mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-02-02 19:12:53 +08:00
Merge remote-tracking branch 'origin/unstable-quests' into unstable-quests
This commit is contained in:
commit
4f1136ce2d
@ -1,72 +1,72 @@
|
|||||||
package emu.grasscutter.auth;
|
package emu.grasscutter.auth;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.ACCOUNT;
|
import static emu.grasscutter.config.Configuration.ACCOUNT;
|
||||||
import static emu.grasscutter.utils.Language.translate;
|
import static emu.grasscutter.utils.Language.translate;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.auth.DefaultAuthenticators.*;
|
import emu.grasscutter.auth.DefaultAuthenticators.*;
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.server.http.objects.ComboTokenResJson;
|
import emu.grasscutter.server.http.objects.ComboTokenResJson;
|
||||||
import emu.grasscutter.server.http.objects.LoginResultJson;
|
import emu.grasscutter.server.http.objects.LoginResultJson;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The default Grasscutter authentication implementation. Allows all users to access any account.
|
* The default Grasscutter authentication implementation. Allows all users to access any account.
|
||||||
*/
|
*/
|
||||||
public final class DefaultAuthentication implements AuthenticationSystem {
|
public final class DefaultAuthentication implements AuthenticationSystem {
|
||||||
private final Authenticator<LoginResultJson> passwordAuthenticator;
|
private final Authenticator<LoginResultJson> passwordAuthenticator;
|
||||||
private final Authenticator<LoginResultJson> tokenAuthenticator = new TokenAuthenticator();
|
private final Authenticator<LoginResultJson> tokenAuthenticator = new TokenAuthenticator();
|
||||||
private final Authenticator<ComboTokenResJson> sessionKeyAuthenticator =
|
private final Authenticator<ComboTokenResJson> sessionKeyAuthenticator =
|
||||||
new SessionKeyAuthenticator();
|
new SessionKeyAuthenticator();
|
||||||
private final ExternalAuthenticator externalAuthenticator = new ExternalAuthentication();
|
private final ExternalAuthenticator externalAuthenticator = new ExternalAuthentication();
|
||||||
private final OAuthAuthenticator oAuthAuthenticator = new OAuthAuthentication();
|
private final OAuthAuthenticator oAuthAuthenticator = new OAuthAuthentication();
|
||||||
|
|
||||||
public DefaultAuthentication() {
|
public DefaultAuthentication() {
|
||||||
if (ACCOUNT.EXPERIMENTAL_RealPassword) {
|
if (ACCOUNT.EXPERIMENTAL_RealPassword) {
|
||||||
passwordAuthenticator = new ExperimentalPasswordAuthenticator();
|
passwordAuthenticator = new ExperimentalPasswordAuthenticator();
|
||||||
} else {
|
} else {
|
||||||
passwordAuthenticator = new PasswordAuthenticator();
|
passwordAuthenticator = new PasswordAuthenticator();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void createAccount(String username, String password) {
|
public void createAccount(String username, String password) {
|
||||||
// Unhandled. The default authenticator doesn't store passwords.
|
// Unhandled. The default authenticator doesn't store passwords.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void resetPassword(String username) {
|
public void resetPassword(String username) {
|
||||||
// Unhandled. The default authenticator doesn't store passwords.
|
// Unhandled. The default authenticator doesn't store passwords.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Account verifyUser(String details) {
|
public Account verifyUser(String details) {
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.info(translate("messages.dispatch.authentication.default_unable_to_verify"));
|
.info(translate("messages.dispatch.authentication.default_unable_to_verify"));
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authenticator<LoginResultJson> getPasswordAuthenticator() {
|
public Authenticator<LoginResultJson> getPasswordAuthenticator() {
|
||||||
return this.passwordAuthenticator;
|
return this.passwordAuthenticator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authenticator<LoginResultJson> getTokenAuthenticator() {
|
public Authenticator<LoginResultJson> getTokenAuthenticator() {
|
||||||
return this.tokenAuthenticator;
|
return this.tokenAuthenticator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Authenticator<ComboTokenResJson> getSessionKeyAuthenticator() {
|
public Authenticator<ComboTokenResJson> getSessionKeyAuthenticator() {
|
||||||
return this.sessionKeyAuthenticator;
|
return this.sessionKeyAuthenticator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ExternalAuthenticator getExternalAuthenticator() {
|
public ExternalAuthenticator getExternalAuthenticator() {
|
||||||
return this.externalAuthenticator;
|
return this.externalAuthenticator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OAuthAuthenticator getOAuthAuthenticator() {
|
public OAuthAuthenticator getOAuthAuthenticator() {
|
||||||
return this.oAuthAuthenticator;
|
return this.oAuthAuthenticator;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,190 +1,190 @@
|
|||||||
package emu.grasscutter.command.commands;
|
package emu.grasscutter.command.commands;
|
||||||
|
|
||||||
import emu.grasscutter.command.Command;
|
import emu.grasscutter.command.Command;
|
||||||
import emu.grasscutter.command.CommandHandler;
|
import emu.grasscutter.command.CommandHandler;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.entity.EntityAvatar;
|
import emu.grasscutter.game.entity.EntityAvatar;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@Command(
|
@Command(
|
||||||
label = "setStats",
|
label = "setStats",
|
||||||
aliases = {"stats", "stat"},
|
aliases = {"stats", "stat"},
|
||||||
usage = {
|
usage = {
|
||||||
"[set] <stat> <value>",
|
"[set] <stat> <value>",
|
||||||
"(lock|freeze) <stat> [<value>]", // Can lock to current value
|
"(lock|freeze) <stat> [<value>]", // Can lock to current value
|
||||||
"(unlock|unfreeze) <stat>"
|
"(unlock|unfreeze) <stat>"
|
||||||
},
|
},
|
||||||
permission = "player.setstats",
|
permission = "player.setstats",
|
||||||
permissionTargeted = "player.setstats.others")
|
permissionTargeted = "player.setstats.others")
|
||||||
public final class SetStatsCommand implements CommandHandler {
|
public final class SetStatsCommand implements CommandHandler {
|
||||||
private final Map<String, Stat> stats;
|
private final Map<String, Stat> stats;
|
||||||
|
|
||||||
public SetStatsCommand() {
|
public SetStatsCommand() {
|
||||||
this.stats = new HashMap<>();
|
this.stats = new HashMap<>();
|
||||||
for (String key : FightProperty.getShortNames()) {
|
for (String key : FightProperty.getShortNames()) {
|
||||||
this.stats.put(key, new Stat(FightProperty.getPropByShortName(key)));
|
this.stats.put(key, new Stat(FightProperty.getPropByShortName(key)));
|
||||||
}
|
}
|
||||||
// Full FightProperty enum that won't be advertised but can be used by devs
|
// Full FightProperty enum that won't be advertised but can be used by devs
|
||||||
// They have a prefix to avoid the "hp" clash
|
// They have a prefix to avoid the "hp" clash
|
||||||
for (FightProperty prop : FightProperty.values()) {
|
for (FightProperty prop : FightProperty.values()) {
|
||||||
String name = prop.toString().substring(10); // FIGHT_PROP_BASE_HP -> _BASE_HP
|
String name = prop.toString().substring(10); // FIGHT_PROP_BASE_HP -> _BASE_HP
|
||||||
String key = name.toLowerCase(); // _BASE_HP -> _base_hp
|
String key = name.toLowerCase(); // _BASE_HP -> _base_hp
|
||||||
name = name.substring(1); // _BASE_HP -> BASE_HP
|
name = name.substring(1); // _BASE_HP -> BASE_HP
|
||||||
this.stats.put(key, new Stat(name, prop));
|
this.stats.put(key, new Stat(name, prop));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compatibility aliases
|
// Compatibility aliases
|
||||||
this.stats.put("mhp", this.stats.get("maxhp"));
|
this.stats.put("mhp", this.stats.get("maxhp"));
|
||||||
this.stats.put("hp", this.stats.get("_cur_hp")); // Overrides FIGHT_PROP_HP
|
this.stats.put("hp", this.stats.get("_cur_hp")); // Overrides FIGHT_PROP_HP
|
||||||
this.stats.put("atk", this.stats.get("_cur_attack")); // Overrides FIGHT_PROP_ATTACK
|
this.stats.put("atk", this.stats.get("_cur_attack")); // Overrides FIGHT_PROP_ATTACK
|
||||||
this.stats.put("def", this.stats.get("_cur_defense")); // Overrides FIGHT_PROP_DEFENSE
|
this.stats.put("def", this.stats.get("_cur_defense")); // Overrides FIGHT_PROP_DEFENSE
|
||||||
this.stats.put(
|
this.stats.put(
|
||||||
"atkb",
|
"atkb",
|
||||||
this.stats.get(
|
this.stats.get(
|
||||||
"_base_attack")); // This doesn't seem to get used to recalculate ATK, so it's only
|
"_base_attack")); // This doesn't seem to get used to recalculate ATK, so it's only
|
||||||
// useful for stuff like Bennett's buff.
|
// useful for stuff like Bennett's buff.
|
||||||
this.stats.put("eanemo", this.stats.get("anemo%"));
|
this.stats.put("eanemo", this.stats.get("anemo%"));
|
||||||
this.stats.put("ecryo", this.stats.get("cryo%"));
|
this.stats.put("ecryo", this.stats.get("cryo%"));
|
||||||
this.stats.put("edendro", this.stats.get("dendro%"));
|
this.stats.put("edendro", this.stats.get("dendro%"));
|
||||||
this.stats.put("edend", this.stats.get("dendro%"));
|
this.stats.put("edend", this.stats.get("dendro%"));
|
||||||
this.stats.put("eelectro", this.stats.get("electro%"));
|
this.stats.put("eelectro", this.stats.get("electro%"));
|
||||||
this.stats.put("eelec", this.stats.get("electro%"));
|
this.stats.put("eelec", this.stats.get("electro%"));
|
||||||
this.stats.put("ethunder", this.stats.get("electro%"));
|
this.stats.put("ethunder", this.stats.get("electro%"));
|
||||||
this.stats.put("egeo", this.stats.get("geo%"));
|
this.stats.put("egeo", this.stats.get("geo%"));
|
||||||
this.stats.put("ehydro", this.stats.get("hydro%"));
|
this.stats.put("ehydro", this.stats.get("hydro%"));
|
||||||
this.stats.put("epyro", this.stats.get("pyro%"));
|
this.stats.put("epyro", this.stats.get("pyro%"));
|
||||||
this.stats.put("ephys", this.stats.get("phys%"));
|
this.stats.put("ephys", this.stats.get("phys%"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float parsePercent(String input) throws NumberFormatException {
|
public static float parsePercent(String input) throws NumberFormatException {
|
||||||
if (input.endsWith("%")) {
|
if (input.endsWith("%")) {
|
||||||
return Float.parseFloat(input.substring(0, input.length() - 1)) / 100f;
|
return Float.parseFloat(input.substring(0, input.length() - 1)) / 100f;
|
||||||
} else {
|
} else {
|
||||||
return Float.parseFloat(input);
|
return Float.parseFloat(input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
String statStr = null;
|
String statStr = null;
|
||||||
String valueStr;
|
String valueStr;
|
||||||
float value = 0f;
|
float value = 0f;
|
||||||
|
|
||||||
if (args.size() < 2) {
|
if (args.size() < 2) {
|
||||||
sendUsageMessage(sender);
|
sendUsageMessage(sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the action and stat
|
// Get the action and stat
|
||||||
String arg0 = args.remove(0).toLowerCase();
|
String arg0 = args.remove(0).toLowerCase();
|
||||||
Action action =
|
Action action =
|
||||||
switch (arg0) {
|
switch (arg0) {
|
||||||
default -> {
|
default -> {
|
||||||
statStr = arg0;
|
statStr = arg0;
|
||||||
yield Action.ACTION_SET;
|
yield Action.ACTION_SET;
|
||||||
} // Implicit set command
|
} // Implicit set command
|
||||||
case "set" -> Action.ACTION_SET; // Explicit set command
|
case "set" -> Action.ACTION_SET; // Explicit set command
|
||||||
case "lock", "freeze" -> Action.ACTION_LOCK;
|
case "lock", "freeze" -> Action.ACTION_LOCK;
|
||||||
case "unlock", "unfreeze" -> Action.ACTION_UNLOCK;
|
case "unlock", "unfreeze" -> Action.ACTION_UNLOCK;
|
||||||
};
|
};
|
||||||
if (statStr == null) {
|
if (statStr == null) {
|
||||||
statStr = args.remove(0).toLowerCase();
|
statStr = args.remove(0).toLowerCase();
|
||||||
}
|
}
|
||||||
if (!stats.containsKey(statStr)) {
|
if (!stats.containsKey(statStr)) {
|
||||||
sendUsageMessage(sender); // Invalid stat or action
|
sendUsageMessage(sender); // Invalid stat or action
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Stat stat = stats.get(statStr);
|
Stat stat = stats.get(statStr);
|
||||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||||
Avatar avatar = entity.getAvatar();
|
Avatar avatar = entity.getAvatar();
|
||||||
|
|
||||||
// Get the value if the action requires it
|
// Get the value if the action requires it
|
||||||
try {
|
try {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_LOCK:
|
case ACTION_LOCK:
|
||||||
if (args.isEmpty()) { // Lock to current value
|
if (args.isEmpty()) { // Lock to current value
|
||||||
value = avatar.getFightProperty(stat.prop);
|
value = avatar.getFightProperty(stat.prop);
|
||||||
break;
|
break;
|
||||||
} // Else fall-through and lock to supplied value
|
} // Else fall-through and lock to supplied value
|
||||||
case ACTION_SET:
|
case ACTION_SET:
|
||||||
value = parsePercent(args.remove(0));
|
value = parsePercent(args.remove(0));
|
||||||
break;
|
break;
|
||||||
case ACTION_UNLOCK:
|
case ACTION_UNLOCK:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.statValue");
|
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.statValue");
|
||||||
return;
|
return;
|
||||||
} catch (IndexOutOfBoundsException ignored) {
|
} catch (IndexOutOfBoundsException ignored) {
|
||||||
sendUsageMessage(sender);
|
sendUsageMessage(sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!args.isEmpty()) { // Leftover arguments!
|
if (!args.isEmpty()) { // Leftover arguments!
|
||||||
sendUsageMessage(sender);
|
sendUsageMessage(sender);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case ACTION_SET:
|
case ACTION_SET:
|
||||||
entity.setFightProperty(stat.prop, value);
|
entity.setFightProperty(stat.prop, value);
|
||||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, stat.prop));
|
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, stat.prop));
|
||||||
break;
|
break;
|
||||||
case ACTION_LOCK:
|
case ACTION_LOCK:
|
||||||
avatar.getFightPropOverrides().put(stat.prop.getId(), value);
|
avatar.getFightPropOverrides().put(stat.prop.getId(), value);
|
||||||
avatar.recalcStats();
|
avatar.recalcStats();
|
||||||
break;
|
break;
|
||||||
case ACTION_UNLOCK:
|
case ACTION_UNLOCK:
|
||||||
avatar.getFightPropOverrides().remove(stat.prop.getId());
|
avatar.getFightPropOverrides().remove(stat.prop.getId());
|
||||||
avatar.recalcStats();
|
avatar.recalcStats();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Report action
|
// Report action
|
||||||
if (FightProperty.isPercentage(stat.prop)) {
|
if (FightProperty.isPercentage(stat.prop)) {
|
||||||
valueStr = String.format("%.1f%%", value * 100f);
|
valueStr = String.format("%.1f%%", value * 100f);
|
||||||
} else {
|
} else {
|
||||||
valueStr = String.format("%.0f", value);
|
valueStr = String.format("%.0f", value);
|
||||||
}
|
}
|
||||||
if (targetPlayer == sender) {
|
if (targetPlayer == sender) {
|
||||||
CommandHandler.sendTranslatedMessage(sender, action.messageKeySelf, stat.name, valueStr);
|
CommandHandler.sendTranslatedMessage(sender, action.messageKeySelf, stat.name, valueStr);
|
||||||
} else {
|
} else {
|
||||||
String uidStr = targetPlayer.getAccount().getId();
|
String uidStr = targetPlayer.getAccount().getId();
|
||||||
CommandHandler.sendTranslatedMessage(
|
CommandHandler.sendTranslatedMessage(
|
||||||
sender, action.messageKeyOther, stat.name, uidStr, valueStr);
|
sender, action.messageKeyOther, stat.name, uidStr, valueStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum Action {
|
private enum Action {
|
||||||
ACTION_SET("commands.generic.set_to", "commands.generic.set_for_to"),
|
ACTION_SET("commands.generic.set_to", "commands.generic.set_for_to"),
|
||||||
ACTION_LOCK("commands.setStats.locked_to", "commands.setStats.locked_for_to"),
|
ACTION_LOCK("commands.setStats.locked_to", "commands.setStats.locked_for_to"),
|
||||||
ACTION_UNLOCK("commands.setStats.unlocked", "commands.setStats.unlocked_for");
|
ACTION_UNLOCK("commands.setStats.unlocked", "commands.setStats.unlocked_for");
|
||||||
public final String messageKeySelf;
|
public final String messageKeySelf;
|
||||||
public final String messageKeyOther;
|
public final String messageKeyOther;
|
||||||
|
|
||||||
Action(String messageKeySelf, String messageKeyOther) {
|
Action(String messageKeySelf, String messageKeyOther) {
|
||||||
this.messageKeySelf = messageKeySelf;
|
this.messageKeySelf = messageKeySelf;
|
||||||
this.messageKeyOther = messageKeyOther;
|
this.messageKeyOther = messageKeyOther;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class Stat {
|
private static class Stat {
|
||||||
String name;
|
String name;
|
||||||
FightProperty prop;
|
FightProperty prop;
|
||||||
|
|
||||||
public Stat(FightProperty prop) {
|
public Stat(FightProperty prop) {
|
||||||
this.name = prop.toString();
|
this.name = prop.toString();
|
||||||
this.prop = prop;
|
this.prop = prop;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Stat(String name, FightProperty prop) {
|
public Stat(String name, FightProperty prop) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.prop = prop;
|
this.prop = prop;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -477,8 +477,8 @@ public final class GameData {
|
|||||||
private static final Int2IntMap trialAvatarIndexIdTrialActivityDataDataMap =
|
private static final Int2IntMap trialAvatarIndexIdTrialActivityDataDataMap =
|
||||||
new Int2IntOpenHashMap();
|
new Int2IntOpenHashMap();
|
||||||
|
|
||||||
private static final Map<Integer, List<Integer>> fetters = new HashMap<>();
|
private static Map<Integer, List<Integer>> fetters = new HashMap<>();
|
||||||
private static final Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
|
||||||
|
|
||||||
// Getters with different names that stay for now
|
// Getters with different names that stay for now
|
||||||
public static Int2ObjectMap<MainQuestData> getMainQuestDataMap() {
|
public static Int2ObjectMap<MainQuestData> getMainQuestDataMap() {
|
||||||
|
@ -19,17 +19,17 @@ import lombok.Setter;
|
|||||||
public class GameDepot {
|
public class GameDepot {
|
||||||
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales
|
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales
|
||||||
|
|
||||||
private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
|
private static Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
|
private static Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
|
private static Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
|
||||||
new Int2ObjectOpenHashMap<>();
|
new Int2ObjectOpenHashMap<>();
|
||||||
|
|
||||||
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
|
private static HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
|
|
||||||
@Getter @Setter private static BlossomConfig blossomConfig;
|
@Getter @Setter private static BlossomConfig blossomConfig;
|
||||||
|
@ -1,35 +1,35 @@
|
|||||||
package emu.grasscutter.data.binout;
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class AbilityModifierEntry {
|
public class AbilityModifierEntry {
|
||||||
public List<AbilityModifierAction> onModifierAdded;
|
public List<AbilityModifierAction> onModifierAdded;
|
||||||
public List<AbilityModifierAction> onThinkInterval;
|
public List<AbilityModifierAction> onThinkInterval;
|
||||||
public List<AbilityModifierAction> onRemoved;
|
public List<AbilityModifierAction> onRemoved;
|
||||||
private final String name; // Custom value
|
private final String name; // Custom value
|
||||||
|
|
||||||
public AbilityModifierEntry(String name) {
|
public AbilityModifierEntry(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.onModifierAdded = new ArrayList<>();
|
this.onModifierAdded = new ArrayList<>();
|
||||||
this.onThinkInterval = new ArrayList<>();
|
this.onThinkInterval = new ArrayList<>();
|
||||||
this.onRemoved = new ArrayList<>();
|
this.onRemoved = new ArrayList<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbilityModifierAction> getOnAdded() {
|
public List<AbilityModifierAction> getOnAdded() {
|
||||||
return onModifierAdded;
|
return onModifierAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbilityModifierAction> getOnThinkInterval() {
|
public List<AbilityModifierAction> getOnThinkInterval() {
|
||||||
return onThinkInterval;
|
return onThinkInterval;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<AbilityModifierAction> getOnRemoved() {
|
public List<AbilityModifierAction> getOnRemoved() {
|
||||||
return onRemoved;
|
return onRemoved;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,71 +1,71 @@
|
|||||||
package emu.grasscutter.data.binout;
|
package emu.grasscutter.data.binout;
|
||||||
|
|
||||||
import emu.grasscutter.data.ResourceLoader.OpenConfigData;
|
import emu.grasscutter.data.ResourceLoader.OpenConfigData;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class OpenConfigEntry {
|
public class OpenConfigEntry {
|
||||||
private final String name;
|
private final String name;
|
||||||
private String[] addAbilities;
|
private String[] addAbilities;
|
||||||
private int extraTalentIndex;
|
private int extraTalentIndex;
|
||||||
private SkillPointModifier[] skillPointModifiers;
|
private SkillPointModifier[] skillPointModifiers;
|
||||||
|
|
||||||
public OpenConfigEntry(String name, OpenConfigData[] data) {
|
public OpenConfigEntry(String name, OpenConfigData[] data) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
|
||||||
List<String> abilityList = new ArrayList<>();
|
List<String> abilityList = new ArrayList<>();
|
||||||
List<SkillPointModifier> modList = new ArrayList<>();
|
List<SkillPointModifier> modList = new ArrayList<>();
|
||||||
|
|
||||||
for (OpenConfigData entry : data) {
|
for (OpenConfigData entry : data) {
|
||||||
if (entry.$type.contains("AddAbility")) {
|
if (entry.$type.contains("AddAbility")) {
|
||||||
abilityList.add(entry.abilityName);
|
abilityList.add(entry.abilityName);
|
||||||
} else if (entry.talentIndex > 0) {
|
} else if (entry.talentIndex > 0) {
|
||||||
this.extraTalentIndex = entry.talentIndex;
|
this.extraTalentIndex = entry.talentIndex;
|
||||||
} else if (entry.$type.contains("ModifySkillPoint")) {
|
} else if (entry.$type.contains("ModifySkillPoint")) {
|
||||||
modList.add(new SkillPointModifier(entry.skillID, entry.pointDelta));
|
modList.add(new SkillPointModifier(entry.skillID, entry.pointDelta));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (abilityList.size() > 0) {
|
if (abilityList.size() > 0) {
|
||||||
this.addAbilities = abilityList.toArray(new String[0]);
|
this.addAbilities = abilityList.toArray(new String[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (modList.size() > 0) {
|
if (modList.size() > 0) {
|
||||||
this.skillPointModifiers = modList.toArray(new SkillPointModifier[0]);
|
this.skillPointModifiers = modList.toArray(new SkillPointModifier[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String[] getAddAbilities() {
|
public String[] getAddAbilities() {
|
||||||
return addAbilities;
|
return addAbilities;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getExtraTalentIndex() {
|
public int getExtraTalentIndex() {
|
||||||
return extraTalentIndex;
|
return extraTalentIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SkillPointModifier[] getSkillPointModifiers() {
|
public SkillPointModifier[] getSkillPointModifiers() {
|
||||||
return skillPointModifiers;
|
return skillPointModifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SkillPointModifier {
|
public static class SkillPointModifier {
|
||||||
private final int skillId;
|
private int skillId;
|
||||||
private final int delta;
|
private int delta;
|
||||||
|
|
||||||
public SkillPointModifier(int skillId, int delta) {
|
public SkillPointModifier(int skillId, int delta) {
|
||||||
this.skillId = skillId;
|
this.skillId = skillId;
|
||||||
this.delta = delta;
|
this.delta = delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSkillId() {
|
public int getSkillId() {
|
||||||
return skillId;
|
return skillId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getDelta() {
|
public int getDelta() {
|
||||||
return delta;
|
return delta;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ public class ItemData extends GameResource {
|
|||||||
@Getter(onMethod_ = @Override)
|
@Getter(onMethod_ = @Override)
|
||||||
private int id;
|
private int id;
|
||||||
|
|
||||||
private final int stackLimit = 1;
|
private int stackLimit = 1;
|
||||||
private int maxUseCount;
|
private int maxUseCount;
|
||||||
private int rankLevel;
|
private int rankLevel;
|
||||||
private String effectName;
|
private String effectName;
|
||||||
@ -43,7 +43,7 @@ public class ItemData extends GameResource {
|
|||||||
private int[] destroyReturnMaterialCount;
|
private int[] destroyReturnMaterialCount;
|
||||||
|
|
||||||
// Enums
|
// Enums
|
||||||
private final ItemType itemType = ItemType.ITEM_NONE;
|
private ItemType itemType = ItemType.ITEM_NONE;
|
||||||
private MaterialType materialType = MaterialType.MATERIAL_NONE;
|
private MaterialType materialType = MaterialType.MATERIAL_NONE;
|
||||||
private EquipType equipType = EquipType.EQUIP_NONE;
|
private EquipType equipType = EquipType.EQUIP_NONE;
|
||||||
private String effectType;
|
private String effectType;
|
||||||
|
@ -1,21 +1,21 @@
|
|||||||
package emu.grasscutter.data.excels;
|
package emu.grasscutter.data.excels;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameResource;
|
import emu.grasscutter.data.GameResource;
|
||||||
import emu.grasscutter.data.ResourceType;
|
import emu.grasscutter.data.ResourceType;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
@ResourceType(name = "PlayerLevelExcelConfigData.json")
|
@ResourceType(name = "PlayerLevelExcelConfigData.json")
|
||||||
@Getter
|
@Getter
|
||||||
public class PlayerLevelData extends GameResource {
|
public class PlayerLevelData extends GameResource {
|
||||||
private int level;
|
private int level;
|
||||||
private int exp;
|
private int exp;
|
||||||
private int rewardId;
|
private int rewardId;
|
||||||
private final int expeditionLimitAdd = 0;
|
private int expeditionLimitAdd = 0;
|
||||||
private int unlockWorldLevel;
|
private int unlockWorldLevel;
|
||||||
private long unlockDescTextMapHash;
|
private long unlockDescTextMapHash;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return this.level;
|
return this.level;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ public class AchievementData extends GameResource {
|
|||||||
private static final AtomicBoolean isDivided = new AtomicBoolean();
|
private static final AtomicBoolean isDivided = new AtomicBoolean();
|
||||||
private int goalId;
|
private int goalId;
|
||||||
private int preStageAchievementId;
|
private int preStageAchievementId;
|
||||||
private final Set<Integer> groupAchievementIdList = new HashSet<>();
|
private Set<Integer> groupAchievementIdList = new HashSet<>();
|
||||||
private boolean isParent;
|
private boolean isParent;
|
||||||
private long titleTextMapHash;
|
private long titleTextMapHash;
|
||||||
private long descTextMapHash;
|
private long descTextMapHash;
|
||||||
|
@ -26,7 +26,7 @@ public class Account {
|
|||||||
|
|
||||||
private String token;
|
private String token;
|
||||||
private String sessionKey; // Session token for dispatch server
|
private String sessionKey; // Session token for dispatch server
|
||||||
private final List<String> permissions;
|
private List<String> permissions;
|
||||||
private Locale locale;
|
private Locale locale;
|
||||||
|
|
||||||
private String banReason;
|
private String banReason;
|
||||||
|
@ -1,214 +1,214 @@
|
|||||||
package emu.grasscutter.game.ability;
|
package emu.grasscutter.game.ability;
|
||||||
|
|
||||||
import emu.grasscutter.game.entity.EntityAvatar;
|
import emu.grasscutter.game.entity.EntityAvatar;
|
||||||
import emu.grasscutter.game.entity.GameEntity;
|
import emu.grasscutter.game.entity.GameEntity;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.FightProperty;
|
import emu.grasscutter.game.props.FightProperty;
|
||||||
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
import emu.grasscutter.net.proto.AbilityInvokeEntryOuterClass.AbilityInvokeEntry;
|
||||||
import emu.grasscutter.net.proto.AbilityMetaModifierChangeOuterClass.AbilityMetaModifierChange;
|
import emu.grasscutter.net.proto.AbilityMetaModifierChangeOuterClass.AbilityMetaModifierChange;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public class HealAbilityManager {
|
public class HealAbilityManager {
|
||||||
ArrayList<HealDataAvatar> healDataAvatarList;
|
ArrayList<HealDataAvatar> healDataAvatarList;
|
||||||
private final Player player;
|
private Player player;
|
||||||
|
|
||||||
public HealAbilityManager(Player player) {
|
public HealAbilityManager(Player player) {
|
||||||
this.player = player;
|
this.player = player;
|
||||||
healDataAvatarList = new ArrayList();
|
healDataAvatarList = new ArrayList();
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000054, "Kokomi", 0)
|
new HealDataAvatar(10000054, "Kokomi", 0)
|
||||||
.addHealData(
|
.addHealData(
|
||||||
"E",
|
"E",
|
||||||
"ElementalArt_Heal_MaxHP_Base_Percentage",
|
"ElementalArt_Heal_MaxHP_Base_Percentage",
|
||||||
"ElementalArt_Heal_Base_Amount",
|
"ElementalArt_Heal_Base_Amount",
|
||||||
false)
|
false)
|
||||||
.addHealData("Q", "Avatar_Kokomi_ElementalBurst_Heal", 0.0172f, 212f, false));
|
.addHealData("Q", "Avatar_Kokomi_ElementalBurst_Heal", 0.0172f, 212f, false));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000003, "Qin", 1).addHealData("Q", "Heal", "BurstHealConst", true));
|
new HealDataAvatar(10000003, "Qin", 1).addHealData("Q", "Heal", "BurstHealConst", true));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000034, "Noel", 2)
|
new HealDataAvatar(10000034, "Noel", 2)
|
||||||
.addHealData("E", "OnAttack_HealthRate", 0.452f, 282f, true));
|
.addHealData("E", "OnAttack_HealthRate", 0.452f, 282f, true));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000032, "Bennett", 0)
|
new HealDataAvatar(10000032, "Bennett", 0)
|
||||||
.addHealData("Q", "HealMaxHpRatio", "HealConst", false));
|
.addHealData("Q", "HealMaxHpRatio", "HealConst", false));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000039, "Diona", 0)
|
new HealDataAvatar(10000039, "Diona", 0)
|
||||||
.addHealData("Q", "HealHPRatio", "HealHP_Const", false));
|
.addHealData("Q", "HealHPRatio", "HealHP_Const", false));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000053, "Sayu", 1)
|
new HealDataAvatar(10000053, "Sayu", 1)
|
||||||
.addHealData("Q", "Constellation_6_Damage", "Heal_BaseAmount", true)
|
.addHealData("Q", "Constellation_6_Damage", "Heal_BaseAmount", true)
|
||||||
.addHealData("Q", "Heal_AttackRatio", "Constellation_6_Heal", true));
|
.addHealData("Q", "Heal_AttackRatio", "Constellation_6_Heal", true));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000014, "Barbara", 0)
|
new HealDataAvatar(10000014, "Barbara", 0)
|
||||||
.addHealData("E", "HealHPOnAdded", "HealHPOnAdded_Const", true)
|
.addHealData("E", "HealHPOnAdded", "HealHPOnAdded_Const", true)
|
||||||
.addHealData("E", "HealHP_OnHittingOthers", "HealHP_Const_OnHittingOthers", true)
|
.addHealData("E", "HealHP_OnHittingOthers", "HealHP_Const_OnHittingOthers", true)
|
||||||
.addHealData("Q", "Avatar_Barbara_IdolHeal", 0.374f, 4660f, true));
|
.addHealData("Q", "Avatar_Barbara_IdolHeal", 0.374f, 4660f, true));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000065, "Shinobu", 0)
|
new HealDataAvatar(10000065, "Shinobu", 0)
|
||||||
.addHealData("E", "ElementalArt_Heal_MaxHP_Percentage", 0.064f, 795f, false));
|
.addHealData("E", "ElementalArt_Heal_MaxHP_Percentage", 0.064f, 795f, false));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000035, "Qiqi", 1)
|
new HealDataAvatar(10000035, "Qiqi", 1)
|
||||||
.addHealData("E", "HealHP_OnHittingOthers", "HealHP_Const_OnHittingOthers", true)
|
.addHealData("E", "HealHP_OnHittingOthers", "HealHP_Const_OnHittingOthers", true)
|
||||||
.addHealData("E", "ElementalArt_HealHp_Ratio", "ElementalArt_HealHp_Const", true)
|
.addHealData("E", "ElementalArt_HealHp_Ratio", "ElementalArt_HealHp_Const", true)
|
||||||
.addHealData("Q", "Avatar_Qiqi_ElementalBurst_ApplyModifier", 0.0191f, 1588f, false));
|
.addHealData("Q", "Avatar_Qiqi_ElementalBurst_ApplyModifier", 0.0191f, 1588f, false));
|
||||||
healDataAvatarList.add(
|
healDataAvatarList.add(
|
||||||
new HealDataAvatar(10000046, "Hutao", 0)
|
new HealDataAvatar(10000046, "Hutao", 0)
|
||||||
.addHealData("Q", "Avatar_Hutao_VermilionBite_BakeMesh", 0.1166f, 0f, false));
|
.addHealData("Q", "Avatar_Hutao_VermilionBite_BakeMesh", 0.1166f, 0f, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayer() {
|
public Player getPlayer() {
|
||||||
return this.player;
|
return this.player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void healHandler(AbilityInvokeEntry invoke) throws Exception {
|
public void healHandler(AbilityInvokeEntry invoke) throws Exception {
|
||||||
AbilityMetaModifierChange data = AbilityMetaModifierChange.parseFrom(invoke.getAbilityData());
|
AbilityMetaModifierChange data = AbilityMetaModifierChange.parseFrom(invoke.getAbilityData());
|
||||||
|
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameEntity sourceEntity = player.getScene().getEntityById(data.getApplyEntityId());
|
GameEntity sourceEntity = player.getScene().getEntityById(data.getApplyEntityId());
|
||||||
|
|
||||||
String modifierString = "";
|
String modifierString = "";
|
||||||
if (data.getParentAbilityName() != null) modifierString = data.getParentAbilityName().getStr();
|
if (data.getParentAbilityName() != null) modifierString = data.getParentAbilityName().getStr();
|
||||||
|
|
||||||
if (sourceEntity != null) checkAndHeal(sourceEntity, modifierString);
|
if (sourceEntity != null) checkAndHeal(sourceEntity, modifierString);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkAndHeal(GameEntity sourceEntity, String modifierString) {
|
public void checkAndHeal(GameEntity sourceEntity, String modifierString) {
|
||||||
int fightPropertyType = 0;
|
int fightPropertyType = 0;
|
||||||
float healAmount = 0;
|
float healAmount = 0;
|
||||||
float ratio = 0, base = 0;
|
float ratio = 0, base = 0;
|
||||||
float maxHP, curHP, curAttack, curDefense;
|
float maxHP, curHP, curAttack, curDefense;
|
||||||
Map<String, Float> map = sourceEntity.getMetaOverrideMap();
|
Map<String, Float> map = sourceEntity.getMetaOverrideMap();
|
||||||
|
|
||||||
for (int i = 0; i < healDataAvatarList.size(); i++) {
|
for (int i = 0; i < healDataAvatarList.size(); i++) {
|
||||||
HealDataAvatar healDataAvatar = healDataAvatarList.get(i);
|
HealDataAvatar healDataAvatar = healDataAvatarList.get(i);
|
||||||
if (modifierString.contains(healDataAvatar.avatarName)) {
|
if (modifierString.contains(healDataAvatar.avatarName)) {
|
||||||
fightPropertyType = healDataAvatar.fightPropertyType;
|
fightPropertyType = healDataAvatar.fightPropertyType;
|
||||||
ArrayList<HealData> healDataList = healDataAvatar.healDataList;
|
ArrayList<HealData> healDataList = healDataAvatar.healDataList;
|
||||||
|
|
||||||
for (int j = 0; j < healDataList.size(); j++) {
|
for (int j = 0; j < healDataList.size(); j++) {
|
||||||
HealData healData = healDataList.get(j);
|
HealData healData = healDataList.get(j);
|
||||||
if (map.containsKey(healData.sRatio) || modifierString.equals(healData.sRatio)) {
|
if (map.containsKey(healData.sRatio) || modifierString.equals(healData.sRatio)) {
|
||||||
if (healData.isString) {
|
if (healData.isString) {
|
||||||
ratio = map.get(healData.sRatio);
|
ratio = map.get(healData.sRatio);
|
||||||
base = map.get(healData.sBase);
|
base = map.get(healData.sBase);
|
||||||
} else {
|
} else {
|
||||||
ratio = healData.fRatio;
|
ratio = healData.fRatio;
|
||||||
base = healData.fBase;
|
base = healData.fBase;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
List<EntityAvatar> activeTeam = player.getTeamManager().getActiveTeam();
|
List<EntityAvatar> activeTeam = player.getTeamManager().getActiveTeam();
|
||||||
List<EntityAvatar> needHealAvatars = new ArrayList();
|
List<EntityAvatar> needHealAvatars = new ArrayList();
|
||||||
int currentIndex = player.getTeamManager().getCurrentCharacterIndex();
|
int currentIndex = player.getTeamManager().getCurrentCharacterIndex();
|
||||||
EntityAvatar currentAvatar = activeTeam.get(currentIndex);
|
EntityAvatar currentAvatar = activeTeam.get(currentIndex);
|
||||||
if (healData.healAll) {
|
if (healData.healAll) {
|
||||||
needHealAvatars = activeTeam;
|
needHealAvatars = activeTeam;
|
||||||
} else {
|
} else {
|
||||||
needHealAvatars.add(currentAvatar);
|
needHealAvatars.add(currentAvatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
EntityAvatar healActionAvatar = null;
|
EntityAvatar healActionAvatar = null;
|
||||||
for (int k = 0; k < activeTeam.size(); k++) {
|
for (int k = 0; k < activeTeam.size(); k++) {
|
||||||
EntityAvatar avatar = activeTeam.get(k);
|
EntityAvatar avatar = activeTeam.get(k);
|
||||||
int avatarId = avatar.getAvatar().getAvatarId();
|
int avatarId = avatar.getAvatar().getAvatarId();
|
||||||
if (avatarId == healDataAvatar.avatarId) {
|
if (avatarId == healDataAvatar.avatarId) {
|
||||||
healActionAvatar = avatar;
|
healActionAvatar = avatar;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (healActionAvatar != null) {
|
if (healActionAvatar != null) {
|
||||||
maxHP = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
maxHP = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP);
|
||||||
curHP = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
curHP = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
|
||||||
curAttack = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK);
|
curAttack = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK);
|
||||||
curDefense = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE);
|
curDefense = healActionAvatar.getFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE);
|
||||||
|
|
||||||
// Special case for Hu Tao:
|
// Special case for Hu Tao:
|
||||||
if (healDataAvatar.avatarName.equals("Hutao") && curHP <= maxHP * 0.5 && ratio != 0) {
|
if (healDataAvatar.avatarName.equals("Hutao") && curHP <= maxHP * 0.5 && ratio != 0) {
|
||||||
ratio = 0.1555f;
|
ratio = 0.1555f;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (fightPropertyType) {
|
switch (fightPropertyType) {
|
||||||
case 0:
|
case 0:
|
||||||
healAmount = ratio * maxHP + base;
|
healAmount = ratio * maxHP + base;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
healAmount = ratio * curAttack + base;
|
healAmount = ratio * curAttack + base;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
healAmount = ratio * curDefense + base;
|
healAmount = ratio * curDefense + base;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int k = 0; k < needHealAvatars.size(); k++) {
|
for (int k = 0; k < needHealAvatars.size(); k++) {
|
||||||
EntityAvatar avatar = needHealAvatars.get(k);
|
EntityAvatar avatar = needHealAvatars.get(k);
|
||||||
avatar.heal(healAmount);
|
avatar.heal(healAmount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class HealData {
|
private class HealData {
|
||||||
public boolean isString = true;
|
public boolean isString = true;
|
||||||
public String abilityType = ""; // "E" or "Q"
|
public String abilityType = ""; // "E" or "Q"
|
||||||
public String sRatio = "";
|
public String sRatio = "";
|
||||||
public String sBase = "";
|
public String sBase = "";
|
||||||
public float fRatio = 0;
|
public float fRatio = 0;
|
||||||
public float fBase = 0;
|
public float fBase = 0;
|
||||||
public boolean healAll = false;
|
public boolean healAll = false;
|
||||||
|
|
||||||
public HealData(String _abilityType, String _sRatio, String _sBase, boolean _healAll) {
|
public HealData(String _abilityType, String _sRatio, String _sBase, boolean _healAll) {
|
||||||
abilityType = _abilityType;
|
abilityType = _abilityType;
|
||||||
isString = true;
|
isString = true;
|
||||||
sRatio = _sRatio;
|
sRatio = _sRatio;
|
||||||
sBase = _sBase;
|
sBase = _sBase;
|
||||||
healAll = _healAll;
|
healAll = _healAll;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HealData(
|
public HealData(
|
||||||
String _abilityType, String _sRatio, float _fRatio, float _fBase, boolean _healAll) {
|
String _abilityType, String _sRatio, float _fRatio, float _fBase, boolean _healAll) {
|
||||||
abilityType = _abilityType;
|
abilityType = _abilityType;
|
||||||
isString = false;
|
isString = false;
|
||||||
sRatio = _sRatio;
|
sRatio = _sRatio;
|
||||||
fRatio = _fRatio;
|
fRatio = _fRatio;
|
||||||
fBase = _fBase;
|
fBase = _fBase;
|
||||||
healAll = _healAll;
|
healAll = _healAll;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class HealDataAvatar {
|
private class HealDataAvatar {
|
||||||
public int avatarId = 0;
|
public int avatarId = 0;
|
||||||
public String avatarName = "";
|
public String avatarName = "";
|
||||||
public int fightPropertyType = 0; // 0: maxHP, 1: curAttack, 2: curDefense
|
public int fightPropertyType = 0; // 0: maxHP, 1: curAttack, 2: curDefense
|
||||||
public ArrayList<HealData> healDataList;
|
public ArrayList<HealData> healDataList;
|
||||||
|
|
||||||
public HealDataAvatar(int _avatarId, String _avatarName, int _fightPropertyType) {
|
public HealDataAvatar(int _avatarId, String _avatarName, int _fightPropertyType) {
|
||||||
avatarId = _avatarId;
|
avatarId = _avatarId;
|
||||||
avatarName = _avatarName;
|
avatarName = _avatarName;
|
||||||
fightPropertyType = _fightPropertyType;
|
fightPropertyType = _fightPropertyType;
|
||||||
healDataList = new ArrayList();
|
healDataList = new ArrayList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public HealDataAvatar addHealData(
|
public HealDataAvatar addHealData(
|
||||||
String abilityType, String sRatio, String sBase, boolean healAll) {
|
String abilityType, String sRatio, String sBase, boolean healAll) {
|
||||||
HealData healData = new HealData(abilityType, sRatio, sBase, healAll);
|
HealData healData = new HealData(abilityType, sRatio, sBase, healAll);
|
||||||
healDataList.add(healData);
|
healDataList.add(healData);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HealDataAvatar addHealData(
|
public HealDataAvatar addHealData(
|
||||||
String abilityType, String sRatio, float fRatio, float fBase, boolean healAll) {
|
String abilityType, String sRatio, float fRatio, float fBase, boolean healAll) {
|
||||||
HealData healData = new HealData(abilityType, sRatio, fRatio, fBase, healAll);
|
HealData healData = new HealData(abilityType, sRatio, fRatio, fBase, healAll);
|
||||||
healDataList.add(healData);
|
healDataList.add(healData);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
package emu.grasscutter.game.achievement;
|
package emu.grasscutter.game.achievement;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.net.proto.AchievementOuterClass;
|
import emu.grasscutter.net.proto.AchievementOuterClass;
|
||||||
import emu.grasscutter.net.proto.StatusOuterClass;
|
import emu.grasscutter.net.proto.StatusOuterClass;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@Getter
|
@Getter
|
||||||
public class Achievement {
|
public class Achievement {
|
||||||
@Setter private StatusOuterClass.Status status;
|
@Setter private StatusOuterClass.Status status;
|
||||||
private final int id;
|
private int id;
|
||||||
private final int totalProgress;
|
private int totalProgress;
|
||||||
@Setter private int curProgress;
|
@Setter private int curProgress;
|
||||||
@Setter private int finishTimestampSec;
|
@Setter private int finishTimestampSec;
|
||||||
|
|
||||||
public Achievement(
|
public Achievement(
|
||||||
StatusOuterClass.Status status,
|
StatusOuterClass.Status status,
|
||||||
int id,
|
int id,
|
||||||
int totalProgress,
|
int totalProgress,
|
||||||
int curProgress,
|
int curProgress,
|
||||||
int finishTimestampSec) {
|
int finishTimestampSec) {
|
||||||
this.status = status;
|
this.status = status;
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.totalProgress = totalProgress;
|
this.totalProgress = totalProgress;
|
||||||
this.curProgress = curProgress;
|
this.curProgress = curProgress;
|
||||||
this.finishTimestampSec = finishTimestampSec;
|
this.finishTimestampSec = finishTimestampSec;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AchievementOuterClass.Achievement toProto() {
|
public AchievementOuterClass.Achievement toProto() {
|
||||||
return AchievementOuterClass.Achievement.newBuilder()
|
return AchievementOuterClass.Achievement.newBuilder()
|
||||||
.setStatus(this.getStatus())
|
.setStatus(this.getStatus())
|
||||||
.setId(this.getId())
|
.setId(this.getId())
|
||||||
.setTotalProgress(this.getTotalProgress())
|
.setTotalProgress(this.getTotalProgress())
|
||||||
.setCurProgress(this.getCurProgress())
|
.setCurProgress(this.getCurProgress())
|
||||||
.setFinishTimestamp(this.getFinishTimestampSec())
|
.setFinishTimestamp(this.getFinishTimestampSec())
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -74,13 +74,13 @@ public class Avatar {
|
|||||||
|
|
||||||
private List<Integer> fetters;
|
private List<Integer> fetters;
|
||||||
|
|
||||||
private final Map<Integer, Integer> skillLevelMap = new Int2IntArrayMap(7); // Talent levels
|
private Map<Integer, Integer> skillLevelMap = new Int2IntArrayMap(7); // Talent levels
|
||||||
|
|
||||||
@Transient @Getter
|
@Transient @Getter
|
||||||
private final Map<Integer, Integer> skillExtraChargeMap = new Int2IntArrayMap(2); // Charges
|
private Map<Integer, Integer> skillExtraChargeMap = new Int2IntArrayMap(2); // Charges
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private final Map<Integer, Integer> proudSkillBonusMap =
|
private Map<Integer, Integer> proudSkillBonusMap =
|
||||||
new Int2IntArrayMap(2); // Talent bonus levels (from const)
|
new Int2IntArrayMap(2); // Talent bonus levels (from const)
|
||||||
|
|
||||||
@Getter private int skillDepotId;
|
@Getter private int skillDepotId;
|
||||||
|
@ -1,122 +1,122 @@
|
|||||||
package emu.grasscutter.game.entity;
|
package emu.grasscutter.game.entity;
|
||||||
|
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.game.props.PlayerProperty;
|
import emu.grasscutter.game.props.PlayerProperty;
|
||||||
import emu.grasscutter.game.world.Scene;
|
import emu.grasscutter.game.world.Scene;
|
||||||
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
import emu.grasscutter.net.proto.AbilitySyncStateInfoOuterClass.AbilitySyncStateInfo;
|
||||||
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
import emu.grasscutter.net.proto.AnimatorParameterValueInfoPairOuterClass.AnimatorParameterValueInfoPair;
|
||||||
import emu.grasscutter.net.proto.ClientGadgetInfoOuterClass;
|
import emu.grasscutter.net.proto.ClientGadgetInfoOuterClass;
|
||||||
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
import emu.grasscutter.net.proto.EntityAuthorityInfoOuterClass.EntityAuthorityInfo;
|
||||||
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
import emu.grasscutter.net.proto.EntityClientDataOuterClass.EntityClientData;
|
||||||
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
import emu.grasscutter.net.proto.EntityRendererChangedInfoOuterClass.EntityRendererChangedInfo;
|
||||||
import emu.grasscutter.net.proto.EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify;
|
import emu.grasscutter.net.proto.EvtCreateGadgetNotifyOuterClass.EvtCreateGadgetNotify;
|
||||||
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
import emu.grasscutter.net.proto.MotionInfoOuterClass.MotionInfo;
|
||||||
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
import emu.grasscutter.net.proto.PropPairOuterClass.PropPair;
|
||||||
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
import emu.grasscutter.net.proto.ProtEntityTypeOuterClass.ProtEntityType;
|
||||||
import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
|
import emu.grasscutter.net.proto.SceneEntityAiInfoOuterClass.SceneEntityAiInfo;
|
||||||
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
import emu.grasscutter.net.proto.SceneEntityInfoOuterClass.SceneEntityInfo;
|
||||||
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
import emu.grasscutter.net.proto.SceneGadgetInfoOuterClass.SceneGadgetInfo;
|
||||||
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
import emu.grasscutter.net.proto.VectorOuterClass.Vector;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import emu.grasscutter.utils.ProtoHelper;
|
import emu.grasscutter.utils.ProtoHelper;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
import it.unimi.dsi.fastutil.ints.Int2FloatMap;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class EntityClientGadget extends EntityBaseGadget {
|
public class EntityClientGadget extends EntityBaseGadget {
|
||||||
@Getter private final Player owner;
|
@Getter private final Player owner;
|
||||||
|
|
||||||
@Getter(onMethod_ = @Override)
|
@Getter(onMethod_ = @Override)
|
||||||
private final int gadgetId;
|
private int gadgetId;
|
||||||
|
|
||||||
@Getter private final int campId;
|
@Getter private int campId;
|
||||||
@Getter private final int campType;
|
@Getter private int campType;
|
||||||
@Getter private final int ownerEntityId;
|
@Getter private int ownerEntityId;
|
||||||
@Getter private final int targetEntityId;
|
@Getter private int targetEntityId;
|
||||||
@Getter private final boolean asyncLoad;
|
@Getter private boolean asyncLoad;
|
||||||
|
|
||||||
@Getter private final int originalOwnerEntityId;
|
@Getter private int originalOwnerEntityId;
|
||||||
|
|
||||||
public EntityClientGadget(Scene scene, Player player, EvtCreateGadgetNotify notify) {
|
public EntityClientGadget(Scene scene, Player player, EvtCreateGadgetNotify notify) {
|
||||||
super(scene, new Position(notify.getInitPos()), new Position(notify.getInitEulerAngles()));
|
super(scene, new Position(notify.getInitPos()), new Position(notify.getInitEulerAngles()));
|
||||||
this.owner = player;
|
this.owner = player;
|
||||||
this.id = notify.getEntityId();
|
this.id = notify.getEntityId();
|
||||||
this.gadgetId = notify.getConfigId();
|
this.gadgetId = notify.getConfigId();
|
||||||
this.campId = notify.getCampId();
|
this.campId = notify.getCampId();
|
||||||
this.campType = notify.getCampType();
|
this.campType = notify.getCampType();
|
||||||
this.ownerEntityId = notify.getPropOwnerEntityId();
|
this.ownerEntityId = notify.getPropOwnerEntityId();
|
||||||
this.targetEntityId = notify.getTargetEntityId();
|
this.targetEntityId = notify.getTargetEntityId();
|
||||||
this.asyncLoad = notify.getIsAsyncLoad();
|
this.asyncLoad = notify.getIsAsyncLoad();
|
||||||
|
|
||||||
GameEntity owner = scene.getEntityById(this.ownerEntityId);
|
GameEntity owner = scene.getEntityById(this.ownerEntityId);
|
||||||
if (owner instanceof EntityClientGadget ownerGadget) {
|
if (owner instanceof EntityClientGadget ownerGadget) {
|
||||||
this.originalOwnerEntityId = ownerGadget.getOriginalOwnerEntityId();
|
this.originalOwnerEntityId = ownerGadget.getOriginalOwnerEntityId();
|
||||||
} else {
|
} else {
|
||||||
this.originalOwnerEntityId = this.ownerEntityId;
|
this.originalOwnerEntityId = this.ownerEntityId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDeath(int killerId) {
|
public void onDeath(int killerId) {
|
||||||
super.onDeath(killerId); // Invoke super class's onDeath() method.
|
super.onDeath(killerId); // Invoke super class's onDeath() method.
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Int2FloatMap getFightProperties() {
|
public Int2FloatMap getFightProperties() {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SceneEntityInfo toProto() {
|
public SceneEntityInfo toProto() {
|
||||||
EntityAuthorityInfo authority =
|
EntityAuthorityInfo authority =
|
||||||
EntityAuthorityInfo.newBuilder()
|
EntityAuthorityInfo.newBuilder()
|
||||||
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
.setAbilityInfo(AbilitySyncStateInfo.newBuilder())
|
||||||
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
|
.setRendererChangedInfo(EntityRendererChangedInfo.newBuilder())
|
||||||
.setAiInfo(
|
.setAiInfo(
|
||||||
SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(Vector.newBuilder()))
|
SceneEntityAiInfo.newBuilder().setIsAiOpen(true).setBornPos(Vector.newBuilder()))
|
||||||
.setBornPos(Vector.newBuilder())
|
.setBornPos(Vector.newBuilder())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
SceneEntityInfo.Builder entityInfo =
|
SceneEntityInfo.Builder entityInfo =
|
||||||
SceneEntityInfo.newBuilder()
|
SceneEntityInfo.newBuilder()
|
||||||
.setEntityId(getId())
|
.setEntityId(getId())
|
||||||
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
|
.setEntityType(ProtEntityType.PROT_ENTITY_TYPE_GADGET)
|
||||||
.setMotionInfo(
|
.setMotionInfo(
|
||||||
MotionInfo.newBuilder()
|
MotionInfo.newBuilder()
|
||||||
.setPos(getPosition().toProto())
|
.setPos(getPosition().toProto())
|
||||||
.setRot(getRotation().toProto())
|
.setRot(getRotation().toProto())
|
||||||
.setSpeed(Vector.newBuilder()))
|
.setSpeed(Vector.newBuilder()))
|
||||||
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
|
.addAnimatorParaList(AnimatorParameterValueInfoPair.newBuilder())
|
||||||
.setEntityClientData(EntityClientData.newBuilder())
|
.setEntityClientData(EntityClientData.newBuilder())
|
||||||
.setEntityAuthorityInfo(authority)
|
.setEntityAuthorityInfo(authority)
|
||||||
.setLifeState(1);
|
.setLifeState(1);
|
||||||
|
|
||||||
PropPair pair =
|
PropPair pair =
|
||||||
PropPair.newBuilder()
|
PropPair.newBuilder()
|
||||||
.setType(PlayerProperty.PROP_LEVEL.getId())
|
.setType(PlayerProperty.PROP_LEVEL.getId())
|
||||||
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 1))
|
.setPropValue(ProtoHelper.newPropValue(PlayerProperty.PROP_LEVEL, 1))
|
||||||
.build();
|
.build();
|
||||||
entityInfo.addPropList(pair);
|
entityInfo.addPropList(pair);
|
||||||
|
|
||||||
ClientGadgetInfoOuterClass.ClientGadgetInfo clientGadget =
|
ClientGadgetInfoOuterClass.ClientGadgetInfo clientGadget =
|
||||||
ClientGadgetInfoOuterClass.ClientGadgetInfo.newBuilder()
|
ClientGadgetInfoOuterClass.ClientGadgetInfo.newBuilder()
|
||||||
.setCampId(this.getCampId())
|
.setCampId(this.getCampId())
|
||||||
.setCampType(this.getCampType())
|
.setCampType(this.getCampType())
|
||||||
.setOwnerEntityId(this.getOwnerEntityId())
|
.setOwnerEntityId(this.getOwnerEntityId())
|
||||||
.setTargetEntityId(this.getTargetEntityId())
|
.setTargetEntityId(this.getTargetEntityId())
|
||||||
.setAsyncLoad(this.isAsyncLoad())
|
.setAsyncLoad(this.isAsyncLoad())
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
SceneGadgetInfo.Builder gadgetInfo =
|
SceneGadgetInfo.Builder gadgetInfo =
|
||||||
SceneGadgetInfo.newBuilder()
|
SceneGadgetInfo.newBuilder()
|
||||||
.setGadgetId(this.getGadgetId())
|
.setGadgetId(this.getGadgetId())
|
||||||
.setOwnerEntityId(this.getOwnerEntityId())
|
.setOwnerEntityId(this.getOwnerEntityId())
|
||||||
.setIsEnableInteract(true)
|
.setIsEnableInteract(true)
|
||||||
.setClientGadget(clientGadget)
|
.setClientGadget(clientGadget)
|
||||||
.setPropOwnerEntityId(this.getOwnerEntityId())
|
.setPropOwnerEntityId(this.getOwnerEntityId())
|
||||||
.setAuthorityPeerId(this.getOwner().getPeerId());
|
.setAuthorityPeerId(this.getOwner().getPeerId());
|
||||||
|
|
||||||
entityInfo.setGadget(gadgetInfo);
|
entityInfo.setGadget(gadgetInfo);
|
||||||
|
|
||||||
return entityInfo.build();
|
return entityInfo.build();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ public class EntityGadget extends EntityBaseGadget {
|
|||||||
private final Int2FloatMap fightProperties = new Int2FloatOpenHashMap();
|
private final Int2FloatMap fightProperties = new Int2FloatOpenHashMap();
|
||||||
|
|
||||||
@Getter @Setter private SceneGadget metaGadget;
|
@Getter @Setter private SceneGadget metaGadget;
|
||||||
@Nullable @Getter private ConfigEntityGadget configGadget;
|
@Nullable @Getter ConfigEntityGadget configGadget;
|
||||||
@Getter @Setter private BaseRoute routeConfig;
|
@Getter @Setter private BaseRoute routeConfig;
|
||||||
|
|
||||||
@Getter @Setter private int stopValue = 0; // Controller related, inited to zero
|
@Getter @Setter private int stopValue = 0; // Controller related, inited to zero
|
||||||
|
@ -42,7 +42,7 @@ public class EntityVehicle extends EntityBaseGadget {
|
|||||||
@Getter private final int gadgetId;
|
@Getter private final int gadgetId;
|
||||||
|
|
||||||
@Getter @Setter private float curStamina;
|
@Getter @Setter private float curStamina;
|
||||||
@Getter private final List<VehicleMember> vehicleMembers;
|
@Getter private List<VehicleMember> vehicleMembers;
|
||||||
@Nullable @Getter private ConfigEntityGadget configGadget;
|
@Nullable @Getter private ConfigEntityGadget configGadget;
|
||||||
|
|
||||||
public EntityVehicle(
|
public EntityVehicle(
|
||||||
|
@ -1,352 +1,352 @@
|
|||||||
package emu.grasscutter.game.gacha;
|
package emu.grasscutter.game.gacha;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.*;
|
import static emu.grasscutter.config.Configuration.*;
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.data.common.ItemParamData;
|
import emu.grasscutter.data.common.ItemParamData;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
|
import emu.grasscutter.net.proto.GachaInfoOuterClass.GachaInfo;
|
||||||
import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo;
|
import emu.grasscutter.net.proto.GachaUpInfoOuterClass.GachaUpInfo;
|
||||||
import emu.grasscutter.utils.Utils;
|
import emu.grasscutter.utils.Utils;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
public class GachaBanner {
|
public class GachaBanner {
|
||||||
// Constants used by the BannerType enum
|
// Constants used by the BannerType enum
|
||||||
static final int[][] DEFAULT_WEIGHTS_4 = {{1, 510}, {8, 510}, {10, 10000}};
|
static final int[][] DEFAULT_WEIGHTS_4 = {{1, 510}, {8, 510}, {10, 10000}};
|
||||||
static final int[][] DEFAULT_WEIGHTS_4_WEAPON = {{1, 600}, {7, 600}, {8, 6600}, {10, 12600}};
|
static final int[][] DEFAULT_WEIGHTS_4_WEAPON = {{1, 600}, {7, 600}, {8, 6600}, {10, 12600}};
|
||||||
static final int[][] DEFAULT_WEIGHTS_5 = {{1, 75}, {73, 150}, {90, 10000}};
|
static final int[][] DEFAULT_WEIGHTS_5 = {{1, 75}, {73, 150}, {90, 10000}};
|
||||||
static final int[][] DEFAULT_WEIGHTS_5_CHARACTER = {{1, 80}, {73, 80}, {90, 10000}};
|
static final int[][] DEFAULT_WEIGHTS_5_CHARACTER = {{1, 80}, {73, 80}, {90, 10000}};
|
||||||
static final int[][] DEFAULT_WEIGHTS_5_WEAPON = {{1, 100}, {62, 100}, {73, 7800}, {80, 10000}};
|
static final int[][] DEFAULT_WEIGHTS_5_WEAPON = {{1, 100}, {62, 100}, {73, 7800}, {80, 10000}};
|
||||||
static final int[] DEFAULT_FALLBACK_ITEMS_4_POOL_1 = {
|
static final int[] DEFAULT_FALLBACK_ITEMS_4_POOL_1 = {
|
||||||
1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053,
|
1014, 1020, 1023, 1024, 1025, 1027, 1031, 1032, 1034, 1036, 1039, 1043, 1044, 1045, 1048, 1053,
|
||||||
1055, 1056, 1059, 1064, 1065, 1067, 1068, 1072
|
1055, 1056, 1059, 1064, 1065, 1067, 1068, 1072
|
||||||
}; // Default avatars
|
}; // Default avatars
|
||||||
static final int[] DEFAULT_FALLBACK_ITEMS_4_POOL_2 = {
|
static final int[] DEFAULT_FALLBACK_ITEMS_4_POOL_2 = {
|
||||||
11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403,
|
11401, 11402, 11403, 11405, 12401, 12402, 12403, 12405, 13401, 13407, 14401, 14402, 14403,
|
||||||
14409, 15401, 15402, 15403, 15405
|
14409, 15401, 15402, 15403, 15405
|
||||||
}; // Default weapons
|
}; // Default weapons
|
||||||
static final int[] DEFAULT_FALLBACK_ITEMS_5_POOL_1 = {
|
static final int[] DEFAULT_FALLBACK_ITEMS_5_POOL_1 = {
|
||||||
1003, 1016, 1042, 1035, 1041, 1069
|
1003, 1016, 1042, 1035, 1041, 1069
|
||||||
}; // Default avatars
|
}; // Default avatars
|
||||||
static final int[] DEFAULT_FALLBACK_ITEMS_5_POOL_2 = {
|
static final int[] DEFAULT_FALLBACK_ITEMS_5_POOL_2 = {
|
||||||
11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502
|
11501, 11502, 12501, 12502, 13502, 13505, 14501, 14502, 15501, 15502
|
||||||
}; // Default weapons
|
}; // Default weapons
|
||||||
static final int[] EMPTY_POOL = {}; // Used to remove a type of fallback
|
static final int[] EMPTY_POOL = {}; // Used to remove a type of fallback
|
||||||
@Getter int scheduleId = -1;
|
@Getter int scheduleId = -1;
|
||||||
@Getter int sortId = -1;
|
@Getter int sortId = -1;
|
||||||
@Getter private int gachaType = -1;
|
@Getter private int gachaType = -1;
|
||||||
@Getter private String prefabPath;
|
@Getter private String prefabPath;
|
||||||
@Getter private String previewPrefabPath;
|
@Getter private String previewPrefabPath;
|
||||||
@Getter private String titlePath;
|
@Getter private String titlePath;
|
||||||
private int costItemId = 0;
|
private int costItemId = 0;
|
||||||
private final int costItemAmount = 1;
|
private int costItemAmount = 1;
|
||||||
private int costItemId10 = 0;
|
private int costItemId10 = 0;
|
||||||
private final int costItemAmount10 = 10;
|
private int costItemAmount10 = 10;
|
||||||
@Getter private final int beginTime = 0;
|
@Getter private int beginTime = 0;
|
||||||
@Getter private final int endTime = 1924992000;
|
@Getter private int endTime = 1924992000;
|
||||||
@Getter private final int gachaTimesLimit = Integer.MAX_VALUE;
|
@Getter private int gachaTimesLimit = Integer.MAX_VALUE;
|
||||||
@Getter private final int[] rateUpItems4 = {};
|
@Getter private int[] rateUpItems4 = {};
|
||||||
@Getter private final int[] rateUpItems5 = {};
|
@Getter private int[] rateUpItems5 = {};
|
||||||
// This now handles default values for the fields below
|
// This now handles default values for the fields below
|
||||||
@Getter private final BannerType bannerType = BannerType.STANDARD;
|
@Getter private BannerType bannerType = BannerType.STANDARD;
|
||||||
// These don't change between banner types (apart from Standard having three extra 4star avatars)
|
// These don't change between banner types (apart from Standard having three extra 4star avatars)
|
||||||
@Getter
|
@Getter
|
||||||
private final int[] fallbackItems3 = {
|
private int[] fallbackItems3 = {
|
||||||
11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304
|
11301, 11302, 11306, 12301, 12302, 12305, 13303, 14301, 14302, 14304, 15301, 15302, 15304
|
||||||
};
|
};
|
||||||
|
|
||||||
@Getter private final int[] fallbackItems4Pool1 = DEFAULT_FALLBACK_ITEMS_4_POOL_1;
|
@Getter private int[] fallbackItems4Pool1 = DEFAULT_FALLBACK_ITEMS_4_POOL_1;
|
||||||
@Getter private final int[] fallbackItems4Pool2 = DEFAULT_FALLBACK_ITEMS_4_POOL_2;
|
@Getter private int[] fallbackItems4Pool2 = DEFAULT_FALLBACK_ITEMS_4_POOL_2;
|
||||||
// Different banner types have different defaults, see above for default values and the enum for
|
// Different banner types have different defaults, see above for default values and the enum for
|
||||||
// which are used where.
|
// which are used where.
|
||||||
@Getter private int[] fallbackItems5Pool1;
|
@Getter private int[] fallbackItems5Pool1;
|
||||||
@Getter private int[] fallbackItems5Pool2;
|
@Getter private int[] fallbackItems5Pool2;
|
||||||
private int[][] weights4;
|
private int[][] weights4;
|
||||||
private int[][] weights5;
|
private int[][] weights5;
|
||||||
private int eventChance4 = -1; // Chance to win a featured event item
|
private int eventChance4 = -1; // Chance to win a featured event item
|
||||||
private int eventChance5 = -1; // Chance to win a featured event item
|
private int eventChance5 = -1; // Chance to win a featured event item
|
||||||
//
|
//
|
||||||
@Getter private final boolean removeC6FromPool = false;
|
@Getter private boolean removeC6FromPool = false;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
private final boolean autoStripRateUpFromFallback =
|
private boolean autoStripRateUpFromFallback =
|
||||||
true; // Ensures that featured items won't "double dip" into the losing pool
|
true; // Ensures that featured items won't "double dip" into the losing pool
|
||||||
|
|
||||||
private final int[][] poolBalanceWeights4 = {
|
private int[][] poolBalanceWeights4 = {
|
||||||
{1, 255}, {17, 255}, {21, 10455}
|
{1, 255}, {17, 255}, {21, 10455}
|
||||||
}; // Used to ensure that players won't go too many rolls without getting something from pool 1
|
}; // Used to ensure that players won't go too many rolls without getting something from pool 1
|
||||||
// (avatar) or pool 2 (weapon)
|
// (avatar) or pool 2 (weapon)
|
||||||
private final int[][] poolBalanceWeights5 = {{1, 30}, {147, 150}, {181, 10230}};
|
private int[][] poolBalanceWeights5 = {{1, 30}, {147, 150}, {181, 10230}};
|
||||||
@Getter private final int wishMaxProgress = 2;
|
@Getter private int wishMaxProgress = 2;
|
||||||
|
|
||||||
// Deprecated fields that were tolerated in early May 2022 but have apparently still being
|
// Deprecated fields that were tolerated in early May 2022 but have apparently still being
|
||||||
// circulating in new custom configs
|
// circulating in new custom configs
|
||||||
// For now, throw up big scary errors on load telling people that they will be banned outright in
|
// For now, throw up big scary errors on load telling people that they will be banned outright in
|
||||||
// a future version
|
// a future version
|
||||||
@Deprecated private final int[] rateUpItems1 = {};
|
@Deprecated private int[] rateUpItems1 = {};
|
||||||
@Deprecated private final int[] rateUpItems2 = {};
|
@Deprecated private int[] rateUpItems2 = {};
|
||||||
@Deprecated private final int eventChance = -1;
|
@Deprecated private int eventChance = -1;
|
||||||
@Deprecated private final int costItem = 0;
|
@Deprecated private int costItem = 0;
|
||||||
@Deprecated private final int softPity = -1;
|
@Deprecated private int softPity = -1;
|
||||||
@Deprecated private final int hardPity = -1;
|
@Deprecated private int hardPity = -1;
|
||||||
@Deprecated private final int minItemType = -1;
|
@Deprecated private int minItemType = -1;
|
||||||
@Deprecated private final int maxItemType = -1;
|
@Deprecated private int maxItemType = -1;
|
||||||
@Getter private boolean deprecated = false;
|
@Getter private boolean deprecated = false;
|
||||||
@Getter private final boolean disabled = false;
|
@Getter private boolean disabled = false;
|
||||||
|
|
||||||
private void warnDeprecated(String name, String replacement) {
|
private void warnDeprecated(String name, String replacement) {
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.error(
|
.error(
|
||||||
"Deprecated field found in Banners config: "
|
"Deprecated field found in Banners config: "
|
||||||
+ name
|
+ name
|
||||||
+ " was replaced back in early May 2022, use "
|
+ " was replaced back in early May 2022, use "
|
||||||
+ replacement
|
+ replacement
|
||||||
+ " instead. You MUST remove this field from your config.");
|
+ " instead. You MUST remove this field from your config.");
|
||||||
this.deprecated = true;
|
this.deprecated = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onLoad() {
|
public void onLoad() {
|
||||||
// Handle deprecated configs
|
// Handle deprecated configs
|
||||||
if (eventChance != -1) warnDeprecated("eventChance", "eventChance4 & eventChance5");
|
if (eventChance != -1) warnDeprecated("eventChance", "eventChance4 & eventChance5");
|
||||||
if (costItem != 0) warnDeprecated("costItem", "costItemId");
|
if (costItem != 0) warnDeprecated("costItem", "costItemId");
|
||||||
if (softPity != -1) warnDeprecated("softPity", "weights5");
|
if (softPity != -1) warnDeprecated("softPity", "weights5");
|
||||||
if (hardPity != -1) warnDeprecated("hardPity", "weights5");
|
if (hardPity != -1) warnDeprecated("hardPity", "weights5");
|
||||||
if (minItemType != -1) warnDeprecated("minItemType", "fallbackItems[4,5]Pool[1,2]");
|
if (minItemType != -1) warnDeprecated("minItemType", "fallbackItems[4,5]Pool[1,2]");
|
||||||
if (maxItemType != -1) warnDeprecated("maxItemType", "fallbackItems[4,5]Pool[1,2]");
|
if (maxItemType != -1) warnDeprecated("maxItemType", "fallbackItems[4,5]Pool[1,2]");
|
||||||
if (rateUpItems1.length > 0) warnDeprecated("rateUpItems1", "rateUpItems5");
|
if (rateUpItems1.length > 0) warnDeprecated("rateUpItems1", "rateUpItems5");
|
||||||
if (rateUpItems2.length > 0) warnDeprecated("rateUpItems2", "rateUpItems4");
|
if (rateUpItems2.length > 0) warnDeprecated("rateUpItems2", "rateUpItems4");
|
||||||
|
|
||||||
// Handle default values
|
// Handle default values
|
||||||
if (this.previewPrefabPath != null
|
if (this.previewPrefabPath != null
|
||||||
&& this.previewPrefabPath.equals("UI_Tab_" + this.prefabPath))
|
&& this.previewPrefabPath.equals("UI_Tab_" + this.prefabPath))
|
||||||
Grasscutter.getLogger()
|
Grasscutter.getLogger()
|
||||||
.error(
|
.error(
|
||||||
"Redundant field found in Banners config: previewPrefabPath does not need to be specified if it is identical to prefabPath prefixed with \"UI_Tab_\".");
|
"Redundant field found in Banners config: previewPrefabPath does not need to be specified if it is identical to prefabPath prefixed with \"UI_Tab_\".");
|
||||||
if (this.previewPrefabPath == null || this.previewPrefabPath.isEmpty())
|
if (this.previewPrefabPath == null || this.previewPrefabPath.isEmpty())
|
||||||
this.previewPrefabPath = "UI_Tab_" + this.prefabPath;
|
this.previewPrefabPath = "UI_Tab_" + this.prefabPath;
|
||||||
if (this.gachaType < 0) this.gachaType = this.bannerType.gachaType;
|
if (this.gachaType < 0) this.gachaType = this.bannerType.gachaType;
|
||||||
if (this.costItemId == 0) this.costItemId = this.bannerType.costItemId;
|
if (this.costItemId == 0) this.costItemId = this.bannerType.costItemId;
|
||||||
if (this.costItemId10 == 0) this.costItemId10 = this.costItemId;
|
if (this.costItemId10 == 0) this.costItemId10 = this.costItemId;
|
||||||
if (this.weights4 == null) this.weights4 = this.bannerType.weights4;
|
if (this.weights4 == null) this.weights4 = this.bannerType.weights4;
|
||||||
if (this.weights5 == null) this.weights5 = this.bannerType.weights5;
|
if (this.weights5 == null) this.weights5 = this.bannerType.weights5;
|
||||||
if (this.eventChance4 < 0) this.eventChance4 = this.bannerType.eventChance4;
|
if (this.eventChance4 < 0) this.eventChance4 = this.bannerType.eventChance4;
|
||||||
if (this.eventChance5 < 0) this.eventChance5 = this.bannerType.eventChance5;
|
if (this.eventChance5 < 0) this.eventChance5 = this.bannerType.eventChance5;
|
||||||
if (this.fallbackItems5Pool1 == null)
|
if (this.fallbackItems5Pool1 == null)
|
||||||
this.fallbackItems5Pool1 = this.bannerType.fallbackItems5Pool1;
|
this.fallbackItems5Pool1 = this.bannerType.fallbackItems5Pool1;
|
||||||
if (this.fallbackItems5Pool2 == null)
|
if (this.fallbackItems5Pool2 == null)
|
||||||
this.fallbackItems5Pool2 = this.bannerType.fallbackItems5Pool2;
|
this.fallbackItems5Pool2 = this.bannerType.fallbackItems5Pool2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemParamData getCost(int numRolls) {
|
public ItemParamData getCost(int numRolls) {
|
||||||
return switch (numRolls) {
|
return switch (numRolls) {
|
||||||
case 10 -> new ItemParamData(costItemId10, costItemAmount10);
|
case 10 -> new ItemParamData(costItemId10, costItemAmount10);
|
||||||
default -> new ItemParamData(costItemId, costItemAmount * numRolls);
|
default -> new ItemParamData(costItemId, costItemAmount * numRolls);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public int getCostItem() {
|
public int getCostItem() {
|
||||||
return costItemId;
|
return costItemId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasEpitomized() {
|
public boolean hasEpitomized() {
|
||||||
return bannerType.equals(BannerType.WEAPON);
|
return bannerType.equals(BannerType.WEAPON);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getWeight(int rarity, int pity) {
|
public int getWeight(int rarity, int pity) {
|
||||||
return switch (rarity) {
|
return switch (rarity) {
|
||||||
case 4 -> Utils.lerp(pity, weights4);
|
case 4 -> Utils.lerp(pity, weights4);
|
||||||
default -> Utils.lerp(pity, weights5);
|
default -> Utils.lerp(pity, weights5);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getPoolBalanceWeight(int rarity, int pity) {
|
public int getPoolBalanceWeight(int rarity, int pity) {
|
||||||
return switch (rarity) {
|
return switch (rarity) {
|
||||||
case 4 -> Utils.lerp(pity, poolBalanceWeights4);
|
case 4 -> Utils.lerp(pity, poolBalanceWeights4);
|
||||||
default -> Utils.lerp(pity, poolBalanceWeights5);
|
default -> Utils.lerp(pity, poolBalanceWeights5);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEventChance(int rarity) {
|
public int getEventChance(int rarity) {
|
||||||
return switch (rarity) {
|
return switch (rarity) {
|
||||||
case 4 -> eventChance4;
|
case 4 -> eventChance4;
|
||||||
default -> eventChance5;
|
default -> eventChance5;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public GachaInfo toProto(Player player) {
|
public GachaInfo toProto(Player player) {
|
||||||
// TODO: use other Nonce/key insteadof session key to ensure the overall security for the player
|
// TODO: use other Nonce/key insteadof session key to ensure the overall security for the player
|
||||||
String sessionKey = player.getAccount().getSessionKey();
|
String sessionKey = player.getAccount().getSessionKey();
|
||||||
|
|
||||||
String record =
|
String record =
|
||||||
"http"
|
"http"
|
||||||
+ (HTTP_ENCRYPTION.useInRouting ? "s" : "")
|
+ (HTTP_ENCRYPTION.useInRouting ? "s" : "")
|
||||||
+ "://"
|
+ "://"
|
||||||
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress)
|
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress)
|
||||||
+ ":"
|
+ ":"
|
||||||
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
||||||
+ "/gacha?s="
|
+ "/gacha?s="
|
||||||
+ sessionKey
|
+ sessionKey
|
||||||
+ "&gachaType="
|
+ "&gachaType="
|
||||||
+ gachaType;
|
+ gachaType;
|
||||||
String details =
|
String details =
|
||||||
"http"
|
"http"
|
||||||
+ (HTTP_ENCRYPTION.useInRouting ? "s" : "")
|
+ (HTTP_ENCRYPTION.useInRouting ? "s" : "")
|
||||||
+ "://"
|
+ "://"
|
||||||
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress)
|
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress)
|
||||||
+ ":"
|
+ ":"
|
||||||
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
||||||
+ "/gacha/details?s="
|
+ "/gacha/details?s="
|
||||||
+ sessionKey
|
+ sessionKey
|
||||||
+ "&scheduleId="
|
+ "&scheduleId="
|
||||||
+ scheduleId;
|
+ scheduleId;
|
||||||
|
|
||||||
// Grasscutter.getLogger().info("record = " + record);
|
// Grasscutter.getLogger().info("record = " + record);
|
||||||
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
|
PlayerGachaBannerInfo gachaInfo = player.getGachaInfo().getBannerInfo(this);
|
||||||
int leftGachaTimes =
|
int leftGachaTimes =
|
||||||
switch (gachaTimesLimit) {
|
switch (gachaTimesLimit) {
|
||||||
case Integer.MAX_VALUE -> Integer.MAX_VALUE;
|
case Integer.MAX_VALUE -> Integer.MAX_VALUE;
|
||||||
default -> Math.max(gachaTimesLimit - gachaInfo.getTotalPulls(), 0);
|
default -> Math.max(gachaTimesLimit - gachaInfo.getTotalPulls(), 0);
|
||||||
};
|
};
|
||||||
GachaInfo.Builder info =
|
GachaInfo.Builder info =
|
||||||
GachaInfo.newBuilder()
|
GachaInfo.newBuilder()
|
||||||
.setGachaType(this.getGachaType())
|
.setGachaType(this.getGachaType())
|
||||||
.setScheduleId(this.getScheduleId())
|
.setScheduleId(this.getScheduleId())
|
||||||
.setBeginTime(this.getBeginTime())
|
.setBeginTime(this.getBeginTime())
|
||||||
.setEndTime(this.getEndTime())
|
.setEndTime(this.getEndTime())
|
||||||
.setCostItemId(this.costItemId)
|
.setCostItemId(this.costItemId)
|
||||||
.setCostItemNum(this.costItemAmount)
|
.setCostItemNum(this.costItemAmount)
|
||||||
.setTenCostItemId(this.costItemId10)
|
.setTenCostItemId(this.costItemId10)
|
||||||
.setTenCostItemNum(this.costItemAmount10)
|
.setTenCostItemNum(this.costItemAmount10)
|
||||||
.setGachaPrefabPath(this.getPrefabPath())
|
.setGachaPrefabPath(this.getPrefabPath())
|
||||||
.setGachaPreviewPrefabPath(this.getPreviewPrefabPath())
|
.setGachaPreviewPrefabPath(this.getPreviewPrefabPath())
|
||||||
.setGachaProbUrl(details)
|
.setGachaProbUrl(details)
|
||||||
.setGachaProbUrlOversea(details)
|
.setGachaProbUrlOversea(details)
|
||||||
.setGachaRecordUrl(record)
|
.setGachaRecordUrl(record)
|
||||||
.setGachaRecordUrlOversea(record)
|
.setGachaRecordUrlOversea(record)
|
||||||
.setLeftGachaTimes(leftGachaTimes)
|
.setLeftGachaTimes(leftGachaTimes)
|
||||||
.setGachaTimesLimit(gachaTimesLimit)
|
.setGachaTimesLimit(gachaTimesLimit)
|
||||||
.setGachaSortId(this.getSortId());
|
.setGachaSortId(this.getSortId());
|
||||||
|
|
||||||
if (hasEpitomized()) {
|
if (hasEpitomized()) {
|
||||||
info.setWishItemId(gachaInfo.getWishItemId())
|
info.setWishItemId(gachaInfo.getWishItemId())
|
||||||
.setWishProgress(gachaInfo.getFailedChosenItemPulls())
|
.setWishProgress(gachaInfo.getFailedChosenItemPulls())
|
||||||
.setWishMaxProgress(this.getWishMaxProgress());
|
.setWishMaxProgress(this.getWishMaxProgress());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getTitlePath() != null) {
|
if (this.getTitlePath() != null) {
|
||||||
info.setTitleTextmap(this.getTitlePath());
|
info.setTitleTextmap(this.getTitlePath());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getRateUpItems5().length > 0) {
|
if (this.getRateUpItems5().length > 0) {
|
||||||
GachaUpInfo.Builder upInfo = GachaUpInfo.newBuilder().setItemParentType(1);
|
GachaUpInfo.Builder upInfo = GachaUpInfo.newBuilder().setItemParentType(1);
|
||||||
|
|
||||||
for (int id : getRateUpItems5()) {
|
for (int id : getRateUpItems5()) {
|
||||||
upInfo.addItemIdList(id);
|
upInfo.addItemIdList(id);
|
||||||
info.addDisplayUp5ItemList(id);
|
info.addDisplayUp5ItemList(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
info.addGachaUpInfoList(upInfo);
|
info.addGachaUpInfoList(upInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.getRateUpItems4().length > 0) {
|
if (this.getRateUpItems4().length > 0) {
|
||||||
GachaUpInfo.Builder upInfo = GachaUpInfo.newBuilder().setItemParentType(2);
|
GachaUpInfo.Builder upInfo = GachaUpInfo.newBuilder().setItemParentType(2);
|
||||||
|
|
||||||
for (int id : getRateUpItems4()) {
|
for (int id : getRateUpItems4()) {
|
||||||
upInfo.addItemIdList(id);
|
upInfo.addItemIdList(id);
|
||||||
if (info.getDisplayUp4ItemListCount() == 0) {
|
if (info.getDisplayUp4ItemListCount() == 0) {
|
||||||
info.addDisplayUp4ItemList(id);
|
info.addDisplayUp4ItemList(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info.addGachaUpInfoList(upInfo);
|
info.addGachaUpInfoList(upInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
return info.build();
|
return info.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum BannerType {
|
public enum BannerType {
|
||||||
STANDARD(
|
STANDARD(
|
||||||
200,
|
200,
|
||||||
224,
|
224,
|
||||||
DEFAULT_WEIGHTS_4,
|
DEFAULT_WEIGHTS_4,
|
||||||
DEFAULT_WEIGHTS_5,
|
DEFAULT_WEIGHTS_5,
|
||||||
50,
|
50,
|
||||||
50,
|
50,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_2),
|
DEFAULT_FALLBACK_ITEMS_5_POOL_2),
|
||||||
BEGINNER(
|
BEGINNER(
|
||||||
100,
|
100,
|
||||||
224,
|
224,
|
||||||
DEFAULT_WEIGHTS_4,
|
DEFAULT_WEIGHTS_4,
|
||||||
DEFAULT_WEIGHTS_5,
|
DEFAULT_WEIGHTS_5,
|
||||||
50,
|
50,
|
||||||
50,
|
50,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_2),
|
DEFAULT_FALLBACK_ITEMS_5_POOL_2),
|
||||||
EVENT(
|
EVENT(
|
||||||
301,
|
301,
|
||||||
223,
|
223,
|
||||||
DEFAULT_WEIGHTS_4,
|
DEFAULT_WEIGHTS_4,
|
||||||
DEFAULT_WEIGHTS_5_CHARACTER,
|
DEFAULT_WEIGHTS_5_CHARACTER,
|
||||||
50,
|
50,
|
||||||
50,
|
50,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_2), // Legacy value for CHARACTER
|
DEFAULT_FALLBACK_ITEMS_5_POOL_2), // Legacy value for CHARACTER
|
||||||
CHARACTER(
|
CHARACTER(
|
||||||
301,
|
301,
|
||||||
223,
|
223,
|
||||||
DEFAULT_WEIGHTS_4,
|
DEFAULT_WEIGHTS_4,
|
||||||
DEFAULT_WEIGHTS_5_CHARACTER,
|
DEFAULT_WEIGHTS_5_CHARACTER,
|
||||||
50,
|
50,
|
||||||
50,
|
50,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
||||||
EMPTY_POOL),
|
EMPTY_POOL),
|
||||||
CHARACTER2(
|
CHARACTER2(
|
||||||
400,
|
400,
|
||||||
223,
|
223,
|
||||||
DEFAULT_WEIGHTS_4,
|
DEFAULT_WEIGHTS_4,
|
||||||
DEFAULT_WEIGHTS_5_CHARACTER,
|
DEFAULT_WEIGHTS_5_CHARACTER,
|
||||||
50,
|
50,
|
||||||
50,
|
50,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
DEFAULT_FALLBACK_ITEMS_5_POOL_1,
|
||||||
EMPTY_POOL),
|
EMPTY_POOL),
|
||||||
WEAPON(
|
WEAPON(
|
||||||
302,
|
302,
|
||||||
223,
|
223,
|
||||||
DEFAULT_WEIGHTS_4_WEAPON,
|
DEFAULT_WEIGHTS_4_WEAPON,
|
||||||
DEFAULT_WEIGHTS_5_WEAPON,
|
DEFAULT_WEIGHTS_5_WEAPON,
|
||||||
75,
|
75,
|
||||||
75,
|
75,
|
||||||
EMPTY_POOL,
|
EMPTY_POOL,
|
||||||
DEFAULT_FALLBACK_ITEMS_5_POOL_2);
|
DEFAULT_FALLBACK_ITEMS_5_POOL_2);
|
||||||
|
|
||||||
public final int gachaType;
|
public final int gachaType;
|
||||||
public final int costItemId;
|
public final int costItemId;
|
||||||
public final int[][] weights4;
|
public final int[][] weights4;
|
||||||
public final int[][] weights5;
|
public final int[][] weights5;
|
||||||
public final int eventChance4;
|
public final int eventChance4;
|
||||||
public final int eventChance5;
|
public final int eventChance5;
|
||||||
public final int[] fallbackItems5Pool1;
|
public final int[] fallbackItems5Pool1;
|
||||||
public final int[] fallbackItems5Pool2;
|
public final int[] fallbackItems5Pool2;
|
||||||
|
|
||||||
BannerType(
|
BannerType(
|
||||||
int gachaType,
|
int gachaType,
|
||||||
int costItemId,
|
int costItemId,
|
||||||
int[][] weights4,
|
int[][] weights4,
|
||||||
int[][] weights5,
|
int[][] weights5,
|
||||||
int eventChance4,
|
int eventChance4,
|
||||||
int eventChance5,
|
int eventChance5,
|
||||||
int[] fallbackItems5Pool1,
|
int[] fallbackItems5Pool1,
|
||||||
int[] fallbackItems5Pool2) {
|
int[] fallbackItems5Pool2) {
|
||||||
this.gachaType = gachaType;
|
this.gachaType = gachaType;
|
||||||
this.costItemId = costItemId;
|
this.costItemId = costItemId;
|
||||||
this.weights4 = weights4;
|
this.weights4 = weights4;
|
||||||
this.weights5 = weights5;
|
this.weights5 = weights5;
|
||||||
this.eventChance4 = eventChance4;
|
this.eventChance4 = eventChance4;
|
||||||
this.eventChance5 = eventChance5;
|
this.eventChance5 = eventChance5;
|
||||||
this.fallbackItems5Pool1 = fallbackItems5Pool1;
|
this.fallbackItems5Pool1 = fallbackItems5Pool1;
|
||||||
this.fallbackItems5Pool2 = fallbackItems5Pool2;
|
this.fallbackItems5Pool2 = fallbackItems5Pool2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,62 +1,62 @@
|
|||||||
package emu.grasscutter.game.managers.mapmark;
|
package emu.grasscutter.game.managers.mapmark;
|
||||||
|
|
||||||
import dev.morphia.annotations.Entity;
|
import dev.morphia.annotations.Entity;
|
||||||
import emu.grasscutter.net.proto.MapMarkFromTypeOuterClass.MapMarkFromType;
|
import emu.grasscutter.net.proto.MapMarkFromTypeOuterClass.MapMarkFromType;
|
||||||
import emu.grasscutter.net.proto.MapMarkPointOuterClass.MapMarkPoint;
|
import emu.grasscutter.net.proto.MapMarkPointOuterClass.MapMarkPoint;
|
||||||
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
|
import emu.grasscutter.net.proto.MapMarkPointTypeOuterClass.MapMarkPointType;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
public class MapMark {
|
public class MapMark {
|
||||||
private int sceneId;
|
private int sceneId;
|
||||||
private String name;
|
private String name;
|
||||||
private Position position;
|
private Position position;
|
||||||
private final MapMarkPointType mapMarkPointType;
|
private MapMarkPointType mapMarkPointType;
|
||||||
private int monsterId;
|
private int monsterId;
|
||||||
private final MapMarkFromType mapMarkFromType;
|
private MapMarkFromType mapMarkFromType;
|
||||||
private int questId;
|
private int questId;
|
||||||
|
|
||||||
@Deprecated // Morhpia
|
@Deprecated // Morhpia
|
||||||
public MapMark() {
|
public MapMark() {
|
||||||
this.mapMarkPointType = MapMarkPointType.MAP_MARK_POINT_TYPE_MONSTER;
|
this.mapMarkPointType = MapMarkPointType.MAP_MARK_POINT_TYPE_MONSTER;
|
||||||
this.mapMarkFromType = MapMarkFromType.MAP_MARK_FROM_TYPE_MONSTER;
|
this.mapMarkFromType = MapMarkFromType.MAP_MARK_FROM_TYPE_MONSTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapMark(MapMarkPoint mapMarkPoint) {
|
public MapMark(MapMarkPoint mapMarkPoint) {
|
||||||
this.sceneId = mapMarkPoint.getSceneId();
|
this.sceneId = mapMarkPoint.getSceneId();
|
||||||
this.name = mapMarkPoint.getName();
|
this.name = mapMarkPoint.getName();
|
||||||
this.position = new Position(mapMarkPoint.getPos());
|
this.position = new Position(mapMarkPoint.getPos());
|
||||||
this.mapMarkPointType = mapMarkPoint.getPointType();
|
this.mapMarkPointType = mapMarkPoint.getPointType();
|
||||||
this.monsterId = mapMarkPoint.getMonsterId();
|
this.monsterId = mapMarkPoint.getMonsterId();
|
||||||
this.mapMarkFromType = mapMarkPoint.getFromType();
|
this.mapMarkFromType = mapMarkPoint.getFromType();
|
||||||
this.questId = mapMarkPoint.getQuestId();
|
this.questId = mapMarkPoint.getQuestId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSceneId() {
|
public int getSceneId() {
|
||||||
return this.sceneId;
|
return this.sceneId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
return this.name;
|
return this.name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Position getPosition() {
|
public Position getPosition() {
|
||||||
return this.position;
|
return this.position;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapMarkPointType getMapMarkPointType() {
|
public MapMarkPointType getMapMarkPointType() {
|
||||||
return this.mapMarkPointType;
|
return this.mapMarkPointType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getMonsterId() {
|
public int getMonsterId() {
|
||||||
return this.monsterId;
|
return this.monsterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public MapMarkFromType getMapMarkFromType() {
|
public MapMarkFromType getMapMarkFromType() {
|
||||||
return this.mapMarkFromType;
|
return this.mapMarkFromType;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getQuestId() {
|
public int getQuestId() {
|
||||||
return this.questId;
|
return this.questId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,14 +17,14 @@ public class PlayerCodex {
|
|||||||
@Transient private Player player;
|
@Transient private Player player;
|
||||||
|
|
||||||
// itemId is not codexId!
|
// itemId is not codexId!
|
||||||
@Getter private final Set<Integer> unlockedWeapon;
|
@Getter private Set<Integer> unlockedWeapon;
|
||||||
@Getter private final Map<Integer, Integer> unlockedAnimal;
|
@Getter private Map<Integer, Integer> unlockedAnimal;
|
||||||
@Getter private final Set<Integer> unlockedMaterial;
|
@Getter private Set<Integer> unlockedMaterial;
|
||||||
@Getter private final Set<Integer> unlockedBook;
|
@Getter private Set<Integer> unlockedBook;
|
||||||
@Getter private final Set<Integer> unlockedTip;
|
@Getter private Set<Integer> unlockedTip;
|
||||||
@Getter private final Set<Integer> unlockedView;
|
@Getter private Set<Integer> unlockedView;
|
||||||
@Getter private Set<Integer> unlockedReliquary;
|
@Getter private Set<Integer> unlockedReliquary;
|
||||||
@Getter private final Set<Integer> unlockedReliquarySuitCodex;
|
@Getter private Set<Integer> unlockedReliquarySuitCodex;
|
||||||
|
|
||||||
public PlayerCodex() {
|
public PlayerCodex() {
|
||||||
this.unlockedWeapon = new HashSet<>();
|
this.unlockedWeapon = new HashSet<>();
|
||||||
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
@Entity
|
@Entity
|
||||||
public final class TeamInfo {
|
public final class TeamInfo {
|
||||||
private String name;
|
private String name;
|
||||||
private final List<Integer> avatars;
|
private List<Integer> avatars;
|
||||||
|
|
||||||
public TeamInfo() {
|
public TeamInfo() {
|
||||||
this.name = "";
|
this.name = "";
|
||||||
|
@ -1,263 +1,263 @@
|
|||||||
package emu.grasscutter.game.props;
|
package emu.grasscutter.game.props;
|
||||||
|
|
||||||
import static java.util.Map.entry;
|
import static java.util.Map.entry;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
|
||||||
public enum FightProperty {
|
public enum FightProperty {
|
||||||
FIGHT_PROP_NONE(0),
|
FIGHT_PROP_NONE(0),
|
||||||
FIGHT_PROP_BASE_HP(1),
|
FIGHT_PROP_BASE_HP(1),
|
||||||
FIGHT_PROP_HP(2),
|
FIGHT_PROP_HP(2),
|
||||||
FIGHT_PROP_HP_PERCENT(3),
|
FIGHT_PROP_HP_PERCENT(3),
|
||||||
FIGHT_PROP_BASE_ATTACK(4),
|
FIGHT_PROP_BASE_ATTACK(4),
|
||||||
FIGHT_PROP_ATTACK(5),
|
FIGHT_PROP_ATTACK(5),
|
||||||
FIGHT_PROP_ATTACK_PERCENT(6),
|
FIGHT_PROP_ATTACK_PERCENT(6),
|
||||||
FIGHT_PROP_BASE_DEFENSE(7),
|
FIGHT_PROP_BASE_DEFENSE(7),
|
||||||
FIGHT_PROP_DEFENSE(8),
|
FIGHT_PROP_DEFENSE(8),
|
||||||
FIGHT_PROP_DEFENSE_PERCENT(9),
|
FIGHT_PROP_DEFENSE_PERCENT(9),
|
||||||
FIGHT_PROP_BASE_SPEED(10),
|
FIGHT_PROP_BASE_SPEED(10),
|
||||||
FIGHT_PROP_SPEED_PERCENT(11),
|
FIGHT_PROP_SPEED_PERCENT(11),
|
||||||
FIGHT_PROP_HP_MP_PERCENT(12),
|
FIGHT_PROP_HP_MP_PERCENT(12),
|
||||||
FIGHT_PROP_ATTACK_MP_PERCENT(13),
|
FIGHT_PROP_ATTACK_MP_PERCENT(13),
|
||||||
FIGHT_PROP_CRITICAL(20),
|
FIGHT_PROP_CRITICAL(20),
|
||||||
FIGHT_PROP_ANTI_CRITICAL(21),
|
FIGHT_PROP_ANTI_CRITICAL(21),
|
||||||
FIGHT_PROP_CRITICAL_HURT(22),
|
FIGHT_PROP_CRITICAL_HURT(22),
|
||||||
FIGHT_PROP_CHARGE_EFFICIENCY(23),
|
FIGHT_PROP_CHARGE_EFFICIENCY(23),
|
||||||
FIGHT_PROP_ADD_HURT(24),
|
FIGHT_PROP_ADD_HURT(24),
|
||||||
FIGHT_PROP_SUB_HURT(25),
|
FIGHT_PROP_SUB_HURT(25),
|
||||||
FIGHT_PROP_HEAL_ADD(26),
|
FIGHT_PROP_HEAL_ADD(26),
|
||||||
FIGHT_PROP_HEALED_ADD(27),
|
FIGHT_PROP_HEALED_ADD(27),
|
||||||
FIGHT_PROP_ELEMENT_MASTERY(28),
|
FIGHT_PROP_ELEMENT_MASTERY(28),
|
||||||
FIGHT_PROP_PHYSICAL_SUB_HURT(29),
|
FIGHT_PROP_PHYSICAL_SUB_HURT(29),
|
||||||
FIGHT_PROP_PHYSICAL_ADD_HURT(30),
|
FIGHT_PROP_PHYSICAL_ADD_HURT(30),
|
||||||
FIGHT_PROP_DEFENCE_IGNORE_RATIO(31),
|
FIGHT_PROP_DEFENCE_IGNORE_RATIO(31),
|
||||||
FIGHT_PROP_DEFENCE_IGNORE_DELTA(32),
|
FIGHT_PROP_DEFENCE_IGNORE_DELTA(32),
|
||||||
FIGHT_PROP_FIRE_ADD_HURT(40),
|
FIGHT_PROP_FIRE_ADD_HURT(40),
|
||||||
FIGHT_PROP_ELEC_ADD_HURT(41),
|
FIGHT_PROP_ELEC_ADD_HURT(41),
|
||||||
FIGHT_PROP_WATER_ADD_HURT(42),
|
FIGHT_PROP_WATER_ADD_HURT(42),
|
||||||
FIGHT_PROP_GRASS_ADD_HURT(43),
|
FIGHT_PROP_GRASS_ADD_HURT(43),
|
||||||
FIGHT_PROP_WIND_ADD_HURT(44),
|
FIGHT_PROP_WIND_ADD_HURT(44),
|
||||||
FIGHT_PROP_ROCK_ADD_HURT(45),
|
FIGHT_PROP_ROCK_ADD_HURT(45),
|
||||||
FIGHT_PROP_ICE_ADD_HURT(46),
|
FIGHT_PROP_ICE_ADD_HURT(46),
|
||||||
FIGHT_PROP_HIT_HEAD_ADD_HURT(47),
|
FIGHT_PROP_HIT_HEAD_ADD_HURT(47),
|
||||||
FIGHT_PROP_FIRE_SUB_HURT(50),
|
FIGHT_PROP_FIRE_SUB_HURT(50),
|
||||||
FIGHT_PROP_ELEC_SUB_HURT(51),
|
FIGHT_PROP_ELEC_SUB_HURT(51),
|
||||||
FIGHT_PROP_WATER_SUB_HURT(52),
|
FIGHT_PROP_WATER_SUB_HURT(52),
|
||||||
FIGHT_PROP_GRASS_SUB_HURT(53),
|
FIGHT_PROP_GRASS_SUB_HURT(53),
|
||||||
FIGHT_PROP_WIND_SUB_HURT(54),
|
FIGHT_PROP_WIND_SUB_HURT(54),
|
||||||
FIGHT_PROP_ROCK_SUB_HURT(55),
|
FIGHT_PROP_ROCK_SUB_HURT(55),
|
||||||
FIGHT_PROP_ICE_SUB_HURT(56),
|
FIGHT_PROP_ICE_SUB_HURT(56),
|
||||||
FIGHT_PROP_EFFECT_HIT(60),
|
FIGHT_PROP_EFFECT_HIT(60),
|
||||||
FIGHT_PROP_EFFECT_RESIST(61),
|
FIGHT_PROP_EFFECT_RESIST(61),
|
||||||
FIGHT_PROP_FREEZE_RESIST(62),
|
FIGHT_PROP_FREEZE_RESIST(62),
|
||||||
FIGHT_PROP_TORPOR_RESIST(63),
|
FIGHT_PROP_TORPOR_RESIST(63),
|
||||||
FIGHT_PROP_DIZZY_RESIST(64),
|
FIGHT_PROP_DIZZY_RESIST(64),
|
||||||
FIGHT_PROP_FREEZE_SHORTEN(65),
|
FIGHT_PROP_FREEZE_SHORTEN(65),
|
||||||
FIGHT_PROP_TORPOR_SHORTEN(66),
|
FIGHT_PROP_TORPOR_SHORTEN(66),
|
||||||
FIGHT_PROP_DIZZY_SHORTEN(67),
|
FIGHT_PROP_DIZZY_SHORTEN(67),
|
||||||
FIGHT_PROP_MAX_FIRE_ENERGY(70),
|
FIGHT_PROP_MAX_FIRE_ENERGY(70),
|
||||||
FIGHT_PROP_MAX_ELEC_ENERGY(71),
|
FIGHT_PROP_MAX_ELEC_ENERGY(71),
|
||||||
FIGHT_PROP_MAX_WATER_ENERGY(72),
|
FIGHT_PROP_MAX_WATER_ENERGY(72),
|
||||||
FIGHT_PROP_MAX_GRASS_ENERGY(73),
|
FIGHT_PROP_MAX_GRASS_ENERGY(73),
|
||||||
FIGHT_PROP_MAX_WIND_ENERGY(74),
|
FIGHT_PROP_MAX_WIND_ENERGY(74),
|
||||||
FIGHT_PROP_MAX_ICE_ENERGY(75),
|
FIGHT_PROP_MAX_ICE_ENERGY(75),
|
||||||
FIGHT_PROP_MAX_ROCK_ENERGY(76),
|
FIGHT_PROP_MAX_ROCK_ENERGY(76),
|
||||||
FIGHT_PROP_SKILL_CD_MINUS_RATIO(80),
|
FIGHT_PROP_SKILL_CD_MINUS_RATIO(80),
|
||||||
FIGHT_PROP_SHIELD_COST_MINUS_RATIO(81),
|
FIGHT_PROP_SHIELD_COST_MINUS_RATIO(81),
|
||||||
FIGHT_PROP_CUR_FIRE_ENERGY(1000),
|
FIGHT_PROP_CUR_FIRE_ENERGY(1000),
|
||||||
FIGHT_PROP_CUR_ELEC_ENERGY(1001),
|
FIGHT_PROP_CUR_ELEC_ENERGY(1001),
|
||||||
FIGHT_PROP_CUR_WATER_ENERGY(1002),
|
FIGHT_PROP_CUR_WATER_ENERGY(1002),
|
||||||
FIGHT_PROP_CUR_GRASS_ENERGY(1003),
|
FIGHT_PROP_CUR_GRASS_ENERGY(1003),
|
||||||
FIGHT_PROP_CUR_WIND_ENERGY(1004),
|
FIGHT_PROP_CUR_WIND_ENERGY(1004),
|
||||||
FIGHT_PROP_CUR_ICE_ENERGY(1005),
|
FIGHT_PROP_CUR_ICE_ENERGY(1005),
|
||||||
FIGHT_PROP_CUR_ROCK_ENERGY(1006),
|
FIGHT_PROP_CUR_ROCK_ENERGY(1006),
|
||||||
FIGHT_PROP_CUR_HP(1010),
|
FIGHT_PROP_CUR_HP(1010),
|
||||||
FIGHT_PROP_MAX_HP(2000),
|
FIGHT_PROP_MAX_HP(2000),
|
||||||
FIGHT_PROP_CUR_ATTACK(2001),
|
FIGHT_PROP_CUR_ATTACK(2001),
|
||||||
FIGHT_PROP_CUR_DEFENSE(2002),
|
FIGHT_PROP_CUR_DEFENSE(2002),
|
||||||
FIGHT_PROP_CUR_SPEED(2003),
|
FIGHT_PROP_CUR_SPEED(2003),
|
||||||
FIGHT_PROP_NONEXTRA_ATTACK(3000),
|
FIGHT_PROP_NONEXTRA_ATTACK(3000),
|
||||||
FIGHT_PROP_NONEXTRA_DEFENSE(3001),
|
FIGHT_PROP_NONEXTRA_DEFENSE(3001),
|
||||||
FIGHT_PROP_NONEXTRA_CRITICAL(3002),
|
FIGHT_PROP_NONEXTRA_CRITICAL(3002),
|
||||||
FIGHT_PROP_NONEXTRA_ANTI_CRITICAL(3003),
|
FIGHT_PROP_NONEXTRA_ANTI_CRITICAL(3003),
|
||||||
FIGHT_PROP_NONEXTRA_CRITICAL_HURT(3004),
|
FIGHT_PROP_NONEXTRA_CRITICAL_HURT(3004),
|
||||||
FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY(3005),
|
FIGHT_PROP_NONEXTRA_CHARGE_EFFICIENCY(3005),
|
||||||
FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY(3006),
|
FIGHT_PROP_NONEXTRA_ELEMENT_MASTERY(3006),
|
||||||
FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT(3007),
|
FIGHT_PROP_NONEXTRA_PHYSICAL_SUB_HURT(3007),
|
||||||
FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT(3008),
|
FIGHT_PROP_NONEXTRA_FIRE_ADD_HURT(3008),
|
||||||
FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT(3009),
|
FIGHT_PROP_NONEXTRA_ELEC_ADD_HURT(3009),
|
||||||
FIGHT_PROP_NONEXTRA_WATER_ADD_HURT(3010),
|
FIGHT_PROP_NONEXTRA_WATER_ADD_HURT(3010),
|
||||||
FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT(3011),
|
FIGHT_PROP_NONEXTRA_GRASS_ADD_HURT(3011),
|
||||||
FIGHT_PROP_NONEXTRA_WIND_ADD_HURT(3012),
|
FIGHT_PROP_NONEXTRA_WIND_ADD_HURT(3012),
|
||||||
FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT(3013),
|
FIGHT_PROP_NONEXTRA_ROCK_ADD_HURT(3013),
|
||||||
FIGHT_PROP_NONEXTRA_ICE_ADD_HURT(3014),
|
FIGHT_PROP_NONEXTRA_ICE_ADD_HURT(3014),
|
||||||
FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT(3015),
|
FIGHT_PROP_NONEXTRA_FIRE_SUB_HURT(3015),
|
||||||
FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT(3016),
|
FIGHT_PROP_NONEXTRA_ELEC_SUB_HURT(3016),
|
||||||
FIGHT_PROP_NONEXTRA_WATER_SUB_HURT(3017),
|
FIGHT_PROP_NONEXTRA_WATER_SUB_HURT(3017),
|
||||||
FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT(3018),
|
FIGHT_PROP_NONEXTRA_GRASS_SUB_HURT(3018),
|
||||||
FIGHT_PROP_NONEXTRA_WIND_SUB_HURT(3019),
|
FIGHT_PROP_NONEXTRA_WIND_SUB_HURT(3019),
|
||||||
FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT(3020),
|
FIGHT_PROP_NONEXTRA_ROCK_SUB_HURT(3020),
|
||||||
FIGHT_PROP_NONEXTRA_ICE_SUB_HURT(3021),
|
FIGHT_PROP_NONEXTRA_ICE_SUB_HURT(3021),
|
||||||
FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO(3022),
|
FIGHT_PROP_NONEXTRA_SKILL_CD_MINUS_RATIO(3022),
|
||||||
FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO(3023),
|
FIGHT_PROP_NONEXTRA_SHIELD_COST_MINUS_RATIO(3023),
|
||||||
FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT(3024);
|
FIGHT_PROP_NONEXTRA_PHYSICAL_ADD_HURT(3024);
|
||||||
|
|
||||||
public static final int[] fightProps =
|
public static final int[] fightProps =
|
||||||
new int[] {
|
new int[] {
|
||||||
1, 4, 7, 20, 21, 22, 23, 26, 27, 28, 29, 30, 40, 41, 42, 43, 44, 45, 46, 50, 51, 52, 53, 54,
|
1, 4, 7, 20, 21, 22, 23, 26, 27, 28, 29, 30, 40, 41, 42, 43, 44, 45, 46, 50, 51, 52, 53, 54,
|
||||||
55, 56, 2000, 2001, 2002, 2003, 1010
|
55, 56, 2000, 2001, 2002, 2003, 1010
|
||||||
};
|
};
|
||||||
private static final Int2ObjectMap<FightProperty> map = new Int2ObjectOpenHashMap<>();
|
private static final Int2ObjectMap<FightProperty> map = new Int2ObjectOpenHashMap<>();
|
||||||
private static final Map<String, FightProperty> stringMap = new HashMap<>();
|
private static final Map<String, FightProperty> stringMap = new HashMap<>();
|
||||||
// This was originally for relic properties so some names might not be applicable for e.g.
|
// This was originally for relic properties so some names might not be applicable for e.g.
|
||||||
// setstats
|
// setstats
|
||||||
private static final Map<String, FightProperty> shortNameMap =
|
private static final Map<String, FightProperty> shortNameMap =
|
||||||
Map.ofEntries(
|
Map.ofEntries(
|
||||||
// Normal relic stats
|
// Normal relic stats
|
||||||
entry("hp", FIGHT_PROP_HP),
|
entry("hp", FIGHT_PROP_HP),
|
||||||
entry("atk", FIGHT_PROP_ATTACK),
|
entry("atk", FIGHT_PROP_ATTACK),
|
||||||
entry("def", FIGHT_PROP_DEFENSE),
|
entry("def", FIGHT_PROP_DEFENSE),
|
||||||
entry("hp%", FIGHT_PROP_HP_PERCENT),
|
entry("hp%", FIGHT_PROP_HP_PERCENT),
|
||||||
entry("atk%", FIGHT_PROP_ATTACK_PERCENT),
|
entry("atk%", FIGHT_PROP_ATTACK_PERCENT),
|
||||||
entry("def%", FIGHT_PROP_DEFENSE_PERCENT),
|
entry("def%", FIGHT_PROP_DEFENSE_PERCENT),
|
||||||
entry("em", FIGHT_PROP_ELEMENT_MASTERY),
|
entry("em", FIGHT_PROP_ELEMENT_MASTERY),
|
||||||
entry("er", FIGHT_PROP_CHARGE_EFFICIENCY),
|
entry("er", FIGHT_PROP_CHARGE_EFFICIENCY),
|
||||||
entry("hb", FIGHT_PROP_HEAL_ADD),
|
entry("hb", FIGHT_PROP_HEAL_ADD),
|
||||||
entry("heal", FIGHT_PROP_HEAL_ADD),
|
entry("heal", FIGHT_PROP_HEAL_ADD),
|
||||||
entry("cd", FIGHT_PROP_CRITICAL_HURT),
|
entry("cd", FIGHT_PROP_CRITICAL_HURT),
|
||||||
entry("cdmg", FIGHT_PROP_CRITICAL_HURT),
|
entry("cdmg", FIGHT_PROP_CRITICAL_HURT),
|
||||||
entry("cr", FIGHT_PROP_CRITICAL),
|
entry("cr", FIGHT_PROP_CRITICAL),
|
||||||
entry("crate", FIGHT_PROP_CRITICAL),
|
entry("crate", FIGHT_PROP_CRITICAL),
|
||||||
entry("phys%", FIGHT_PROP_PHYSICAL_ADD_HURT),
|
entry("phys%", FIGHT_PROP_PHYSICAL_ADD_HURT),
|
||||||
entry("dendro%", FIGHT_PROP_GRASS_ADD_HURT),
|
entry("dendro%", FIGHT_PROP_GRASS_ADD_HURT),
|
||||||
entry("geo%", FIGHT_PROP_ROCK_ADD_HURT),
|
entry("geo%", FIGHT_PROP_ROCK_ADD_HURT),
|
||||||
entry("anemo%", FIGHT_PROP_WIND_ADD_HURT),
|
entry("anemo%", FIGHT_PROP_WIND_ADD_HURT),
|
||||||
entry("hydro%", FIGHT_PROP_WATER_ADD_HURT),
|
entry("hydro%", FIGHT_PROP_WATER_ADD_HURT),
|
||||||
entry("cryo%", FIGHT_PROP_ICE_ADD_HURT),
|
entry("cryo%", FIGHT_PROP_ICE_ADD_HURT),
|
||||||
entry("electro%", FIGHT_PROP_ELEC_ADD_HURT),
|
entry("electro%", FIGHT_PROP_ELEC_ADD_HURT),
|
||||||
entry("pyro%", FIGHT_PROP_FIRE_ADD_HURT),
|
entry("pyro%", FIGHT_PROP_FIRE_ADD_HURT),
|
||||||
// Other stats
|
// Other stats
|
||||||
entry("maxhp", FIGHT_PROP_MAX_HP),
|
entry("maxhp", FIGHT_PROP_MAX_HP),
|
||||||
entry("dmg", FIGHT_PROP_ADD_HURT), // This seems to get reset after attacks
|
entry("dmg", FIGHT_PROP_ADD_HURT), // This seems to get reset after attacks
|
||||||
entry("cdr", FIGHT_PROP_SKILL_CD_MINUS_RATIO),
|
entry("cdr", FIGHT_PROP_SKILL_CD_MINUS_RATIO),
|
||||||
entry("heali", FIGHT_PROP_HEALED_ADD),
|
entry("heali", FIGHT_PROP_HEALED_ADD),
|
||||||
entry("shield", FIGHT_PROP_SHIELD_COST_MINUS_RATIO),
|
entry("shield", FIGHT_PROP_SHIELD_COST_MINUS_RATIO),
|
||||||
entry("defi", FIGHT_PROP_DEFENCE_IGNORE_RATIO),
|
entry("defi", FIGHT_PROP_DEFENCE_IGNORE_RATIO),
|
||||||
entry("resall", FIGHT_PROP_SUB_HURT), // This seems to get reset after attacks
|
entry("resall", FIGHT_PROP_SUB_HURT), // This seems to get reset after attacks
|
||||||
entry("resanemo", FIGHT_PROP_WIND_SUB_HURT),
|
entry("resanemo", FIGHT_PROP_WIND_SUB_HURT),
|
||||||
entry("rescryo", FIGHT_PROP_ICE_SUB_HURT),
|
entry("rescryo", FIGHT_PROP_ICE_SUB_HURT),
|
||||||
entry("resdendro", FIGHT_PROP_GRASS_SUB_HURT),
|
entry("resdendro", FIGHT_PROP_GRASS_SUB_HURT),
|
||||||
entry("reselectro", FIGHT_PROP_ELEC_SUB_HURT),
|
entry("reselectro", FIGHT_PROP_ELEC_SUB_HURT),
|
||||||
entry("resgeo", FIGHT_PROP_ROCK_SUB_HURT),
|
entry("resgeo", FIGHT_PROP_ROCK_SUB_HURT),
|
||||||
entry("reshydro", FIGHT_PROP_WATER_SUB_HURT),
|
entry("reshydro", FIGHT_PROP_WATER_SUB_HURT),
|
||||||
entry("respyro", FIGHT_PROP_FIRE_SUB_HURT),
|
entry("respyro", FIGHT_PROP_FIRE_SUB_HURT),
|
||||||
entry("resphys", FIGHT_PROP_PHYSICAL_SUB_HURT));
|
entry("resphys", FIGHT_PROP_PHYSICAL_SUB_HURT));
|
||||||
private static final List<FightProperty> flatProps =
|
private static final List<FightProperty> flatProps =
|
||||||
Arrays.asList(
|
Arrays.asList(
|
||||||
FIGHT_PROP_BASE_HP,
|
FIGHT_PROP_BASE_HP,
|
||||||
FIGHT_PROP_HP,
|
FIGHT_PROP_HP,
|
||||||
FIGHT_PROP_BASE_ATTACK,
|
FIGHT_PROP_BASE_ATTACK,
|
||||||
FIGHT_PROP_ATTACK,
|
FIGHT_PROP_ATTACK,
|
||||||
FIGHT_PROP_BASE_DEFENSE,
|
FIGHT_PROP_BASE_DEFENSE,
|
||||||
FIGHT_PROP_DEFENSE,
|
FIGHT_PROP_DEFENSE,
|
||||||
FIGHT_PROP_HEALED_ADD,
|
FIGHT_PROP_HEALED_ADD,
|
||||||
FIGHT_PROP_CUR_FIRE_ENERGY,
|
FIGHT_PROP_CUR_FIRE_ENERGY,
|
||||||
FIGHT_PROP_CUR_ELEC_ENERGY,
|
FIGHT_PROP_CUR_ELEC_ENERGY,
|
||||||
FIGHT_PROP_CUR_WATER_ENERGY,
|
FIGHT_PROP_CUR_WATER_ENERGY,
|
||||||
FIGHT_PROP_CUR_GRASS_ENERGY,
|
FIGHT_PROP_CUR_GRASS_ENERGY,
|
||||||
FIGHT_PROP_CUR_WIND_ENERGY,
|
FIGHT_PROP_CUR_WIND_ENERGY,
|
||||||
FIGHT_PROP_CUR_ICE_ENERGY,
|
FIGHT_PROP_CUR_ICE_ENERGY,
|
||||||
FIGHT_PROP_CUR_ROCK_ENERGY,
|
FIGHT_PROP_CUR_ROCK_ENERGY,
|
||||||
FIGHT_PROP_CUR_HP,
|
FIGHT_PROP_CUR_HP,
|
||||||
FIGHT_PROP_MAX_HP,
|
FIGHT_PROP_MAX_HP,
|
||||||
FIGHT_PROP_CUR_ATTACK,
|
FIGHT_PROP_CUR_ATTACK,
|
||||||
FIGHT_PROP_CUR_DEFENSE);
|
FIGHT_PROP_CUR_DEFENSE);
|
||||||
private static final Map<FightProperty, CompoundProperty> compoundProperties =
|
private static final Map<FightProperty, CompoundProperty> compoundProperties =
|
||||||
Map.ofEntries(
|
Map.ofEntries(
|
||||||
entry(
|
entry(
|
||||||
FIGHT_PROP_MAX_HP,
|
FIGHT_PROP_MAX_HP,
|
||||||
new CompoundProperty(
|
new CompoundProperty(
|
||||||
FIGHT_PROP_MAX_HP, FIGHT_PROP_BASE_HP, FIGHT_PROP_HP_PERCENT, FIGHT_PROP_HP)),
|
FIGHT_PROP_MAX_HP, FIGHT_PROP_BASE_HP, FIGHT_PROP_HP_PERCENT, FIGHT_PROP_HP)),
|
||||||
entry(
|
entry(
|
||||||
FIGHT_PROP_CUR_ATTACK,
|
FIGHT_PROP_CUR_ATTACK,
|
||||||
new CompoundProperty(
|
new CompoundProperty(
|
||||||
FIGHT_PROP_CUR_ATTACK,
|
FIGHT_PROP_CUR_ATTACK,
|
||||||
FIGHT_PROP_BASE_ATTACK,
|
FIGHT_PROP_BASE_ATTACK,
|
||||||
FIGHT_PROP_ATTACK_PERCENT,
|
FIGHT_PROP_ATTACK_PERCENT,
|
||||||
FIGHT_PROP_ATTACK)),
|
FIGHT_PROP_ATTACK)),
|
||||||
entry(
|
entry(
|
||||||
FIGHT_PROP_CUR_DEFENSE,
|
FIGHT_PROP_CUR_DEFENSE,
|
||||||
new CompoundProperty(
|
new CompoundProperty(
|
||||||
FIGHT_PROP_CUR_DEFENSE,
|
FIGHT_PROP_CUR_DEFENSE,
|
||||||
FIGHT_PROP_BASE_DEFENSE,
|
FIGHT_PROP_BASE_DEFENSE,
|
||||||
FIGHT_PROP_DEFENSE_PERCENT,
|
FIGHT_PROP_DEFENSE_PERCENT,
|
||||||
FIGHT_PROP_DEFENSE)));
|
FIGHT_PROP_DEFENSE)));
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Stream.of(values())
|
Stream.of(values())
|
||||||
.forEach(
|
.forEach(
|
||||||
e -> {
|
e -> {
|
||||||
map.put(e.getId(), e);
|
map.put(e.getId(), e);
|
||||||
stringMap.put(e.name(), e);
|
stringMap.put(e.name(), e);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private final int id;
|
private final int id;
|
||||||
|
|
||||||
FightProperty(int id) {
|
FightProperty(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FightProperty getPropById(int value) {
|
public static FightProperty getPropById(int value) {
|
||||||
return map.getOrDefault(value, FIGHT_PROP_NONE);
|
return map.getOrDefault(value, FIGHT_PROP_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FightProperty getPropByName(String name) {
|
public static FightProperty getPropByName(String name) {
|
||||||
return stringMap.getOrDefault(name, FIGHT_PROP_NONE);
|
return stringMap.getOrDefault(name, FIGHT_PROP_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static FightProperty getPropByShortName(String name) {
|
public static FightProperty getPropByShortName(String name) {
|
||||||
return shortNameMap.getOrDefault(name, FIGHT_PROP_NONE);
|
return shortNameMap.getOrDefault(name, FIGHT_PROP_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<String> getShortNames() {
|
public static Set<String> getShortNames() {
|
||||||
return shortNameMap.keySet();
|
return shortNameMap.keySet();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CompoundProperty getCompoundProperty(FightProperty result) {
|
public static CompoundProperty getCompoundProperty(FightProperty result) {
|
||||||
return compoundProperties.get(result);
|
return compoundProperties.get(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void forEachCompoundProperty(Consumer<CompoundProperty> consumer) {
|
public static void forEachCompoundProperty(Consumer<CompoundProperty> consumer) {
|
||||||
compoundProperties.values().forEach(consumer);
|
compoundProperties.values().forEach(consumer);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isPercentage(FightProperty prop) {
|
public static boolean isPercentage(FightProperty prop) {
|
||||||
return !flatProps.contains(prop);
|
return !flatProps.contains(prop);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
public static class CompoundProperty {
|
public static class CompoundProperty {
|
||||||
private final FightProperty result;
|
private final FightProperty result;
|
||||||
private final FightProperty base;
|
private final FightProperty base;
|
||||||
private final FightProperty percent;
|
private final FightProperty percent;
|
||||||
private final FightProperty flat;
|
private final FightProperty flat;
|
||||||
|
|
||||||
public CompoundProperty(
|
public CompoundProperty(
|
||||||
FightProperty result, FightProperty base, FightProperty percent, FightProperty flat) {
|
FightProperty result, FightProperty base, FightProperty percent, FightProperty flat) {
|
||||||
this.result = result;
|
this.result = result;
|
||||||
this.base = base;
|
this.base = base;
|
||||||
this.percent = percent;
|
this.percent = percent;
|
||||||
this.flat = flat;
|
this.flat = flat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package emu.grasscutter.game.props.ItemUseAction;
|
package emu.grasscutter.game.props.ItemUseAction;
|
||||||
|
|
||||||
import emu.grasscutter.game.props.ItemUseOp;
|
import emu.grasscutter.game.props.ItemUseOp;
|
||||||
|
|
||||||
public class ItemUseAddCurHp extends ItemUseInt {
|
public class ItemUseAddCurHp extends ItemUseInt {
|
||||||
private final String icon;
|
private final String icon;
|
||||||
|
|
||||||
public ItemUseAddCurHp(String[] useParam) {
|
public ItemUseAddCurHp(String[] useParam) {
|
||||||
super(useParam);
|
super(useParam);
|
||||||
this.icon = useParam[1];
|
this.icon = useParam[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemUseOp getItemUseOp() {
|
public ItemUseOp getItemUseOp() {
|
||||||
return ItemUseOp.ITEM_USE_ADD_CUR_HP;
|
return ItemUseOp.ITEM_USE_ADD_CUR_HP;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean useItem(UseItemParams params) {
|
public boolean useItem(UseItemParams params) {
|
||||||
return (params.targetAvatar.getAsEntity().heal(params.count * this.i) > 0.01);
|
return (params.targetAvatar.getAsEntity().heal(params.count * this.i) > 0.01);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,38 +1,38 @@
|
|||||||
package emu.grasscutter.game.props.ItemUseAction;
|
package emu.grasscutter.game.props.ItemUseAction;
|
||||||
|
|
||||||
import emu.grasscutter.game.props.ItemUseOp;
|
import emu.grasscutter.game.props.ItemUseOp;
|
||||||
|
|
||||||
public class ItemUseChestSelectItem extends ItemUseSelectItems {
|
public class ItemUseChestSelectItem extends ItemUseSelectItems {
|
||||||
private final int[] optionItemCounts;
|
private final int[] optionItemCounts;
|
||||||
|
|
||||||
public ItemUseChestSelectItem(String[] useParam) {
|
public ItemUseChestSelectItem(String[] useParam) {
|
||||||
String[] options = useParam[0].split(",");
|
String[] options = useParam[0].split(",");
|
||||||
this.optionItemIds = new int[options.length];
|
this.optionItemIds = new int[options.length];
|
||||||
this.optionItemCounts = new int[options.length];
|
this.optionItemCounts = new int[options.length];
|
||||||
for (int i = 0; i < options.length; i++) {
|
for (int i = 0; i < options.length; i++) {
|
||||||
String[] optionParts = options[i].split(":");
|
String[] optionParts = options[i].split(":");
|
||||||
try {
|
try {
|
||||||
this.optionItemIds[i] = Integer.parseInt(optionParts[0]);
|
this.optionItemIds[i] = Integer.parseInt(optionParts[0]);
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
this.optionItemIds[i] = INVALID;
|
this.optionItemIds[i] = INVALID;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
this.optionItemCounts[i] = Integer.parseInt(optionParts[1]);
|
this.optionItemCounts[i] = Integer.parseInt(optionParts[1]);
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
this.optionItemCounts[i] = INVALID;
|
this.optionItemCounts[i] = INVALID;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemUseOp getItemUseOp() {
|
public ItemUseOp getItemUseOp() {
|
||||||
return ItemUseOp.ITEM_USE_CHEST_SELECT_ITEM;
|
return ItemUseOp.ITEM_USE_CHEST_SELECT_ITEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int getItemCount(int index) {
|
protected int getItemCount(int index) {
|
||||||
if ((optionItemCounts == null) || (index < 0) || (index > optionItemCounts.length))
|
if ((optionItemCounts == null) || (index < 0) || (index > optionItemCounts.length))
|
||||||
return INVALID;
|
return INVALID;
|
||||||
return this.optionItemCounts[index];
|
return this.optionItemCounts[index];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,97 +1,97 @@
|
|||||||
package emu.grasscutter.game.world;
|
package emu.grasscutter.game.world;
|
||||||
|
|
||||||
import emu.grasscutter.data.GameDepot;
|
import emu.grasscutter.data.GameDepot;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
public class SpawnDataEntry {
|
public class SpawnDataEntry {
|
||||||
@Getter @Setter private transient SpawnGroupEntry group;
|
@Getter @Setter private transient SpawnGroupEntry group;
|
||||||
@Getter private int monsterId;
|
@Getter private int monsterId;
|
||||||
@Getter private int gadgetId;
|
@Getter private int gadgetId;
|
||||||
@Getter private int configId;
|
@Getter private int configId;
|
||||||
@Getter private int level;
|
@Getter private int level;
|
||||||
@Getter private int poseId;
|
@Getter private int poseId;
|
||||||
@Getter private int gatherItemId;
|
@Getter private int gatherItemId;
|
||||||
@Getter private int gadgetState;
|
@Getter private int gadgetState;
|
||||||
@Getter private Position pos;
|
@Getter private Position pos;
|
||||||
@Getter private Position rot;
|
@Getter private Position rot;
|
||||||
|
|
||||||
public GridBlockId getBlockId() {
|
public GridBlockId getBlockId() {
|
||||||
int scale = GridBlockId.getScale(gadgetId);
|
int scale = GridBlockId.getScale(gadgetId);
|
||||||
return new GridBlockId(
|
return new GridBlockId(
|
||||||
group.sceneId,
|
group.sceneId,
|
||||||
scale,
|
scale,
|
||||||
(int) (pos.getX() / GameDepot.BLOCK_SIZE[scale]),
|
(int) (pos.getX() / GameDepot.BLOCK_SIZE[scale]),
|
||||||
(int) (pos.getZ() / GameDepot.BLOCK_SIZE[scale]));
|
(int) (pos.getZ() / GameDepot.BLOCK_SIZE[scale]));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SpawnGroupEntry {
|
public static class SpawnGroupEntry {
|
||||||
@Getter private int sceneId;
|
@Getter private int sceneId;
|
||||||
@Getter private int groupId;
|
@Getter private int groupId;
|
||||||
@Getter private int blockId;
|
@Getter private int blockId;
|
||||||
@Getter @Setter private List<SpawnDataEntry> spawns;
|
@Getter @Setter private List<SpawnDataEntry> spawns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class GridBlockId {
|
public static class GridBlockId {
|
||||||
@Getter private final int sceneId;
|
@Getter private int sceneId;
|
||||||
@Getter private final int scale;
|
@Getter private int scale;
|
||||||
@Getter private final int x;
|
@Getter private int x;
|
||||||
@Getter private final int z;
|
@Getter private int z;
|
||||||
|
|
||||||
public GridBlockId(int sceneId, int scale, int x, int z) {
|
public GridBlockId(int sceneId, int scale, int x, int z) {
|
||||||
this.sceneId = sceneId;
|
this.sceneId = sceneId;
|
||||||
this.scale = scale;
|
this.scale = scale;
|
||||||
this.x = x;
|
this.x = x;
|
||||||
this.z = z;
|
this.z = z;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GridBlockId[] getAdjacentGridBlockIds(int sceneId, Position pos) {
|
public static GridBlockId[] getAdjacentGridBlockIds(int sceneId, Position pos) {
|
||||||
GridBlockId[] results = new GridBlockId[5 * 5 * GameDepot.BLOCK_SIZE.length];
|
GridBlockId[] results = new GridBlockId[5 * 5 * GameDepot.BLOCK_SIZE.length];
|
||||||
int t = 0;
|
int t = 0;
|
||||||
for (int scale = 0; scale < GameDepot.BLOCK_SIZE.length; scale++) {
|
for (int scale = 0; scale < GameDepot.BLOCK_SIZE.length; scale++) {
|
||||||
int x = ((int) (pos.getX() / GameDepot.BLOCK_SIZE[scale]));
|
int x = ((int) (pos.getX() / GameDepot.BLOCK_SIZE[scale]));
|
||||||
int z = ((int) (pos.getZ() / GameDepot.BLOCK_SIZE[scale]));
|
int z = ((int) (pos.getZ() / GameDepot.BLOCK_SIZE[scale]));
|
||||||
for (int i = x - 2; i < x + 3; i++) {
|
for (int i = x - 2; i < x + 3; i++) {
|
||||||
for (int j = z - 2; j < z + 3; j++) {
|
for (int j = z - 2; j < z + 3; j++) {
|
||||||
results[t++] = new GridBlockId(sceneId, scale, i, j);
|
results[t++] = new GridBlockId(sceneId, scale, i, j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static int getScale(int gadgetId) {
|
public static int getScale(int gadgetId) {
|
||||||
return 0; // you should implement here,this is index of GameDepot.BLOCK_SIZE
|
return 0; // you should implement here,this is index of GameDepot.BLOCK_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "SpawnDataEntryScaledPoint{"
|
return "SpawnDataEntryScaledPoint{"
|
||||||
+ "sceneId="
|
+ "sceneId="
|
||||||
+ sceneId
|
+ sceneId
|
||||||
+ ", scale="
|
+ ", scale="
|
||||||
+ scale
|
+ scale
|
||||||
+ ", x="
|
+ ", x="
|
||||||
+ x
|
+ x
|
||||||
+ ", z="
|
+ ", z="
|
||||||
+ z
|
+ z
|
||||||
+ '}';
|
+ '}';
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (this == o) return true;
|
if (this == o) return true;
|
||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
GridBlockId that = (GridBlockId) o;
|
GridBlockId that = (GridBlockId) o;
|
||||||
return sceneId == that.sceneId && scale == that.scale && x == that.x && z == that.z;
|
return sceneId == that.sceneId && scale == that.scale && x == that.x && z == that.z;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(sceneId, scale, x, z);
|
return Objects.hash(sceneId, scale, x, z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,12 +37,12 @@ public class World implements Iterable<Player> {
|
|||||||
@Getter private final List<Player> players;
|
@Getter private final List<Player> players;
|
||||||
@Getter private final Int2ObjectMap<Scene> scenes;
|
@Getter private final Int2ObjectMap<Scene> scenes;
|
||||||
|
|
||||||
@Getter private final int levelEntityId;
|
@Getter private int levelEntityId;
|
||||||
private int nextEntityId = 0;
|
private int nextEntityId = 0;
|
||||||
private int nextPeerId = 0;
|
private int nextPeerId = 0;
|
||||||
private int worldLevel;
|
private int worldLevel;
|
||||||
|
|
||||||
private final boolean isMultiplayer;
|
private boolean isMultiplayer;
|
||||||
|
|
||||||
private long lastUpdateTime;
|
private long lastUpdateTime;
|
||||||
@Getter private int tickCount = 0;
|
@Getter private int tickCount = 0;
|
||||||
|
@ -36,10 +36,10 @@ public class ScriptLoader {
|
|||||||
@Getter private static ScriptLib scriptLib;
|
@Getter private static ScriptLib scriptLib;
|
||||||
@Getter private static LuaValue scriptLibLua;
|
@Getter private static LuaValue scriptLibLua;
|
||||||
/** suggest GC to remove it if the memory is less */
|
/** suggest GC to remove it if the memory is less */
|
||||||
private static final Map<String, SoftReference<CompiledScript>> scriptsCache =
|
private static Map<String, SoftReference<CompiledScript>> scriptsCache =
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
/** sceneId - SceneMeta */
|
/** sceneId - SceneMeta */
|
||||||
private static final Map<Integer, SoftReference<SceneMeta>> sceneMetaCache =
|
private static Map<Integer, SoftReference<SceneMeta>> sceneMetaCache =
|
||||||
new ConcurrentHashMap<>();
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
public static synchronized void init() throws Exception {
|
public static synchronized void init() throws Exception {
|
||||||
|
@ -1,26 +1,26 @@
|
|||||||
package emu.grasscutter.server.http.documentation;
|
package emu.grasscutter.server.http.documentation;
|
||||||
|
|
||||||
import static emu.grasscutter.config.Configuration.DOCUMENT_LANGUAGE;
|
import static emu.grasscutter.config.Configuration.DOCUMENT_LANGUAGE;
|
||||||
|
|
||||||
import emu.grasscutter.tools.Tools;
|
import emu.grasscutter.tools.Tools;
|
||||||
import emu.grasscutter.utils.Language;
|
import emu.grasscutter.utils.Language;
|
||||||
import io.javalin.http.ContentType;
|
import io.javalin.http.ContentType;
|
||||||
import io.javalin.http.Context;
|
import io.javalin.http.Context;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
final class GachaMappingRequestHandler implements DocumentationHandler {
|
final class GachaMappingRequestHandler implements DocumentationHandler {
|
||||||
private final List<String> gachaJsons;
|
private final List<String> gachaJsons;
|
||||||
|
|
||||||
GachaMappingRequestHandler() {
|
GachaMappingRequestHandler() {
|
||||||
this.gachaJsons = Tools.createGachaMappingJsons();
|
this.gachaJsons = Tools.createGachaMappingJsons();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(Context ctx) {
|
public void handle(Context ctx) {
|
||||||
final int langIdx =
|
final int langIdx =
|
||||||
Language.TextStrings.MAP_LANGUAGES.getOrDefault(
|
Language.TextStrings.MAP_LANGUAGES.getOrDefault(
|
||||||
DOCUMENT_LANGUAGE,
|
DOCUMENT_LANGUAGE,
|
||||||
0); // TODO: This should really be based off the client language somehow
|
0); // TODO: This should really be based off the client language somehow
|
||||||
ctx.contentType(ContentType.APPLICATION_JSON).result(gachaJsons.get(langIdx));
|
ctx.contentType(ContentType.APPLICATION_JSON).result(gachaJsons.get(langIdx));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,48 @@
|
|||||||
package emu.grasscutter.server.packet.send;
|
package emu.grasscutter.server.packet.send;
|
||||||
|
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo;
|
import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo;
|
||||||
import emu.grasscutter.net.proto.PrivateChatNotifyOuterClass.PrivateChatNotify;
|
import emu.grasscutter.net.proto.PrivateChatNotifyOuterClass.PrivateChatNotify;
|
||||||
|
|
||||||
public class PacketPrivateChatNotify extends BasePacket {
|
public class PacketPrivateChatNotify extends BasePacket {
|
||||||
private final ChatInfo info;
|
private final ChatInfo info;
|
||||||
|
|
||||||
public PacketPrivateChatNotify(int senderId, int recvId, String message) {
|
public PacketPrivateChatNotify(int senderId, int recvId, String message) {
|
||||||
super(PacketOpcodes.PrivateChatNotify);
|
super(PacketOpcodes.PrivateChatNotify);
|
||||||
|
|
||||||
ChatInfo info =
|
ChatInfo info =
|
||||||
ChatInfo.newBuilder()
|
ChatInfo.newBuilder()
|
||||||
.setTime((int) (System.currentTimeMillis() / 1000))
|
.setTime((int) (System.currentTimeMillis() / 1000))
|
||||||
.setUid(senderId)
|
.setUid(senderId)
|
||||||
.setToUid(recvId)
|
.setToUid(recvId)
|
||||||
.setText(message)
|
.setText(message)
|
||||||
.build();
|
.build();
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
|
||||||
PrivateChatNotify proto = PrivateChatNotify.newBuilder().setChatInfo(info).build();
|
PrivateChatNotify proto = PrivateChatNotify.newBuilder().setChatInfo(info).build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
public PacketPrivateChatNotify(int senderId, int recvId, int emote) {
|
public PacketPrivateChatNotify(int senderId, int recvId, int emote) {
|
||||||
super(PacketOpcodes.PrivateChatNotify);
|
super(PacketOpcodes.PrivateChatNotify);
|
||||||
|
|
||||||
ChatInfo info =
|
ChatInfo info =
|
||||||
ChatInfo.newBuilder()
|
ChatInfo.newBuilder()
|
||||||
.setTime((int) (System.currentTimeMillis() / 1000))
|
.setTime((int) (System.currentTimeMillis() / 1000))
|
||||||
.setUid(senderId)
|
.setUid(senderId)
|
||||||
.setToUid(recvId)
|
.setToUid(recvId)
|
||||||
.setIcon(emote)
|
.setIcon(emote)
|
||||||
.build();
|
.build();
|
||||||
this.info = info;
|
this.info = info;
|
||||||
|
|
||||||
PrivateChatNotify proto = PrivateChatNotify.newBuilder().setChatInfo(info).build();
|
PrivateChatNotify proto = PrivateChatNotify.newBuilder().setChatInfo(info).build();
|
||||||
|
|
||||||
this.setData(proto);
|
this.setData(proto);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatInfo getChatInfo() {
|
public ChatInfo getChatInfo() {
|
||||||
return this.info;
|
return this.info;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public class TsvUtils {
|
|||||||
private static final Function<String, Object> parseLong =
|
private static final Function<String, Object> parseLong =
|
||||||
value -> (long) Double.parseDouble(value); // Long::parseLong;
|
value -> (long) Double.parseDouble(value); // Long::parseLong;
|
||||||
private static final Map<Class<?>, Function<String, Object>> enumTypeParsers = new HashMap<>();
|
private static final Map<Class<?>, Function<String, Object>> enumTypeParsers = new HashMap<>();
|
||||||
private static final Map<Type, Function<String, Object>> primitiveTypeParsers =
|
private final static Map<Type, Function<String, Object>> primitiveTypeParsers =
|
||||||
Map.ofEntries(
|
Map.ofEntries(
|
||||||
Map.entry(String.class, parseString),
|
Map.entry(String.class, parseString),
|
||||||
Map.entry(Integer.class, parseInt),
|
Map.entry(Integer.class, parseInt),
|
||||||
@ -72,7 +72,7 @@ public class TsvUtils {
|
|||||||
Map.entry(boolean.class, Boolean::parseBoolean));
|
Map.entry(boolean.class, Boolean::parseBoolean));
|
||||||
private static final Map<Type, Function<String, Object>> typeParsers =
|
private static final Map<Type, Function<String, Object>> typeParsers =
|
||||||
new HashMap<>(primitiveTypeParsers);
|
new HashMap<>(primitiveTypeParsers);
|
||||||
private static final Map<Class<?>, Map<String, FieldParser>> cachedClassFieldMaps =
|
private final static Map<Class<?>, Map<String, FieldParser>> cachedClassFieldMaps =
|
||||||
new HashMap<>();
|
new HashMap<>();
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
Loading…
Reference in New Issue
Block a user