]> git.seodisparate.com - TurnBasedMinecraftMod/commitdiff
1/2 Player-specific TBMM battle config
authorStephen Seo <seo.disparate@gmail.com>
Thu, 31 Oct 2024 05:34:40 +0000 (14:34 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Fri, 1 Nov 2024 04:15:24 +0000 (13:15 +0900)
Add support for custom stats per-player by player username.

src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Battle.java
src/main/java/com/burnedkirby/TurnBasedMinecraft/common/Config.java
src/main/java/com/burnedkirby/TurnBasedMinecraft/common/EditingInfo.java
src/main/java/com/burnedkirby/TurnBasedMinecraft/common/EntityInfo.java
src/main/java/com/burnedkirby/TurnBasedMinecraft/common/networking/PacketEditingMessage.java

index b7dff97abdbcb86256e3fb13811eade08d8d62d6..7044e05da2ebdd1c36a20589b867f1637af4114f 100644 (file)
@@ -134,6 +134,9 @@ public class Battle {
                 } catch (NullPointerException exception) {
                     entityInfo = null;
                 }
+                if (entityInfo == null) {
+                    entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
+                }
                 if (entityInfo == null) {
                     entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
                 }
@@ -166,6 +169,9 @@ public class Battle {
                 } catch (NullPointerException exception) {
                     entityInfo = null;
                 }
+                if (entityInfo == null) {
+                    entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
+                }
                 if (entityInfo == null) {
                     entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
                 }
@@ -268,6 +274,9 @@ public class Battle {
         } catch (NullPointerException exception) {
             entityInfo = null;
         }
+        if (entityInfo == null) {
+            entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
+        }
         if (entityInfo == null) {
             entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
         }
@@ -316,6 +325,9 @@ public class Battle {
         } catch (NullPointerException exception) {
             entityInfo = null;
         }
+        if (entityInfo == null) {
+            entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getPlayerInfo(e.getName().getString());
+        }
         if (entityInfo == null) {
             entityInfo = TurnBasedMinecraftMod.proxy.getConfig().getMatchingEntityInfo(e);
         }
@@ -781,7 +793,7 @@ public class Battle {
                         case ATTACK:
                             debugLog += " attack";
                             Combatant target = null;
-                            if (next.entity instanceof Player) {
+                            if (next.entity instanceof Player player) {
                                 debugLog += " as player";
                                 target = sideA.get(next.targetEntityID);
                                 if (target == null) {
@@ -790,15 +802,15 @@ public class Battle {
                                 if (target == null || !target.entity.isAlive() || target == next) {
                                     continue;
                                 }
-                                ItemStack heldItemStack = ((Player) next.entity).getMainHandItem();
+                                ItemStack heldItemStack = player.getMainHandItem();
                                 if (heldItemStack.getItem() instanceof BowItem) {
                                     debugLog += " with bow";
-                                    if (Utility.doesPlayerHaveArrows((Player) next.entity)) {
+                                    if (Utility.doesPlayerHaveArrows(player)) {
                                         final Entity nextEntity = next.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 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()) {
                                             next.yaw = yawDirection;
                                             next.pitch = pitchDirection;
@@ -815,7 +827,7 @@ public class Battle {
                                     continue;
                                 } else if (heldItemStack.getItem() instanceof CrossbowItem) {
                                     debugLog += " with crossbow";
-                                    if (Utility.doesPlayerHaveArrows((Player) next.entity)) {
+                                    if (Utility.doesPlayerHaveArrows(player)) {
                                         final Entity nextEntity = next.entity;
                                         final Entity targetEntity = target.entity;
                                         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;
                                 }
                                 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) {
-                                    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 {
                                     hitChance = hitChance * (100 - target.entityInfo.evasion) / 100;
                                 }
@@ -1020,48 +1041,111 @@ public class Battle {
                             int fastestEnemySpeed = 0;
                             if (next.isSideA) {
                                 for (Combatant c : sideB.values()) {
-                                    if (c.entity instanceof Player) {
-                                        int playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
-                                        if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SPEED)) {
-                                            playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed();
-                                        } else if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
-                                            playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed();
+                                    if (c.entity instanceof Player player) {
+                                        int playerSpeed;
+                                        if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
+                                            playerSpeed = c.entityInfo.speed;
+                                        } else {
+                                            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) {
                                             fastestEnemySpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
                                         }
                                     } 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;
                                         }
                                     }
                                 }
                             } else {
                                 for (Combatant c : sideA.values()) {
-                                    if (c.entity instanceof Player) {
-                                        int playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
-                                        if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SPEED)) {
-                                            playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed();
-                                        } else if (((Player) c.entity).hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
-                                            playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed();
+                                    if (c.entity instanceof Player player) {
+                                        int playerSpeed;
+                                        if (c.entityInfo != null && !c.entityInfo.playerName.isEmpty()) {
+                                            playerSpeed = c.entityInfo.speed;
+                                        } else {
+                                            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) {
                                             fastestEnemySpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
                                         }
                                     } 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;
                                         }
                                     }
                                 }
                             }
                             int fleeProbability = 0;
-                            if (next.entity instanceof Player) {
-                                int playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSpeed();
-                                if (((Player) next.entity).hasEffect(MobEffects.MOVEMENT_SPEED)) {
-                                    playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerHasteSpeed();
-                                } else if (((Player) next.entity).hasEffect(MobEffects.MOVEMENT_SLOWDOWN)) {
-                                    playerSpeed = TurnBasedMinecraftMod.proxy.getConfig().getPlayerSlowSpeed();
+                            if (next.entity instanceof Player player) {
+                                int playerSpeed;
+                                if (next.entityInfo != null && !next.entityInfo.playerName.isEmpty()) {
+                                    playerSpeed = next.entityInfo.speed;
+                                } else {
+                                    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) {
                                     fleeProbability = TurnBasedMinecraftMod.proxy.getConfig().getFleeBadProbability();
index 20006167a540e3e9583ad813149d98c220cedade..a9a5db90a56c87ce4d7839ef357cf3b40297756e 100644 (file)
@@ -24,6 +24,7 @@ public class Config
     private boolean battleDecisionDurationForever = false;
     private Map<String, EntityInfo> entityInfoMap;
     private Map<String, EntityInfo> customEntityInfoMap;
+    private Map<String, EntityInfo> customPlayerInfoMap;
     private Set<String> ignoreBattleTypes;
     private Logger logger;
     private int playerSpeed = 50;
@@ -57,6 +58,7 @@ public class Config
     {
         entityInfoMap = new HashMap<String, EntityInfo>();
         customEntityInfoMap = new HashMap<String, EntityInfo>();
+        customPlayerInfoMap = new HashMap<String, EntityInfo>();
         ignoreBattleTypes = new HashSet<String>();
         this.logger = logger;
         battleIgnoringPlayers = new HashSet<Integer>();
@@ -517,23 +519,33 @@ public class Config
                         logger.error("Entity with invalid custom_name (must be a string), skipping...");
                         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 {
-                    logger.error("Entity must have \"name\" or \"custom_name\" entry");
+                    logger.error("Entity must have \"name\" or \"custom_name\" or \"player_name\" entry");
                     continue;
                 }
 
-                try {
-                    eInfo.attackPower = nestedConf.getInt("attack_power");
-                    if(eInfo.attackPower < 0) {
-                        logClampedValueEntity("attack_power", name, Integer.toString(eInfo.attackPower), "0");
-                        eInfo.attackPower = 0;
+                if (eInfo.playerName.isEmpty()) {
+                    try {
+                        eInfo.attackPower = nestedConf.getInt("attack_power");
+                        if (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 {
@@ -553,77 +565,79 @@ public class Config
                     eInfo.attackProbability = 30;
                 }
 
-                try {
-                    eInfo.attackEffect = EntityInfo.Effect.fromString(nestedConf.get("attack_effect"));
-                    if(eInfo.attackEffect != EntityInfo.Effect.UNKNOWN) {
-                        try {
-                            eInfo.attackEffectProbability = nestedConf.getInt("attack_effect_probability");
-                            if(eInfo.attackEffectProbability < 0) {
-                                logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "1");
-                                eInfo.attackEffectProbability = 1;
-                            } else if(eInfo.attackEffectProbability > 100) {
-                                logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "100");
-                                eInfo.attackEffectProbability = 100;
+                if (eInfo.playerName.isEmpty()) {
+                    try {
+                        eInfo.attackEffect = EntityInfo.Effect.fromString(nestedConf.get("attack_effect"));
+                        if(eInfo.attackEffect != EntityInfo.Effect.UNKNOWN) {
+                            try {
+                                eInfo.attackEffectProbability = nestedConf.getInt("attack_effect_probability");
+                                if(eInfo.attackEffectProbability < 0) {
+                                    logClampedValueEntity("attack_effect_probability", name, Integer.toString(eInfo.attackEffectProbability), "1");
+                                    eInfo.attackEffectProbability = 1;
+                                } else if(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 {
-                    eInfo.attackVariance = nestedConf.getInt("attack_variance");
-                    if(eInfo.attackVariance < 0) {
-                        logClampedValueEntity("attack_variance", name, Integer.toString(eInfo.attackVariance), "0");
+                    try {
+                        eInfo.attackVariance = nestedConf.getInt("attack_variance");
+                        if (eInfo.attackVariance < 0) {
+                            logClampedValueEntity("attack_variance", name, Integer.toString(eInfo.attackVariance), "0");
+                            eInfo.attackVariance = 0;
+                        }
+                    } catch (ClassCastException e) {
+                        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 {
-                    eInfo.defenseDamage = nestedConf.getInt("defense_damage");
-                    if(eInfo.defenseDamage < 0) {
-                        logClampedValueEntity("defense_damage", name, Integer.toString(eInfo.defenseDamage), "0");
-                        eInfo.defenseDamage = 0;
-                    } else if(eInfo.defenseDamage != 0) {
-                        try {
-                            eInfo.defenseDamageProbability = nestedConf.getInt("defense_damage_probability");
-                            if(eInfo.defenseDamageProbability < 1) {
-                                logClampedValueEntity("defense_damage_probability", name, Integer.toString(eInfo.defenseDamageProbability), "1");
-                                eInfo.defenseDamageProbability = 1;
-                            } else if(eInfo.defenseDamageProbability > 100) {
-                                logClampedValueEntity("defense_damage_probability", name, Integer.toString(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) {
+                    try {
+                        eInfo.defenseDamage = nestedConf.getInt("defense_damage");
+                        if (eInfo.defenseDamage < 0) {
+                            logClampedValueEntity("defense_damage", name, Integer.toString(eInfo.defenseDamage), "0");
                             eInfo.defenseDamage = 0;
-                            logger.warn("Entity \"" + name + "\" has specified defense_damage but defense_damage_probability is missing, disabling defense_damage");
+                        } else if (eInfo.defenseDamage != 0) {
+                            try {
+                                eInfo.defenseDamageProbability = nestedConf.getInt("defense_damage_probability");
+                                if (eInfo.defenseDamageProbability < 1) {
+                                    logClampedValueEntity("defense_damage_probability", name, Integer.toString(eInfo.defenseDamageProbability), "1");
+                                    eInfo.defenseDamageProbability = 1;
+                                } else if (eInfo.defenseDamageProbability > 100) {
+                                    logClampedValueEntity("defense_damage_probability", name, Integer.toString(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;
+                        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 {
@@ -654,82 +668,106 @@ public class Config
                 }
 
                 try {
-                    eInfo.ignoreBattle = nestedConf.get("ignore_battle");
+                    eInfo.hasteSpeed = nestedConf.getInt("haste_speed");
                 } catch (ClassCastException e) {
-                    logEntityInvalidValue("ignore_battle", name, "false");
-                    eInfo.ignoreBattle = false;
+                    logEntityInvalidValue("haste_speed", name, "80");
+                    eInfo.hasteSpeed = 80;
                 } catch (NullPointerException e) {
-                    logEntityMissingRequiredValue("ignore_battle", name, "false");
-                    eInfo.ignoreBattle = false;
+                    logEntityMissingOptionalValue("haste_speed", name, "80");
+                    eInfo.hasteSpeed = 80;
                 }
 
                 try {
-                    eInfo.category = nestedConf.get("category");
+                    eInfo.slowSpeed = nestedConf.getInt("slow_speed");
                 } catch (ClassCastException e) {
-                    logEntityInvalidValue("category", name, "unknown");
-                    eInfo.category = "unknown";
+                    logEntityInvalidValue("slow_speed", name, "20");
+                    eInfo.slowSpeed = 20;
                 } catch (NullPointerException e) {
-                    logEntityMissingRequiredValue("category", name, "unknown");
-                    eInfo.category = "unknown";
+                    logEntityMissingOptionalValue("slow_speed", name, "20");
+                    eInfo.slowSpeed = 20;
                 }
 
-                try {
-                    eInfo.decisionAttack = nestedConf.getInt("decision_attack_probability");
-                    if(eInfo.decisionAttack < 0) {
-                        logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "0");
-                        eInfo.decisionAttack = 0;
-                    } else if(eInfo.decisionAttack > 100) {
-                        logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "100");
-                        eInfo.decisionAttack = 100;
+                if (eInfo.playerName.isEmpty()) {
+                    try {
+                        eInfo.ignoreBattle = nestedConf.get("ignore_battle");
+                    } catch (ClassCastException e) {
+                        logEntityInvalidValue("ignore_battle", name, "false");
+                        eInfo.ignoreBattle = false;
+                    } catch (NullPointerException e) {
+                        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 {
-                    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;
+                    try {
+                        eInfo.category = nestedConf.get("category");
+                    } catch (ClassCastException e) {
+                        logEntityInvalidValue("category", name, "unknown");
+                        eInfo.category = "unknown";
+                    } catch (NullPointerException e) {
+                        logEntityMissingRequiredValue("category", name, "unknown");
+                        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 {
-                    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;
+                    try {
+                        eInfo.decisionAttack = nestedConf.getInt("decision_attack_probability");
+                        if (eInfo.decisionAttack < 0) {
+                            logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "0");
+                            eInfo.decisionAttack = 0;
+                        } else if (eInfo.decisionAttack > 100) {
+                            logClampedValueEntity("decision_attack_probability", name, Integer.toString(eInfo.decisionAttack), "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) {
                     entityInfoMap.put(eInfo.classType.getName(), eInfo);
                 } else if(!eInfo.customName.isEmpty()) {
                     customEntityInfoMap.put(eInfo.customName, eInfo);
+                } else if (!eInfo.playerName.isEmpty()) {
+                    customPlayerInfoMap.put(eInfo.playerName, eInfo);
                 } 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("evasion", eInfo.evasion);
         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("category", eInfo.category);
         newConf.set("decision_attack_probability", eInfo.decisionAttack);
@@ -824,9 +864,11 @@ public class Config
 
         boolean saved = false;
         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) {
                     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()))) {
                         entity.set("attack_power", eInfo.attackPower);
                         entity.set("attack_probability", eInfo.attackProbability);
@@ -837,6 +879,8 @@ public class Config
                         entity.set("defense_damage_probability", eInfo.defenseDamageProbability);
                         entity.set("evasion", eInfo.evasion);
                         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("category", eInfo.category);
                         entity.set("decision_attack_probability", eInfo.decisionAttack);
@@ -844,26 +888,33 @@ public class Config
                         entity.set("decision_flee_probability", eInfo.decisionFlee);
                         saved = true;
                         break;
-                    } else {
-                        String customName = entity.get("custom_name");
-                        if(!eInfo.customName.isEmpty() && customName != null && customName.equals(eInfo.customName)) {
-                            entity.set("attack_power", eInfo.attackPower);
-                            entity.set("attack_probability", eInfo.attackProbability);
-                            entity.set("attack_variance", eInfo.attackVariance);
-                            entity.set("attack_effect", eInfo.attackEffect.toString());
-                            entity.set("attack_effect_probability", eInfo.attackEffectProbability);
-                            entity.set("defense_damage", eInfo.defenseDamage);
-                            entity.set("defense_damage_probability", eInfo.defenseDamageProbability);
-                            entity.set("evasion", eInfo.evasion);
-                            entity.set("speed", eInfo.speed);
-                            entity.set("ignore_battle", eInfo.ignoreBattle);
-                            entity.set("category", eInfo.category);
-                            entity.set("decision_attack_probability", eInfo.decisionAttack);
-                            entity.set("decision_defend_probability", eInfo.decisionDefend);
-                            entity.set("decision_flee_probability", eInfo.decisionFlee);
-                            saved = true;
-                            break;
-                        }
+                    } else if (!eInfo.customName.isEmpty() && customName != null && customName.equals(eInfo.customName)) {
+                        entity.set("attack_power", eInfo.attackPower);
+                        entity.set("attack_probability", eInfo.attackProbability);
+                        entity.set("attack_variance", eInfo.attackVariance);
+                        entity.set("attack_effect", eInfo.attackEffect.toString());
+                        entity.set("attack_effect_probability", eInfo.attackEffectProbability);
+                        entity.set("defense_damage", eInfo.defenseDamage);
+                        entity.set("defense_damage_probability", eInfo.defenseDamageProbability);
+                        entity.set("evasion", eInfo.evasion);
+                        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("category", eInfo.category);
+                        entity.set("decision_attack_probability", eInfo.decisionAttack);
+                        entity.set("decision_defend_probability", eInfo.decisionDefend);
+                        entity.set("decision_flee_probability", eInfo.decisionFlee);
+                        saved = true;
+                        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) {
@@ -872,25 +923,36 @@ public class Config
                         newEntry.set("name", eInfo.classType.getName());
                     } else if(!eInfo.customName.isEmpty()) {
                         newEntry.set("custom_name", eInfo.customName);
+                    } else if (!eInfo.playerName.isEmpty()) {
+                        newEntry.set("player_name", eInfo.playerName);
                     } else {
                         logger.error("Failed to save new entity entry into config, no name or custom_name");
                         conf.close();
                         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_variance", eInfo.attackVariance);
-                    newEntry.set("attack_effect", eInfo.attackEffect.toString());
-                    newEntry.set("attack_effect_probability", eInfo.attackEffectProbability);
-                    newEntry.set("defense_damage", eInfo.defenseDamage);
-                    newEntry.set("defense_damage_probability", eInfo.defenseDamageProbability);
+                    if (eInfo.playerName.isEmpty()) {
+                        newEntry.set("attack_variance", eInfo.attackVariance);
+                        newEntry.set("attack_effect", eInfo.attackEffect.toString());
+                        newEntry.set("attack_effect_probability", eInfo.attackEffectProbability);
+                        newEntry.set("defense_damage", eInfo.defenseDamage);
+                        newEntry.set("defense_damage_probability", eInfo.defenseDamageProbability);
+                    }
                     newEntry.set("evasion", eInfo.evasion);
                     newEntry.set("speed", eInfo.speed);
-                    newEntry.set("ignore_battle", eInfo.ignoreBattle);
-                    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);
+                    newEntry.set("haste_speed", eInfo.hasteSpeed);
+                    newEntry.set("slow_speed", eInfo.slowSpeed);
+                    if (eInfo.playerName.isEmpty()) {
+                        newEntry.set("ignore_battle", eInfo.ignoreBattle);
+                        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);
                     saved = true;
                 }
@@ -915,8 +977,10 @@ public class Config
 
         if(eInfo.classType != null) {
             entityInfoMap.put(eInfo.classType.getName(), eInfo);
-        } else if(!eInfo.customName.isEmpty()){
+        } else if(!eInfo.customName.isEmpty()) {
             customEntityInfoMap.put(eInfo.customName, eInfo);
+        } else if (!eInfo.playerName.isEmpty()) {
+            customPlayerInfoMap.put(eInfo.playerName, eInfo);
         } else {
             logger.warn("Failed to update entity info in memory");
         }
@@ -1096,6 +1160,22 @@ public class Config
         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)
     {
         if(customName == null) {
@@ -1104,6 +1184,13 @@ public class Config
         return customEntityInfoMap.get(customName);
     }
 
+    protected EntityInfo getPlayerInfoReference(String playerName) {
+        if (playerName == null) {
+            return null;
+        }
+        return customPlayerInfoMap.get(playerName);
+    }
+
     private int getConfigFileVersion(File configFile)
     {
         int version = 0;
index d2d2609f33912c2e2c0d7a54c9fb79f3c8c1bb93..176422ac188c7ccfc27f358a345cfb339821058e 100644 (file)
@@ -8,6 +8,7 @@ public class EditingInfo
     public EntityInfo entityInfo;
     public boolean isPendingEntitySelection;
     public boolean isEditingCustomName;
+    public boolean isEditingPlayer;
 
     public EditingInfo()
     {
@@ -15,6 +16,7 @@ public class EditingInfo
         entityInfo = null;
         isPendingEntitySelection = true;
         isEditingCustomName = false;
+        isEditingPlayer = false;
     }
 
     public EditingInfo(Player player)
@@ -23,5 +25,6 @@ public class EditingInfo
         entityInfo = null;
         isPendingEntitySelection = true;
         isEditingCustomName = false;
+        isEditingPlayer = false;
     }
 }
index dbde2edf19965f8392f281920cbdc89df96946e8..131bede19abeb6f9f1b80661b0d470b74cf548f1 100644 (file)
@@ -20,12 +20,15 @@ public class EntityInfo
     public int defenseDamageProbability;
     public int evasion;
     public int speed;
+    public int hasteSpeed;
+    public int slowSpeed;
     public String category;
     public int decisionAttack;
     public int decisionDefend;
     public int decisionFlee;
     public String customName;
-    
+    public String playerName;
+
     public enum Effect
     {
         SPEED,
@@ -369,17 +372,20 @@ public class EntityInfo
         defenseDamageProbability = 0;
         evasion = 15;
         speed = 50;
+        hasteSpeed = 80;
+        slowSpeed = 20;
         category = "unknown";
         decisionAttack = 70;
         decisionDefend = 20;
         decisionFlee = 10;
         customName = new String();
+        playerName = new String();
     }
 
     public EntityInfo(Class classType, boolean ignoreBattle, int attackPower, int attackProbability, int attackVariance,
                       Effect attackEffect, int attackEffectProbability, int defenseDamage, int defenseDamageProbability,
-                      int evasion, int speed, String category, int decisionAttack, int decisionDefend, int decisionFlee,
-                      String customName) {
+                      int evasion, int speed, int hasteSpeed, int slowSpeed, String category, int decisionAttack, int decisionDefend, int decisionFlee,
+                      String customName, String playerName) {
         this.classType = classType;
         this.ignoreBattle = ignoreBattle;
         this.attackPower = attackPower;
@@ -391,11 +397,14 @@ public class EntityInfo
         this.defenseDamageProbability = defenseDamageProbability;
         this.evasion = evasion;
         this.speed = speed;
+        this.hasteSpeed = hasteSpeed;
+        this.slowSpeed = slowSpeed;
         this.category = category;
         this.decisionAttack = decisionAttack;
         this.decisionDefend = decisionDefend;
         this.decisionFlee = decisionFlee;
         this.customName = customName;
+        this.playerName = playerName;
     }
     
     public EntityInfo clone()
@@ -412,11 +421,14 @@ public class EntityInfo
         newEntityInfo.defenseDamageProbability = defenseDamageProbability;
         newEntityInfo.evasion = evasion;
         newEntityInfo.speed = speed;
+        newEntityInfo.hasteSpeed = hasteSpeed;
+        newEntityInfo.slowSpeed = slowSpeed;
         newEntityInfo.category = category;
         newEntityInfo.decisionAttack = decisionAttack;
         newEntityInfo.decisionDefend = decisionDefend;
         newEntityInfo.decisionFlee = decisionFlee;
-        newEntityInfo.customName = new String(customName);
+        newEntityInfo.customName = customName;
+        newEntityInfo.playerName = playerName;
         return newEntityInfo;
     }
 
@@ -448,6 +460,8 @@ public class EntityInfo
         defenseDamageProbability = buffer.readInt();
         evasion = buffer.readInt();
         speed = buffer.readInt();
+        hasteSpeed = buffer.readInt();
+        slowSpeed = buffer.readInt();
 
         int category_len = buffer.readInt();
         ByteBuf category_bytes = buffer.readBytes(category_len);
@@ -464,6 +478,14 @@ public class EntityInfo
         } else {
             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) {
@@ -491,6 +513,8 @@ public class EntityInfo
         buffer.writeInt(defenseDamageProbability);
         buffer.writeInt(evasion);
         buffer.writeInt(speed);
+        buffer.writeInt(hasteSpeed);
+        buffer.writeInt(slowSpeed);
 
         byte[] category_bytes = category.getBytes(StandardCharsets.UTF_8);
         buffer.writeInt(category_bytes.length);
@@ -507,5 +531,13 @@ public class EntityInfo
             buffer.writeInt(custom_bytes.length);
             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);
+        }
     }
 }
index 8694d8725960dff582bfabc58cade7fdab8c48c9..64cd64f14802325960d93806251fb4e727e6257e 100644 (file)
@@ -48,11 +48,14 @@ public class PacketEditingMessage implements CustomPacketPayload
         EDIT_DEFENSE_DAMAGE_PROBABILITY(9),
         EDIT_EVASION(10),
         EDIT_SPEED(11),
+        EDIT_HASTE_SPEED(18),
+        EDIT_SLOW_SPEED(19),
         EDIT_CATEGORY(12),
         EDIT_DECISION_ATTACK(13),
         EDIT_DECISION_DEFEND(14),
         EDIT_DECISION_FLEE(15),
-        SERVER_EDIT(16);
+        SERVER_EDIT(16),
+        PICK_PLAYER(17);
 
         Type(int value)
         {