1/2 Player-specific TBMM battle config

Add support for custom stats per-player by player username.
This commit is contained in:
Stephen Seo 2024-10-31 14:34:40 +09:00
parent c58ca0fe37
commit 2c369a125a
5 changed files with 402 additions and 193 deletions

View file

@ -134,6 +134,9 @@ public class Battle {
} catch (NullPointerException exception) { } catch (NullPointerException exception) {
entityInfo = null; entityInfo = null;
} }
if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
}
if (entityInfo == null) { if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e); entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
} }
@ -166,6 +169,9 @@ public class Battle {
} catch (NullPointerException exception) { } catch (NullPointerException exception) {
entityInfo = null; entityInfo = null;
} }
if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
}
if (entityInfo == null) { if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e); entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
} }
@ -268,6 +274,9 @@ public class Battle {
} catch (NullPointerException exception) { } catch (NullPointerException exception) {
entityInfo = null; entityInfo = null;
} }
if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
}
if (entityInfo == null) { if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e); entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
} }
@ -316,6 +325,9 @@ public class Battle {
} catch (NullPointerException exception) { } catch (NullPointerException exception) {
entityInfo = null; entityInfo = null;
} }
if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
}
if (entityInfo == null) { if (entityInfo == null) {
entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e); entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
} }
@ -781,7 +793,7 @@ public class Battle {
case ATTACK: case ATTACK:
debugLog += " attack"; debugLog += " attack";
Combatant target = null; Combatant target = null;
if (next.entity instanceof Player) { if (next.entity instanceof Player player) {
debugLog += " as player"; debugLog += " as player";
target = sideA.get(next.targetEntityID); target = sideA.get(next.targetEntityID);
if (target == null) { if (target == null) {
@ -790,15 +802,15 @@ public class Battle {
if (target == null || !target.entity.isAlive() || target == next) { if (target == null || !target.entity.isAlive() || target == next) {
continue; continue;
} }
ItemStack heldItemStack = ((Player) next.entity).getMainHandItem(); ItemStack heldItemStack = player.getMainHandItem();
if (heldItemStack.getItem() instanceof BowItem) { if (heldItemStack.getItem() instanceof BowItem) {
debugLog += " with bow"; debugLog += " with bow";
if (Utility.doesPlayerHaveArrows((Player) next.entity)) { if (Utility.doesPlayerHaveArrows(player)) {
final Entity nextEntity = next.entity; final Entity nextEntity = next.entity;
final Entity targetEntity = target.entity; final Entity targetEntity = target.entity;
final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ()); final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ());
final float pitchDirection = Utility.pitchDirection(next.entity.getX(), next.entity.getY(), next.entity.getZ(), target.entity.getX(), target.entity.getY(), target.entity.getZ()); final float pitchDirection = Utility.pitchDirection(next.entity.getX(), next.entity.getY(), next.entity.getZ(), target.entity.getX(), target.entity.getY(), target.entity.getZ());
final int randomTimeLeft = random.nextInt(heldItemStack.getItem().getUseDuration(heldItemStack, (LivingEntity)next.entity) / 3); final int randomTimeLeft = random.nextInt(heldItemStack.getItem().getUseDuration(heldItemStack, player) / 3);
if (TurnBasedMinecraftMod.proxy.getConfig().isFreezeCombatantsEnabled()) { if (TurnBasedMinecraftMod.proxy.getConfig().isFreezeCombatantsEnabled()) {
next.yaw = yawDirection; next.yaw = yawDirection;
next.pitch = pitchDirection; next.pitch = pitchDirection;
@ -815,7 +827,7 @@ public class Battle {
continue; continue;
} else if (heldItemStack.getItem() instanceof CrossbowItem) { } else if (heldItemStack.getItem() instanceof CrossbowItem) {
debugLog += " with crossbow"; debugLog += " with crossbow";
if (Utility.doesPlayerHaveArrows((Player) next.entity)) { if (Utility.doesPlayerHaveArrows(player)) {
final Entity nextEntity = next.entity; final Entity nextEntity = next.entity;
final Entity targetEntity = target.entity; final Entity targetEntity = target.entity;
final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ()); final float yawDirection = Utility.yawDirection(next.entity.getX(), next.entity.getZ(), target.entity.getX(), target.entity.getZ());
@ -837,9 +849,18 @@ public class Battle {
continue; continue;
} }
debugLog += " without bow"; debugLog += " without bow";
int hitChance = TurnBasedMinecraftMod.proxy.getConfig().getPlayerAttackProbability(); int hitChance;
if (next.entityInfo != null && !next.entityInfo.playerName.isEmpty()) {
hitChance = next.entityInfo.attackProbability;
} else {
hitChance = TurnBasedMinecraftMod.proxy.getConfig().getPlayerAttackProbability();
}
if (target.entity instanceof Player) { if (target.entity instanceof Player) {
hitChance = hitChance * (100 - TurnBasedMinecraftMod.proxy.getConfig().getPlayerEvasion()) / 100; if (target.entityInfo != null && !target.entityInfo.playerName.isEmpty()) {
hitChance = hitChance * (100 - target.entityInfo.evasion) / 100;
} else {
hitChance = hitChance * (100 - TurnBasedMinecraftMod.proxy.getConfig().getPlayerEvasion()) / 100;
}
} else { } else {
hitChance = hitChance * (100 - target.entityInfo.evasion) / 100; hitChance = hitChance * (100 - target.entityInfo.evasion) / 100;
} }
@ -1020,48 +1041,111 @@ public class Battle {
int fastestEnemySpeed = 0; int fastestEnemySpeed = 0;
if (next.isSideA) { if (next.isSideA) {
for (Combatant c : sideB.values()) { for (Combatant c : sideB.values()) {
if (c.entity instanceof Player) { if (c.entity instanceof Player player) {
int playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed(); int playerSpeed;
if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SPEED)) { if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed(); playerSpeed = c.entityInfo.speed;
} else if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) { } else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed(); playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
}
if (player.hasEffect(MobEffects.MOVEMENT_SPEED)) {
if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
playerSpeed = c.entityInfo.hasteSpeed;
} else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed();
}
} else if (player.hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
playerSpeed = c.entityInfo.slowSpeed;
} else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed();
}
} }
if (playerSpeed > fastestEnemySpeed) { if (playerSpeed > fastestEnemySpeed) {
fastestEnemySpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed(); fastestEnemySpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
} }
} else { } else {
if (c.entityInfo.speed > fastestEnemySpeed) { if (c.entity instanceof LivingEntity livingEntity) {
if (livingEntity.hasEffect(MobEffects.MOVEMENT_SPEED)) {
if (c.entityInfo.hasteSpeed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.hasteSpeed;
}
} else if (livingEntity.hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
if (c.entityInfo.slowSpeed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.slowSpeed;
}
} else if (c.entityInfo.speed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.speed;
}
} else if (c.entityInfo.speed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.speed; fastestEnemySpeed = c.entityInfo.speed;
} }
} }
} }
} else { } else {
for (Combatant c : sideA.values()) { for (Combatant c : sideA.values()) {
if (c.entity instanceof Player) { if (c.entity instanceof Player player) {
int playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed(); int playerSpeed;
if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SPEED)) { if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed(); playerSpeed = c.entityInfo.speed;
} else if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) { } else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed(); playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
}
if (player.hasEffect(MobEffects.MOVEMENT_SPEED)) {
if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
playerSpeed = c.entityInfo.hasteSpeed;
} else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed();
}
} else if (player.hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
playerSpeed = c.entityInfo.slowSpeed;
} else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed();
}
} }
if (playerSpeed > fastestEnemySpeed) { if (playerSpeed > fastestEnemySpeed) {
fastestEnemySpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed(); fastestEnemySpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
} }
} else { } else {
if (c.entityInfo.speed > fastestEnemySpeed) { if (c.entity instanceof LivingEntity livingEntity) {
if (livingEntity.hasEffect(MobEffects.MOVEMENT_SPEED)) {
if (c.entityInfo.hasteSpeed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.hasteSpeed;
}
} else if (livingEntity.hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
if (c.entityInfo.slowSpeed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.slowSpeed;
}
} else if (c.entityInfo.speed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.speed;
}
} else if (c.entityInfo.speed > fastestEnemySpeed) {
fastestEnemySpeed = c.entityInfo.speed; fastestEnemySpeed = c.entityInfo.speed;
} }
} }
} }
} }
int fleeProbability = 0; int fleeProbability = 0;
if (next.entity instanceof Player) { if (next.entity instanceof Player player) {
int playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed(); int playerSpeed;
if (((Player) next.entity).hasEffect(MobEffects.MOVEMENT_SPEED)) { if (next.entityInfo != null && !next.entityInfo.playerName.isEmpty()) {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed(); playerSpeed = next.entityInfo.speed;
} else if (((Player) next.entity).hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) { } else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed(); playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
}
if (player.hasEffect(MobEffects.MOVEMENT_SPEED)) {
if (next.entityInfo != null && !next.entityInfo.playerName.isEmpty()) {
playerSpeed = next.entityInfo.hasteSpeed;
} else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed();
}
} else if (player.hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
if (next.entityInfo != null && !next.entityInfo.playerName.isEmpty()) {
playerSpeed = next.entityInfo.slowSpeed;
} else {
playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed();
}
} }
if (fastestEnemySpeed >= playerSpeed) { if (fastestEnemySpeed >= playerSpeed) {
fleeProbability = TurnBasedMinecraftMod.proxy.getConfig().getFleeBadProbability(); fleeProbability = TurnBasedMinecraftMod.proxy.getConfig().getFleeBadProbability();

View file

@ -24,6 +24,7 @@ public class Config
private boolean battleDecisionDurationForever = false; private boolean battleDecisionDurationForever = false;
private Map<String, EntityInfo> entityInfoMap; private Map<String, EntityInfo> entityInfoMap;
private Map<String, EntityInfo> customEntityInfoMap; private Map<String, EntityInfo> customEntityInfoMap;
private Map<String, EntityInfo> customPlayerInfoMap;
private Set<String> ignoreBattleTypes; private Set<String> ignoreBattleTypes;
private Logger logger; private Logger logger;
private int playerSpeed = 50; private int playerSpeed = 50;
@ -57,6 +58,7 @@ public class Config
{ {
entityInfoMap = new HashMap<String, EntityInfo>(); entityInfoMap = new HashMap<String, EntityInfo>();
customEntityInfoMap = new HashMap<String, EntityInfo>(); customEntityInfoMap = new HashMap<String, EntityInfo>();
customPlayerInfoMap = new HashMap<String, EntityInfo>();
ignoreBattleTypes = new HashSet<String>(); ignoreBattleTypes = new HashSet<String>();
this.logger = logger; this.logger = logger;
battleIgnoringPlayers = new HashSet<Integer>(); battleIgnoringPlayers = new HashSet<Integer>();
@ -517,23 +519,33 @@ public class Config
logger.error("Entity with invalid custom_name (must be a string), skipping..."); logger.error("Entity with invalid custom_name (must be a string), skipping...");
continue; continue;
} }
} else if (nestedConf.contains("player_name")) {
try {
eInfo.playerName = nestedConf.get("player_name");
name = eInfo.playerName;
} catch (ClassCastException e) {
logger.error("Entity with invalid player_name (must be a string), skipping...");
continue;
}
} else { } else {
logger.error("Entity must have \"name\" or \"custom_name\" entry"); logger.error("Entity must have \"name\" or \"custom_name\" or \"player_name\" entry");
continue; continue;
} }
try { if (eInfo.playerName.isEmpty()) {
eInfo.attackPower = nestedConf.getInt("attack_power"); try {
if(eInfo.attackPower < 0) { eInfo.attackPower = nestedConf.getInt("attack_power");
logClampedValueEntity("attack_power", name, Integer.toString(eInfo.attackPower), "0"); if (eInfo.attackPower < 0) {
eInfo.attackPower = 0; logClampedValueEntity("attack_power", name, Integer.toString(eInfo.attackPower), "0");
eInfo.attackPower = 0;
}
} catch (ClassCastException e) {
logEntityInvalidValue("attack_power", name, "3");
eInfo.attackPower = 3;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("attack_power", name, "3");
eInfo.attackPower = 3;
} }
} catch (ClassCastException e) {
logEntityInvalidValue("attack_power", name, "3");
eInfo.attackPower = 3;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("attack_power", name, "3");
eInfo.attackPower = 3;
} }
try { try {
@ -553,77 +565,79 @@ public class Config
eInfo.attackProbability = 30; eInfo.attackProbability = 30;
} }
try { if (eInfo.playerName.isEmpty()) {
eInfo.attackEffect = EntityInfo.Effect.fromString(nestedConf.get("attack_effect")); try {
if(eInfo.attackEffect != EntityInfo.Effect.UNKNOWN) { eInfo.attackEffect = EntityInfo.Effect.fromString(nestedConf.get("attack_effect"));
try { if(eInfo.attackEffect != EntityInfo.Effect.UNKNOWN) {
eInfo.attackEffectProbability = nestedConf.getInt("attack_effect_probability"); try {
if(eInfo.attackEffectProbability < 0) { eInfo.attackEffectProbability = nestedConf.getInt("attack_effect_probability");
logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "1"); if(eInfo.attackEffectProbability < 0) {
eInfo.attackEffectProbability = 1; logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "1");
} else if(eInfo.attackEffectProbability > 100) { eInfo.attackEffectProbability = 1;
logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "100"); } else if(eInfo.attackEffectProbability > 100) {
eInfo.attackEffectProbability = 100; logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "100");
eInfo.attackEffectProbability = 100;
}
} catch (ClassCastException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logger.warn("Entity \"" + name + "\" has specified attack_effect but attack_effect_probability is invalid, unsetting attack_effect");
} catch (NullPointerException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logger.warn("Entity \"" + name + "\" has specified attack_effect but attack_effect_probability is missing, unsetting attack_effect");
} }
} catch (ClassCastException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logger.warn("Entity \"" + name + "\" has specified attack_effect but attack_effect_probability is invalid, unsetting attack_effect");
} catch (NullPointerException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logger.warn("Entity \"" + name + "\" has specified attack_effect but attack_effect_probability is missing, unsetting attack_effect");
} }
} catch (ClassCastException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logEntityInvalidValue("attack_effect", name, "unknown");
} catch (NullPointerException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logEntityMissingOptionalValue("attack_effect", name, "unknown");
} }
} catch (ClassCastException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logEntityInvalidValue("attack_effect", name, "unknown");
} catch (NullPointerException e) {
eInfo.attackEffect = EntityInfo.Effect.UNKNOWN;
logEntityMissingOptionalValue("attack_effect", name, "unknown");
}
try { try {
eInfo.attackVariance = nestedConf.getInt("attack_variance"); eInfo.attackVariance = nestedConf.getInt("attack_variance");
if(eInfo.attackVariance < 0) { if (eInfo.attackVariance < 0) {
logClampedValueEntity("attack_variance", name, Integer.toString(eInfo.attackVariance), "0"); logClampedValueEntity("attack_variance", name, Integer.toString(eInfo.attackVariance), "0");
eInfo.attackVariance = 0;
}
} catch (ClassCastException e) {
eInfo.attackVariance = 0; eInfo.attackVariance = 0;
logEntityInvalidValue("attack_variance", name, "0");
} catch (NullPointerException e) {
eInfo.attackVariance = 0;
logEntityMissingOptionalValue("attack_variance", name, "0");
} }
} catch (ClassCastException e) {
eInfo.attackVariance = 0;
logEntityInvalidValue("attack_variance", name, "0");
} catch (NullPointerException e) {
eInfo.attackVariance = 0;
logEntityMissingOptionalValue("attack_variance", name, "0");
}
try { try {
eInfo.defenseDamage = nestedConf.getInt("defense_damage"); eInfo.defenseDamage = nestedConf.getInt("defense_damage");
if(eInfo.defenseDamage < 0) { if (eInfo.defenseDamage < 0) {
logClampedValueEntity("defense_damage", name, Integer.toString(eInfo.defenseDamage), "0"); logClampedValueEntity("defense_damage", name, Integer.toString(eInfo.defenseDamage), "0");
eInfo.defenseDamage = 0; eInfo.defenseDamage = 0;
} else if(eInfo.defenseDamage != 0) { } else if (eInfo.defenseDamage != 0) {
try { try {
eInfo.defenseDamageProbability = nestedConf.getInt("defense_damage_probability"); eInfo.defenseDamageProbability = nestedConf.getInt("defense_damage_probability");
if(eInfo.defenseDamageProbability < 1) { if (eInfo.defenseDamageProbability < 1) {
logClampedValueEntity("defense_damage_probability", name, Integer.toString(eInfo.defenseDamageProbability), "1"); logClampedValueEntity("defense_damage_probability", name, Integer.toString(eInfo.defenseDamageProbability), "1");
eInfo.defenseDamageProbability = 1; eInfo.defenseDamageProbability = 1;
} else if(eInfo.defenseDamageProbability > 100) { } else if (eInfo.defenseDamageProbability > 100) {
logClampedValueEntity("defense_damage_probability", name, Integer.toString(eInfo.defenseDamageProbability), "100"); logClampedValueEntity("defense_damage_probability", name, Integer.toString(eInfo.defenseDamageProbability), "100");
eInfo.defenseDamageProbability = 100; eInfo.defenseDamageProbability = 100;
}
} catch (ClassCastException e) {
eInfo.defenseDamage = 0;
logger.warn("Entity \"" + name + "\" has specified defense_damage but defense_damage_probability is invalid, disabling defense_damage");
} catch (NullPointerException e) {
eInfo.defenseDamage = 0;
logger.warn("Entity \"" + name + "\" has specified defense_damage but defense_damage_probability is missing, disabling defense_damage");
} }
} catch (ClassCastException e) {
eInfo.defenseDamage = 0;
logger.warn("Entity \"" + name + "\" has specified defense_damage but defense_damage_probability is invalid, disabling defense_damage");
} catch (NullPointerException e) {
eInfo.defenseDamage = 0;
logger.warn("Entity \"" + name + "\" has specified defense_damage but defense_damage_probability is missing, disabling defense_damage");
} }
} catch (ClassCastException e) {
eInfo.defenseDamage = 0;
logEntityInvalidValue("defense_damage", name, "0");
} catch (NullPointerException e) {
eInfo.defenseDamage = 0;
logEntityMissingOptionalValue("defense_damage", name, "0");
} }
} catch (ClassCastException e) {
eInfo.defenseDamage = 0;
logEntityInvalidValue("defense_damage", name, "0");
} catch (NullPointerException e) {
eInfo.defenseDamage = 0;
logEntityMissingOptionalValue("defense_damage", name, "0");
} }
try { try {
@ -654,82 +668,106 @@ public class Config
} }
try { try {
eInfo.ignoreBattle = nestedConf.get("ignore_battle"); eInfo.hasteSpeed = nestedConf.getInt("haste_speed");
} catch (ClassCastException e) { } catch (ClassCastException e) {
logEntityInvalidValue("ignore_battle", name, "false"); logEntityInvalidValue("haste_speed", name, "80");
eInfo.ignoreBattle = false; eInfo.hasteSpeed = 80;
} catch (NullPointerException e) { } catch (NullPointerException e) {
logEntityMissingRequiredValue("ignore_battle", name, "false"); logEntityMissingOptionalValue("haste_speed", name, "80");
eInfo.ignoreBattle = false; eInfo.hasteSpeed = 80;
} }
try { try {
eInfo.category = nestedConf.get("category"); eInfo.slowSpeed = nestedConf.getInt("slow_speed");
} catch (ClassCastException e) { } catch (ClassCastException e) {
logEntityInvalidValue("category", name, "unknown"); logEntityInvalidValue("slow_speed", name, "20");
eInfo.category = "unknown"; eInfo.slowSpeed = 20;
} catch (NullPointerException e) { } catch (NullPointerException e) {
logEntityMissingRequiredValue("category", name, "unknown"); logEntityMissingOptionalValue("slow_speed", name, "20");
eInfo.category = "unknown"; eInfo.slowSpeed = 20;
} }
try { if (eInfo.playerName.isEmpty()) {
eInfo.decisionAttack = nestedConf.getInt("decision_attack_probability"); try {
if(eInfo.decisionAttack < 0) { eInfo.ignoreBattle = nestedConf.get("ignore_battle");
logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "0"); } catch (ClassCastException e) {
eInfo.decisionAttack = 0; logEntityInvalidValue("ignore_battle", name, "false");
} else if(eInfo.decisionAttack > 100) { eInfo.ignoreBattle = false;
logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "100"); } catch (NullPointerException e) {
eInfo.decisionAttack = 100; logEntityMissingRequiredValue("ignore_battle", name, "false");
eInfo.ignoreBattle = false;
} }
} catch (ClassCastException e) {
logEntityInvalidValue("decision_attack_probability", name, "70");
eInfo.decisionAttack = 70;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("decision_attack_probability", name, "70");
eInfo.decisionAttack = 70;
}
try { try {
eInfo.decisionDefend = nestedConf.getInt("decision_defend_probability"); eInfo.category = nestedConf.get("category");
if(eInfo.decisionDefend < 0) { } catch (ClassCastException e) {
logClampedValueEntity("decision_defend_probability", name, Integer.toString(eInfo.decisionDefend), "0"); logEntityInvalidValue("category", name, "unknown");
eInfo.decisionDefend = 0; eInfo.category = "unknown";
} else if(eInfo.decisionDefend > 100) { } catch (NullPointerException e) {
logClampedValueEntity("decision_defend_probability", name, Integer.toString(eInfo.decisionDefend), "100"); logEntityMissingRequiredValue("category", name, "unknown");
eInfo.decisionDefend = 100; eInfo.category = "unknown";
} }
} catch (ClassCastException e) {
logEntityInvalidValue("decision_defend_probability", name, "20");
eInfo.decisionDefend = 20;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("decision_defend_probability", name, "20");
eInfo.decisionDefend = 20;
}
try { try {
eInfo.decisionFlee = nestedConf.getInt("decision_flee_probability"); eInfo.decisionAttack = nestedConf.getInt("decision_attack_probability");
if(eInfo.decisionFlee < 0) { if (eInfo.decisionAttack < 0) {
logClampedValueEntity("decision_flee_probability", name, Integer.toString(eInfo.decisionFlee), "0"); logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "0");
eInfo.decisionFlee = 0; eInfo.decisionAttack = 0;
} else if(eInfo.decisionFlee > 100) { } else if (eInfo.decisionAttack > 100) {
logClampedValueEntity("decision_flee_probability", name, Integer.toString(eInfo.decisionFlee), "100"); logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "100");
eInfo.decisionFlee = 100; eInfo.decisionAttack = 100;
}
} catch (ClassCastException e) {
logEntityInvalidValue("decision_attack_probability", name, "70");
eInfo.decisionAttack = 70;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("decision_attack_probability", name, "70");
eInfo.decisionAttack = 70;
}
try {
eInfo.decisionDefend = nestedConf.getInt("decision_defend_probability");
if (eInfo.decisionDefend < 0) {
logClampedValueEntity("decision_defend_probability", name, Integer.toString(eInfo.decisionDefend), "0");
eInfo.decisionDefend = 0;
} else if (eInfo.decisionDefend > 100) {
logClampedValueEntity("decision_defend_probability", name, Integer.toString(eInfo.decisionDefend), "100");
eInfo.decisionDefend = 100;
}
} catch (ClassCastException e) {
logEntityInvalidValue("decision_defend_probability", name, "20");
eInfo.decisionDefend = 20;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("decision_defend_probability", name, "20");
eInfo.decisionDefend = 20;
}
try {
eInfo.decisionFlee = nestedConf.getInt("decision_flee_probability");
if (eInfo.decisionFlee < 0) {
logClampedValueEntity("decision_flee_probability", name, Integer.toString(eInfo.decisionFlee), "0");
eInfo.decisionFlee = 0;
} else if (eInfo.decisionFlee > 100) {
logClampedValueEntity("decision_flee_probability", name, Integer.toString(eInfo.decisionFlee), "100");
eInfo.decisionFlee = 100;
}
} catch (ClassCastException e) {
logEntityInvalidValue("decision_flee_probability", name, "10");
eInfo.decisionFlee = 10;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("decision_flee_probability", name, "10");
eInfo.decisionFlee = 10;
} }
} catch (ClassCastException e) {
logEntityInvalidValue("decision_flee_probability", name, "10");
eInfo.decisionFlee = 10;
} catch (NullPointerException e) {
logEntityMissingRequiredValue("decision_flee_probability", name, "10");
eInfo.decisionFlee = 10;
} }
if(eInfo.classType != null) { if(eInfo.classType != null) {
entityInfoMap.put(eInfo.classType.getName(), eInfo); entityInfoMap.put(eInfo.classType.getName(), eInfo);
} else if(!eInfo.customName.isEmpty()) { } else if(!eInfo.customName.isEmpty()) {
customEntityInfoMap.put(eInfo.customName, eInfo); customEntityInfoMap.put(eInfo.customName, eInfo);
} else if (!eInfo.playerName.isEmpty()) {
customPlayerInfoMap.put(eInfo.playerName, eInfo);
} else { } else {
logger.error("Cannot add entity to internal config, no \"name\" or \"custom_name\""); logger.error("Cannot add entity to internal config, no \"name\" or \"custom_name\" or \"player_name\"");
} }
} }
} }
@ -795,6 +833,8 @@ public class Config
newConf.set("defense_damage_probability", eInfo.defenseDamageProbability); newConf.set("defense_damage_probability", eInfo.defenseDamageProbability);
newConf.set("evasion", eInfo.evasion); newConf.set("evasion", eInfo.evasion);
newConf.set("speed", eInfo.speed); newConf.set("speed", eInfo.speed);
newConf.set("haste_speed", eInfo.hasteSpeed);
newConf.set("slow_speed", eInfo.slowSpeed);
newConf.set("ignore_battle", eInfo.ignoreBattle); newConf.set("ignore_battle", eInfo.ignoreBattle);
newConf.set("category", eInfo.category); newConf.set("category", eInfo.category);
newConf.set("decision_attack_probability", eInfo.decisionAttack); newConf.set("decision_attack_probability", eInfo.decisionAttack);
@ -824,9 +864,11 @@ public class Config
boolean saved = false; boolean saved = false;
try { try {
if (eInfo.classType != null || !eInfo.customName.isEmpty()) { if (eInfo.classType != null || !eInfo.customName.isEmpty() || !eInfo.playerName.isEmpty()) {
for (com.electronwill.nightconfig.core.Config entity : entities) { for (com.electronwill.nightconfig.core.Config entity : entities) {
String entityName = entity.get("name"); String entityName = entity.get("name");
String customName = entity.get("custom_name");
String playerName = entity.get("player_name");
if ((eInfo.classType != null && entityName != null && entityName.equals(eInfo.classType.getName()))) { if ((eInfo.classType != null && entityName != null && entityName.equals(eInfo.classType.getName()))) {
entity.set("attack_power", eInfo.attackPower); entity.set("attack_power", eInfo.attackPower);
entity.set("attack_probability", eInfo.attackProbability); entity.set("attack_probability", eInfo.attackProbability);
@ -837,6 +879,8 @@ public class Config
entity.set("defense_damage_probability", eInfo.defenseDamageProbability); entity.set("defense_damage_probability", eInfo.defenseDamageProbability);
entity.set("evasion", eInfo.evasion); entity.set("evasion", eInfo.evasion);
entity.set("speed", eInfo.speed); entity.set("speed", eInfo.speed);
entity.set("haste_speed", eInfo.hasteSpeed);
entity.set("slow_speed", eInfo.slowSpeed);
entity.set("ignore_battle", eInfo.ignoreBattle); entity.set("ignore_battle", eInfo.ignoreBattle);
entity.set("category", eInfo.category); entity.set("category", eInfo.category);
entity.set("decision_attack_probability", eInfo.decisionAttack); entity.set("decision_attack_probability", eInfo.decisionAttack);
@ -844,26 +888,33 @@ public class Config
entity.set("decision_flee_probability", eInfo.decisionFlee); entity.set("decision_flee_probability", eInfo.decisionFlee);
saved = true; saved = true;
break; break;
} else { } else if (!eInfo.customName.isEmpty() && customName != null && customName.equals(eInfo.customName)) {
String customName = entity.get("custom_name"); entity.set("attack_power", eInfo.attackPower);
if(!eInfo.customName.isEmpty() && customName != null && customName.equals(eInfo.customName)) { entity.set("attack_probability", eInfo.attackProbability);
entity.set("attack_power", eInfo.attackPower); entity.set("attack_variance", eInfo.attackVariance);
entity.set("attack_probability", eInfo.attackProbability); entity.set("attack_effect", eInfo.attackEffect.toString());
entity.set("attack_variance", eInfo.attackVariance); entity.set("attack_effect_probability", eInfo.attackEffectProbability);
entity.set("attack_effect", eInfo.attackEffect.toString()); entity.set("defense_damage", eInfo.defenseDamage);
entity.set("attack_effect_probability", eInfo.attackEffectProbability); entity.set("defense_damage_probability", eInfo.defenseDamageProbability);
entity.set("defense_damage", eInfo.defenseDamage); entity.set("evasion", eInfo.evasion);
entity.set("defense_damage_probability", eInfo.defenseDamageProbability); entity.set("speed", eInfo.speed);
entity.set("evasion", eInfo.evasion); entity.set("haste_speed", eInfo.hasteSpeed);
entity.set("speed", eInfo.speed); entity.set("slow_speed", eInfo.slowSpeed);
entity.set("ignore_battle", eInfo.ignoreBattle); entity.set("ignore_battle", eInfo.ignoreBattle);
entity.set("category", eInfo.category); entity.set("category", eInfo.category);
entity.set("decision_attack_probability", eInfo.decisionAttack); entity.set("decision_attack_probability", eInfo.decisionAttack);
entity.set("decision_defend_probability", eInfo.decisionDefend); entity.set("decision_defend_probability", eInfo.decisionDefend);
entity.set("decision_flee_probability", eInfo.decisionFlee); entity.set("decision_flee_probability", eInfo.decisionFlee);
saved = true; saved = true;
break; break;
} } else if (!eInfo.playerName.isEmpty() && playerName != null && playerName.equals(eInfo.playerName)) {
entity.set("attack_probability", eInfo.attackProbability);
entity.set("evasion", eInfo.evasion);
entity.set("speed", eInfo.speed);
entity.set("haste_speed", eInfo.hasteSpeed);
entity.set("slow_speed", eInfo.slowSpeed);
saved = true;
break;
} }
} }
if(!saved) { if(!saved) {
@ -872,25 +923,36 @@ public class Config
newEntry.set("name", eInfo.classType.getName()); newEntry.set("name", eInfo.classType.getName());
} else if(!eInfo.customName.isEmpty()) { } else if(!eInfo.customName.isEmpty()) {
newEntry.set("custom_name", eInfo.customName); newEntry.set("custom_name", eInfo.customName);
} else if (!eInfo.playerName.isEmpty()) {
newEntry.set("player_name", eInfo.playerName);
} else { } else {
logger.error("Failed to save new entity entry into config, no name or custom_name"); logger.error("Failed to save new entity entry into config, no name or custom_name");
conf.close(); conf.close();
return false; return false;
} }
newEntry.set("attack_power", eInfo.attackPower);
if (eInfo.playerName.isEmpty()) {
newEntry.set("attack_power", eInfo.attackPower);
}
newEntry.set("attack_probability", eInfo.attackProbability); newEntry.set("attack_probability", eInfo.attackProbability);
newEntry.set("attack_variance", eInfo.attackVariance); if (eInfo.playerName.isEmpty()) {
newEntry.set("attack_effect", eInfo.attackEffect.toString()); newEntry.set("attack_variance", eInfo.attackVariance);
newEntry.set("attack_effect_probability", eInfo.attackEffectProbability); newEntry.set("attack_effect", eInfo.attackEffect.toString());
newEntry.set("defense_damage", eInfo.defenseDamage); newEntry.set("attack_effect_probability", eInfo.attackEffectProbability);
newEntry.set("defense_damage_probability", eInfo.defenseDamageProbability); newEntry.set("defense_damage", eInfo.defenseDamage);
newEntry.set("defense_damage_probability", eInfo.defenseDamageProbability);
}
newEntry.set("evasion", eInfo.evasion); newEntry.set("evasion", eInfo.evasion);
newEntry.set("speed", eInfo.speed); newEntry.set("speed", eInfo.speed);
newEntry.set("ignore_battle", eInfo.ignoreBattle); newEntry.set("haste_speed", eInfo.hasteSpeed);
newEntry.set("category", eInfo.category); newEntry.set("slow_speed", eInfo.slowSpeed);
newEntry.set("decision_attack_probability", eInfo.decisionAttack); if (eInfo.playerName.isEmpty()) {
newEntry.set("decision_defend_probability", eInfo.decisionDefend); newEntry.set("ignore_battle", eInfo.ignoreBattle);
newEntry.set("decision_flee_probability", eInfo.decisionFlee); newEntry.set("category", eInfo.category);
newEntry.set("decision_attack_probability", eInfo.decisionAttack);
newEntry.set("decision_defend_probability", eInfo.decisionDefend);
newEntry.set("decision_flee_probability", eInfo.decisionFlee);
}
entities.add(newEntry); entities.add(newEntry);
saved = true; saved = true;
} }
@ -915,8 +977,10 @@ public class Config
if(eInfo.classType != null) { if(eInfo.classType != null) {
entityInfoMap.put(eInfo.classType.getName(), eInfo); entityInfoMap.put(eInfo.classType.getName(), eInfo);
} else if(!eInfo.customName.isEmpty()){ } else if(!eInfo.customName.isEmpty()) {
customEntityInfoMap.put(eInfo.customName, eInfo); customEntityInfoMap.put(eInfo.customName, eInfo);
} else if (!eInfo.playerName.isEmpty()) {
customPlayerInfoMap.put(eInfo.playerName, eInfo);
} else { } else {
logger.warn("Failed to update entity info in memory"); logger.warn("Failed to update entity info in memory");
} }
@ -1096,6 +1160,22 @@ public class Config
return eInfo; return eInfo;
} }
/**
* Returns a clone of an EntityInfo (to prevent editing it).
* @param playerName
* @return a clone of the stored custom EntityInfo or null if invalid String
*/
public EntityInfo getPlayerInfo(String playerName) {
if (playerName == null) {
return null;
}
EntityInfo eInfo = customPlayerInfoMap.get(playerName);
if (eInfo != null) {
eInfo = eInfo.clone();
}
return eInfo;
}
protected EntityInfo getCustomEntityInfoReference(String customName) protected EntityInfo getCustomEntityInfoReference(String customName)
{ {
if(customName == null) { if(customName == null) {
@ -1104,6 +1184,13 @@ public class Config
return customEntityInfoMap.get(customName); return customEntityInfoMap.get(customName);
} }
protected EntityInfo getPlayerInfoReference(String playerName) {
if (playerName == null) {
return null;
}
return customPlayerInfoMap.get(playerName);
}
private int getConfigFileVersion(File configFile) private int getConfigFileVersion(File configFile)
{ {
int version = 0; int version = 0;

View file

@ -8,6 +8,7 @@ public class EditingInfo
public EntityInfo entityInfo; public EntityInfo entityInfo;
public boolean isPendingEntitySelection; public boolean isPendingEntitySelection;
public boolean isEditingCustomName; public boolean isEditingCustomName;
public boolean isEditingPlayer;
public EditingInfo() public EditingInfo()
{ {
@ -15,6 +16,7 @@ public class EditingInfo
entityInfo = null; entityInfo = null;
isPendingEntitySelection = true; isPendingEntitySelection = true;
isEditingCustomName = false; isEditingCustomName = false;
isEditingPlayer = false;
} }
public EditingInfo(Player player) public EditingInfo(Player player)
@ -23,5 +25,6 @@ public class EditingInfo
entityInfo = null; entityInfo = null;
isPendingEntitySelection = true; isPendingEntitySelection = true;
isEditingCustomName = false; isEditingCustomName = false;
isEditingPlayer = false;
} }
} }

View file

@ -20,12 +20,15 @@ public class EntityInfo
public int defenseDamageProbability; public int defenseDamageProbability;
public int evasion; public int evasion;
public int speed; public int speed;
public int hasteSpeed;
public int slowSpeed;
public String category; public String category;
public int decisionAttack; public int decisionAttack;
public int decisionDefend; public int decisionDefend;
public int decisionFlee; public int decisionFlee;
public String customName; public String customName;
public String playerName;
public enum Effect public enum Effect
{ {
SPEED, SPEED,
@ -369,17 +372,20 @@ public class EntityInfo
defenseDamageProbability = 0; defenseDamageProbability = 0;
evasion = 15; evasion = 15;
speed = 50; speed = 50;
hasteSpeed = 80;
slowSpeed = 20;
category = "unknown"; category = "unknown";
decisionAttack = 70; decisionAttack = 70;
decisionDefend = 20; decisionDefend = 20;
decisionFlee = 10; decisionFlee = 10;
customName = new String(); customName = new String();
playerName = new String();
} }
public EntityInfo(Class classType, boolean ignoreBattle, int attackPower, int attackProbability, int attackVariance, public EntityInfo(Class classType, boolean ignoreBattle, int attackPower, int attackProbability, int attackVariance,
Effect attackEffect, int attackEffectProbability, int defenseDamage, int defenseDamageProbability, Effect attackEffect, int attackEffectProbability, int defenseDamage, int defenseDamageProbability,
int evasion, int speed, String category, int decisionAttack, int decisionDefend, int decisionFlee, int evasion, int speed, int hasteSpeed, int slowSpeed, String category, int decisionAttack, int decisionDefend, int decisionFlee,
String customName) { String customName, String playerName) {
this.classType = classType; this.classType = classType;
this.ignoreBattle = ignoreBattle; this.ignoreBattle = ignoreBattle;
this.attackPower = attackPower; this.attackPower = attackPower;
@ -391,11 +397,14 @@ public class EntityInfo
this.defenseDamageProbability = defenseDamageProbability; this.defenseDamageProbability = defenseDamageProbability;
this.evasion = evasion; this.evasion = evasion;
this.speed = speed; this.speed = speed;
this.hasteSpeed = hasteSpeed;
this.slowSpeed = slowSpeed;
this.category = category; this.category = category;
this.decisionAttack = decisionAttack; this.decisionAttack = decisionAttack;
this.decisionDefend = decisionDefend; this.decisionDefend = decisionDefend;
this.decisionFlee = decisionFlee; this.decisionFlee = decisionFlee;
this.customName = customName; this.customName = customName;
this.playerName = playerName;
} }
public EntityInfo clone() public EntityInfo clone()
@ -412,11 +421,14 @@ public class EntityInfo
newEntityInfo.defenseDamageProbability = defenseDamageProbability; newEntityInfo.defenseDamageProbability = defenseDamageProbability;
newEntityInfo.evasion = evasion; newEntityInfo.evasion = evasion;
newEntityInfo.speed = speed; newEntityInfo.speed = speed;
newEntityInfo.hasteSpeed = hasteSpeed;
newEntityInfo.slowSpeed = slowSpeed;
newEntityInfo.category = category; newEntityInfo.category = category;
newEntityInfo.decisionAttack = decisionAttack; newEntityInfo.decisionAttack = decisionAttack;
newEntityInfo.decisionDefend = decisionDefend; newEntityInfo.decisionDefend = decisionDefend;
newEntityInfo.decisionFlee = decisionFlee; newEntityInfo.decisionFlee = decisionFlee;
newEntityInfo.customName = new String(customName); newEntityInfo.customName = customName;
newEntityInfo.playerName = playerName;
return newEntityInfo; return newEntityInfo;
} }
@ -448,6 +460,8 @@ public class EntityInfo
defenseDamageProbability = buffer.readInt(); defenseDamageProbability = buffer.readInt();
evasion = buffer.readInt(); evasion = buffer.readInt();
speed = buffer.readInt(); speed = buffer.readInt();
hasteSpeed = buffer.readInt();
slowSpeed = buffer.readInt();
int category_len = buffer.readInt(); int category_len = buffer.readInt();
ByteBuf category_bytes = buffer.readBytes(category_len); ByteBuf category_bytes = buffer.readBytes(category_len);
@ -464,6 +478,14 @@ public class EntityInfo
} else { } else {
customName = ""; customName = "";
} }
int player_len = buffer.readInt();
if (player_len > 0) {
ByteBuf player_bytes = buffer.readBytes(player_len);
playerName = player_bytes.toString(StandardCharsets.UTF_8);
} else {
playerName = "";
}
} }
public void encode(ByteBuf buffer) { public void encode(ByteBuf buffer) {
@ -491,6 +513,8 @@ public class EntityInfo
buffer.writeInt(defenseDamageProbability); buffer.writeInt(defenseDamageProbability);
buffer.writeInt(evasion); buffer.writeInt(evasion);
buffer.writeInt(speed); buffer.writeInt(speed);
buffer.writeInt(hasteSpeed);
buffer.writeInt(slowSpeed);
byte[] category_bytes = category.getBytes(StandardCharsets.UTF_8); byte[] category_bytes = category.getBytes(StandardCharsets.UTF_8);
buffer.writeInt(category_bytes.length); buffer.writeInt(category_bytes.length);
@ -507,5 +531,13 @@ public class EntityInfo
buffer.writeInt(custom_bytes.length); buffer.writeInt(custom_bytes.length);
buffer.writeBytes(custom_bytes); buffer.writeBytes(custom_bytes);
} }
if (playerName.isEmpty()) {
buffer.writeInt(0);
} else {
byte[] player_bytes = playerName.getBytes(StandardCharsets.UTF_8);
buffer.writeInt(player_bytes.length);
buffer.writeBytes(player_bytes);
}
} }
} }

View file

@ -48,11 +48,14 @@ public class PacketEditingMessage implements CustomPacketPayload
EDIT_DEFENSE_DAMAGE_PROBABILITY(9), EDIT_DEFENSE_DAMAGE_PROBABILITY(9),
EDIT_EVASION(10), EDIT_EVASION(10),
EDIT_SPEED(11), EDIT_SPEED(11),
EDIT_HASTE_SPEED(18),
EDIT_SLOW_SPEED(19),
EDIT_CATEGORY(12), EDIT_CATEGORY(12),
EDIT_DECISION_ATTACK(13), EDIT_DECISION_ATTACK(13),
EDIT_DECISION_DEFEND(14), EDIT_DECISION_DEFEND(14),
EDIT_DECISION_FLEE(15), EDIT_DECISION_FLEE(15),
SERVER_EDIT(16); SERVER_EDIT(16),
PICK_PLAYER(17);
Type(int value) Type(int value)
{ {