private static BattleManager battleManager;
private static int packetHandlerID = 0;
public static Entity attackingEntity;
- private static Config config;
+ public static Config config;
public static Battle currentBattle;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
+import java.util.PriorityQueue;
+import java.util.SortedSet;
+import java.util.TreeSet;
+import java.util.concurrent.PriorityBlockingQueue;
+import java.util.concurrent.atomic.AtomicInteger;
import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo;
private final int id;
private Map<Integer, Combatant> sideA;
private Map<Integer, Combatant> sideB;
- private Map<Integer, EntityPlayer> players;
+ private Map<Integer, Combatant> players;
+ private PriorityQueue<Combatant> turnOrderQueue;
private Instant lastUpdated;
private State state;
- private int playerCount;
- private int undecidedCount;
+ private AtomicInteger playerCount;
+ private AtomicInteger undecidedCount;
private Duration timer;
public enum State
this.id = id;
this.sideA = new Hashtable<Integer, Combatant>();
this.sideB = new Hashtable<Integer, Combatant>();
- players = new HashMap<Integer, EntityPlayer>();
- playerCount = 0;
+ players = new Hashtable<Integer, Combatant>();
+ turnOrderQueue = new PriorityQueue<Combatant>(new Combatant.CombatantComparator());
+ playerCount = new AtomicInteger(0);
+ undecidedCount = new AtomicInteger(0);
if(sideA != null)
{
for(Entity e : sideA)
{
- this.sideA.put(e.getEntityId(), new Combatant(e));
+ EntityInfo entityInfo = TurnBasedMinecraftMod.config.getMatchingEntityInfo(e);
+ if(entityInfo == null && !(e instanceof EntityPlayer))
+ {
+ continue;
+ }
+ Combatant newCombatant = new Combatant(e, entityInfo);
+ this.sideA.put(e.getEntityId(), newCombatant);
if(e instanceof EntityPlayer)
{
- ++playerCount;
- players.put(e.getEntityId(), (EntityPlayer)e);
+ newCombatant.recalcSpeedOnCompare = true;
+ playerCount.incrementAndGet();
+ players.put(e.getEntityId(), newCombatant);
}
}
}
{
for(Entity e : sideB)
{
- this.sideB.put(e.getEntityId(), new Combatant(e));
+ EntityInfo entityInfo = TurnBasedMinecraftMod.config.getMatchingEntityInfo(e);
+ if(entityInfo == null && !(e instanceof EntityPlayer))
+ {
+ continue;
+ }
+ Combatant newCombatant = new Combatant(e, entityInfo);
+ this.sideB.put(e.getEntityId(), newCombatant);
if(e instanceof EntityPlayer)
{
- ++playerCount;
- players.put(e.getEntityId(), (EntityPlayer)e);
+ newCombatant.recalcSpeedOnCompare = true;
+ playerCount.incrementAndGet();
+ players.put(e.getEntityId(), newCombatant);
}
}
}
lastUpdated = null;
state = State.DECISION;
- undecidedCount = playerCount;
+ undecidedCount.set(playerCount.get());
timer = TurnBasedMinecraftMod.BattleDecisionTime;
}
public void addCombatantToSideA(Entity e)
{
- sideA.put(e.getEntityId(), new Combatant(e));
+ EntityInfo entityInfo = TurnBasedMinecraftMod.config.getMatchingEntityInfo(e);
+ if(entityInfo == null && !(e instanceof EntityPlayer))
+ {
+ return;
+ }
+ Combatant newCombatant = new Combatant(e, entityInfo);
+ sideA.put(e.getEntityId(), newCombatant);
if(e instanceof EntityPlayer)
{
- ++playerCount;
- players.put(e.getEntityId(), (EntityPlayer)e);
+ newCombatant.recalcSpeedOnCompare = true;
+ playerCount.incrementAndGet();
+ players.put(e.getEntityId(), newCombatant);
if(state == State.DECISION)
{
- ++undecidedCount;
+ undecidedCount.incrementAndGet();
}
}
}
public void addCombatantToSideB(Entity e)
{
- sideB.put(e.getEntityId(), new Combatant(e));
+ EntityInfo entityInfo = TurnBasedMinecraftMod.config.getMatchingEntityInfo(e);
+ if(entityInfo == null && !(e instanceof EntityPlayer))
+ {
+ return;
+ }
+ Combatant newCombatant = new Combatant(e, entityInfo);
+ sideB.put(e.getEntityId(), newCombatant);
if(e instanceof EntityPlayer)
{
- ++playerCount;
- players.put(e.getEntityId(), (EntityPlayer)e);
+ newCombatant.recalcSpeedOnCompare = true;
+ playerCount.incrementAndGet();
+ players.put(e.getEntityId(), newCombatant);
if(state == State.DECISION)
{
- ++undecidedCount;
+ undecidedCount.incrementAndGet();
}
}
}
sideA.clear();
sideB.clear();
players.clear();
- playerCount = 0;
- undecidedCount = 0;
+ playerCount.set(0);
+ undecidedCount.set(0);
}
public Collection<Combatant> getSideA()
return combatant;
}
- public void setDecision(int entityID, Decision decision)
+ public void setDecision(int entityID, Decision decision, int targetEntityID)
{
if(state != State.DECISION)
{
return;
}
- Combatant combatant = sideA.get(entityID);
+ Combatant combatant = players.get(entityID);
if(combatant == null)
{
- combatant = sideB.get(entityID);
- if(combatant == null)
- {
- return;
- }
- }
-
- if(combatant.entity instanceof EntityPlayer)
- {
- combatant.decision = decision;
- --undecidedCount;
+ return;
}
+ combatant.decision = decision;
+ combatant.targetEntityID = targetEntityID;
+ undecidedCount.decrementAndGet();
}
public State getState()
return;
}
PacketBattleInfo infoPacket = new PacketBattleInfo(getSideAIDs(), getSideBIDs());
- for(EntityPlayer p : players.values())
+ for(Combatant p : players.values())
{
- PacketHandler.INSTANCE.sendTo(infoPacket, (EntityPlayerMP)p);
+ PacketHandler.INSTANCE.sendTo(infoPacket, (EntityPlayerMP)p.entity);
}
}
{
case DECISION:
timer = timer.minus(dt);
- if(timer.isNegative() || timer.isZero() || undecidedCount <= 0)
+ if(timer.isNegative() || timer.isZero() || undecidedCount.get() <= 0)
{
state = State.ATTACK;
timer = TurnBasedMinecraftMod.BattleDecisionTime;
+ turnOrderQueue.clear();
+ for(Combatant c : sideA.values())
+ {
+ turnOrderQueue.add(c);
+ }
+ for(Combatant c : sideB.values())
+ {
+ turnOrderQueue.add(c);
+ }
update(Duration.ZERO);
}
break;
case ATTACK:
- // TODO
+ Combatant next = turnOrderQueue.poll();
+ while(next != null)
+ {
+ // TODO attack per entity here
+ next = turnOrderQueue.poll();
+ }
break;
case HEALTH_CHECK:
// TODO
import java.util.Hashtable;
import java.util.Map;
+import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleEntered;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
*/
public boolean checkAttack(final LivingAttackEvent event)
{
+ // verify that both entities are EntityPlayer or has a corresponding EntityInfo
+ if(!(event.getEntity() instanceof EntityPlayer || TurnBasedMinecraftMod.config.getEntityInfoReference(event.getEntity().getClass().getName()) != null)
+ || !(event.getSource().getTrueSource() instanceof EntityPlayer || TurnBasedMinecraftMod.config.getEntityInfoReference(event.getSource().getTrueSource().getClass().getName()) != null))
+ {
+ return false;
+ }
// check if one is in battle
Entity inBattle = null;
Entity notInBattle = null;
package com.seodisparate.TurnBasedMinecraft.common;
+import java.util.Comparator;
+
+import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
+
import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.init.MobEffects;
+import net.minecraft.potion.PotionEffect;
public class Combatant
{
public Entity entity;
public Battle.Decision decision;
public int itemToUse;
- public float speed;
+ public EntityInfo entityInfo;
+ public boolean recalcSpeedOnCompare;
+ public int targetEntityID;
public Combatant()
{
decision = Battle.Decision.UNDECIDED;
- speed = 0.5f;
+ recalcSpeedOnCompare = false;
}
- public Combatant(Entity e)
+ public Combatant(Entity e, EntityInfo entityInfo)
{
entity = e;
decision = Battle.Decision.UNDECIDED;
- speed = 0.5f;
+ this.entityInfo = entityInfo;
+ recalcSpeedOnCompare = false;
}
- public Combatant(Entity e, float speed)
+ /**
+ * Provided in reverse order of speed because PriorityQueue has least first.
+ */
+ public static class CombatantComparator implements Comparator<Combatant>
{
- entity = e;
- decision = Battle.Decision.UNDECIDED;
- this.speed = speed;
+ @Override
+ public int compare(Combatant c0, Combatant c1)
+ {
+ if(c0.entity instanceof EntityPlayer && c0.recalcSpeedOnCompare)
+ {
+ EntityLivingBase c0Entity = (EntityLivingBase)c0.entity;
+ boolean isHaste = false;
+ boolean isSlow = false;
+ for(PotionEffect e : c0Entity.getActivePotionEffects())
+ {
+ if(e.getEffectName().equals(MobEffects.HASTE.getName()))
+ {
+ isHaste = true;
+ }
+ else if(e.getEffectName().equals(MobEffects.SLOWNESS.getName()))
+ {
+ isSlow = true;
+ }
+ }
+ if(c0.entityInfo == null)
+ {
+ c0.entityInfo = new EntityInfo();
+ }
+ if(isHaste && !isSlow)
+ {
+ c0.entityInfo.speed = TurnBasedMinecraftMod.config.getPlayerHasteSpeed();
+ }
+ else if(isSlow && !isHaste)
+ {
+ c0.entityInfo.speed = TurnBasedMinecraftMod.config.getPlayerSlowSpeed();
+ }
+ else
+ {
+ c0.entityInfo.speed = TurnBasedMinecraftMod.config.getPlayerSpeed();
+ }
+ }
+
+ if(c1.entity instanceof EntityPlayer && c1.recalcSpeedOnCompare)
+ {
+ EntityLivingBase c1Entity = (EntityLivingBase)c1.entity;
+ boolean isHaste = false;
+ boolean isSlow = false;
+ for(PotionEffect e : c1Entity.getActivePotionEffects())
+ {
+ if(e.getEffectName().equals(MobEffects.HASTE.getName()))
+ {
+ isHaste = true;
+ }
+ else if(e.getEffectName().equals(MobEffects.SLOWNESS.getName()))
+ {
+ isSlow = true;
+ }
+ }
+ if(c1.entityInfo == null)
+ {
+ c1.entityInfo = new EntityInfo();
+ }
+ if(isHaste && !isSlow)
+ {
+ c1.entityInfo.speed = TurnBasedMinecraftMod.config.getPlayerHasteSpeed();
+ }
+ else if(isSlow && !isHaste)
+ {
+ c1.entityInfo.speed = TurnBasedMinecraftMod.config.getPlayerSlowSpeed();
+ }
+ else
+ {
+ c1.entityInfo.speed = TurnBasedMinecraftMod.config.getPlayerSpeed();
+ }
+ }
+
+ if(c0.entityInfo.speed > c1.entityInfo.speed)
+ {
+ return -1;
+ }
+ else if(c0.entityInfo.speed < c1.entityInfo.speed)
+ {
+ return 1;
+ }
+ else
+ {
+ return 0;
+ }
+ }
}
}
public class Config
{
- private Map<Class, EntityInfo> entityInfoMap;
+ private Map<String, EntityInfo> entityInfoMap;
private Set<EntityInfo.Category> ignoreBattleTypes;
private Logger logger;
+ private int playerSpeed;
+ private int playerHasteSpeed;
+ private int playerSlowSpeed;
private enum ConfigParseResult
{
public Config(Logger logger)
{
- entityInfoMap = new HashMap<Class, EntityInfo>();
+ entityInfoMap = new HashMap<String, EntityInfo>();
ignoreBattleTypes = new HashSet<EntityInfo.Category>();
this.logger = logger;
ConfigParseResult result = parseConfig(configFile);
if(result == ConfigParseResult.IS_OLD)
{
+ logger.warn("Config file " + TurnBasedMinecraftMod.CONFIG_FILENAME + " is older version, renaming...");
moveOldConfig();
writeConfig();
ConfigParseResult resultSecond = parseConfig(configFile);
File configFile = new File(TurnBasedMinecraftMod.CONFIG_FILE_PATH);
if(configFile.exists())
{
- configFile.renameTo(new File(TurnBasedMinecraftMod.CONFIG_DIRECTORY + "_"
- + DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(Instant.now())));
+ configFile.renameTo(new File(TurnBasedMinecraftMod.CONFIG_DIRECTORY
+ + "TBM_Config_"
+ + DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(Instant.now())
+ + ".xml"));
}
}
}
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("IgnoreBattleTypes")));
}
+ else if(xmlReader.getLocalName().equals("PlayerStats"))
+ {
+ do
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ if(xmlReader.getLocalName().equals("Speed"))
+ {
+ playerSpeed = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("HasteSpeed"))
+ {
+ playerHasteSpeed = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("SlowSpeed"))
+ {
+ playerSlowSpeed = Integer.parseInt(xmlReader.getElementText());
+ }
+ }
+ } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("PlayerStats")));
+ }
else if(xmlReader.getLocalName().equals("EntityStats"))
{
do
{
eInfo.attackProbability = Integer.parseInt(xmlReader.getAttributeValue(i));
}
+ else if(xmlReader.getAttributeLocalName(i).equals("Variance"))
+ {
+ eInfo.attackVariance = Integer.parseInt(xmlReader.getAttributeValue(i));
+ }
}
eInfo.attackPower = Integer.parseInt(xmlReader.getElementText());
}
}
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("Conflicts")));
}
+ else if(xmlReader.getLocalName().equals("IgnoreBattle"))
+ {
+ if(xmlReader.getElementText().toLowerCase().equals("true"))
+ {
+ eInfo.ignoreBattle = true;
+ }
+ }
+ else if(xmlReader.getLocalName().equals("Speed"))
+ {
+ eInfo.speed = Integer.parseInt(xmlReader.getElementText());
+ }
}
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals(classType)));
- entityInfoMap.put(eInfo.classType, eInfo);
+ entityInfoMap.put(eInfo.classType.getName(), eInfo);
}
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("EntityStats")));
}
fis.close();
return ConfigParseResult.SUCCESS;
}
+
+ public int getPlayerSpeed()
+ {
+ return playerSpeed;
+ }
+
+ public int getPlayerHasteSpeed()
+ {
+ return playerHasteSpeed;
+ }
+
+ public int getPlayerSlowSpeed()
+ {
+ return playerSlowSpeed;
+ }
+
+ /**
+ * Returns a clone of an EntityInfo (to prevent editing it).
+ * @param classFullName
+ * @return a clone of the stored EntityInfo or null if invalid String
+ */
+ public EntityInfo getEntityInfo(String classFullName)
+ {
+ return entityInfoMap.get(classFullName).clone();
+ }
+
+ protected EntityInfo getEntityInfoReference(String classFullName)
+ {
+ return entityInfoMap.get(classFullName);
+ }
+
+ protected EntityInfo getMatchingEntityInfo(Object entity)
+ {
+ EntityInfo matching = entityInfoMap.get(entity.getClass().getName());
+ if(matching.classType.isInstance(entity))
+ {
+ for(Class c : matching.conflictingTypes)
+ {
+ if(c.isInstance(entity))
+ {
+ return entityInfoMap.get(c.getName());
+ }
+ }
+ return matching;
+ }
+ return null;
+ }
}
package com.seodisparate.TurnBasedMinecraft.common;
import java.util.ArrayList;
+import java.util.Comparator;
import java.util.List;
public class EntityInfo
{
public Class classType;
public List<Class> conflictingTypes;
+ public boolean ignoreBattle;
public int attackPower;
public int attackProbability;
+ public int attackVariance;
public Effect attackEffect;
public int attackEffectProbability;
public int defenseDamage;
public int defenseDamageProbability;
public int evasion;
+ public int speed;
public Category category;
public enum Category
{
classType = null;
conflictingTypes = new ArrayList<Class>();
+ ignoreBattle = false;
attackPower = 0;
attackProbability = 70;
+ attackVariance = 0;
attackEffect = Effect.UNKNOWN;
attackEffectProbability = 50;
defenseDamage = 0;
defenseDamageProbability = 0;
evasion = 15;
+ speed = 50;
category = Category.UNKNOWN;
}
{
newEntityInfo.conflictingTypes.add(c);
}
+ newEntityInfo.ignoreBattle = ignoreBattle;
newEntityInfo.attackPower = attackPower;
newEntityInfo.attackProbability = attackProbability;
+ newEntityInfo.attackVariance = attackVariance;
newEntityInfo.attackEffect = attackEffect;
newEntityInfo.attackEffectProbability = attackEffectProbability;
newEntityInfo.defenseDamage = defenseDamage;
newEntityInfo.defenseDamageProbability = defenseDamageProbability;
newEntityInfo.evasion = evasion;
+ newEntityInfo.speed = speed;
newEntityInfo.category = category;
return newEntityInfo;
}
{
private int battleID;
private Battle.Decision decision;
+ private int targetEntityID;
public PacketBattleDecision() {}
- public PacketBattleDecision(int battleID, Battle.Decision decision)
+ public PacketBattleDecision(int battleID, Battle.Decision decision, int targetEntityID)
{
this.battleID = battleID;
this.decision = decision;
+ this.targetEntityID = targetEntityID;
}
@Override
{
battleID = buf.readInt();
decision = Decision.valueOf(buf.readInt());
+ targetEntityID = buf.readInt();
}
@Override
{
buf.writeInt(battleID);
buf.writeInt(decision.getValue());
+ buf.writeInt(targetEntityID);
}
public static class HandleBattleDecision implements IMessageHandler<PacketBattleDecision, IMessage>
if(b != null)
{
EntityPlayerMP player = ctx.getServerHandler().player;
- b.setDecision(player.getEntityId(), message.decision);
+ b.setDecision(player.getEntityId(), message.decision, message.targetEntityID);
}
return null;
}
<TurnBasedMinecraftConfig>
+ <!-- If the mod has a newer version config, it will rename the existing config and place the new config -->
<Version>1</Version>
+ <!-- Types that will not initiate battle with player. They are listed as "Category" per EntiytStats entity. -->
<IgnoreBattleTypes>
<Passive></Passive>
<Boss></Boss>
</IgnoreBattleTypes>
+ <PlayerStats>
+ <Speed>50</Speed>
+ <HasteSpeed>80</HasteSpeed>
+ <SlowSpeed>20</SlowSpeed>
+ </PlayerStats>
+ <!-- Battle stats for entities should be specified here. If an entity is not listed it cannot enter battle. -->
<EntityStats>
+ <!-- AttackPower: How much damage an entity does per attack. Usually has a "Probability" attribute between 0 and 100. Also may have a "Variance" attribute that varies the attack power by the specified amount randomly. -->
+ <!-- AttackEffect: (Optional) Applies effect to target entity with "Probability" success rate. -->
+ <!-- DefenseDamage: (Optional) Applies damage to an attacker when attacked with "Probability" success rate. -->
+ <!-- Evasion: Determines the percentage of evading attacks between 0 and 100. -->
+ <!-- Speed: Value in range of 0 to 100 that determines the order entities act in battle. Higher is sooner. Entities with same speed will take their turn as a group in random order (not at the same time). -->
+ <!-- IgnoreBattle: (Optional) Per entity setting to not enter turn-based-battle if value is "true". If "true" these stats will not apply to the entity as they are only used in turn-based-battle. -->
+ <!-- Category: Sets the type of the entity, used by "IgnoreBattleTypes" to determine what types ignore battle. -->
+ <!-- Conflicts: (Optional) Tells the mod that this entity should not be mistaken for the listed entities (possible because some entities derive from others; CaveSpiders are also Spiders). -->
<net.minecraft.entity.monster.EntityBlaze>
<AttackPower Probability="50">5</AttackPower>
<AttackEffect Probability="75">fire</AttackEffect>
<Evasion>5</Evasion>
<Category>monster</Category>
+ <Speed>45</Speed>
</net.minecraft.entity.monster.EntityBlaze>
<net.minecraft.entity.monster.EntityCaveSpider>
<AttackPower Probability="75">2</AttackPower>
<AttackEffect Probability="90">poison</AttackEffect>
<Evasion>35</Evasion>
<Category>monster</Category>
+ <Speed>75</Speed>
</net.minecraft.entity.monster.EntityCaveSpider>
<net.minecraft.entity.monster.EntityCreeper>
<IgnoreBattle>true</IgnoreBattle>
<AttackPower Probability="17" Variance="7">15</AttackPower>
<Evasion>5</Evasion>
<Category>monster</Category>
+ <Speed>25</Speed>
</net.minecraft.entity.monster.EntityCreeper>
<net.minecraft.entity.monster.EntityElderGuardian>
<AttackPower Probability="65">8</AttackPower>
<DefenseDamage Probability="35">2</DefenseDamage>
<Evasion>25</Evasion>
<Category>monster</Category>
+ <Speed>45</Speed>
</net.minecraft.entity.monster.EntityElderGuardian>
<net.minecraft.entity.monster.EntityEnderman>
<AttackPower Probability="80">7</AttackPower>
<Evasion>40</Evasion>
<Category>monster</Category>
+ <Speed>70</Speed>
</net.minecraft.entity.monster.EntityEnderman>
<net.minecraft.entity.monster.EntityEndermite>
<AttackPower Probability="80">2</AttackPower>
<Evasion>40</Evasion>
<Category>monster</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntityEndermite>
<net.minecraft.entity.monster.EntityEvoker>
<AttackPower Probability="60">6</AttackPower>
<Evasion>35</Evasion>
<Category>monster</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntityEvoker>
<net.minecraft.entity.monster.EntityGhast>
<IgnoreBattle>true</IgnoreBattle>
<AttackPower Probability="20">13</AttackPower>
<Evasion>35</Evasion>
<Category>monster</Category>
+ <Speed>60</Speed>
</net.minecraft.entity.monster.EntityGhast>
<net.minecraft.entity.monster.EntityGiantZombie>
<AttackPower Probability="35">11</AttackPower>
<Evasion>2</Evasion>
<Category>monster</Category>
+ <Speed>45</Speed>
</net.minecraft.entity.monster.EntityGiantZombie>
<net.minecraft.entity.monster.EntityGuardian>
<AttackPower Probability="55">6</AttackPower>
<DefenseDamage Probability="30">2</DefenseDamage>
<Evasion>25</Evasion>
<Category>monster</Category>
+ <Speed>50</Speed>
</net.minecraft.entity.monster.EntityGuardian>
<net.minecraft.entity.monster.EntityHusk>
<AttackPower Probability="70">3</AttackPower>
<AttackEffect Probability="95">hunger</AttackEffect>
<Evasion>5</Evasion>
<Category>monster</Category>
+ <Speed>25</Speed>
</net.minecraft.entity.monster.EntityHusk>
<net.minecraft.entity.monster.EntityIronGolem>
<AttackPower Probability="85" Variance="7">14</AttackPower>
<Evasion>5</Evasion>
<Category>monster</Category>
+ <Speed>45</Speed>
</net.minecraft.entity.monster.EntityIronGolem>
<net.minecraft.entity.monster.EntityMagmaCube>
<AttackPower Probability="35">3</AttackPower>
<Evasion>12</Evasion>
<Category>monster</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntityMagmaCube>
<net.minecraft.entity.monster.EntityPigZombie>
<AttackPower Probability="70">8</AttackPower>
<Evasion>10</Evasion>
<Category>monster</Category>
+ <Speed>50</Speed>
</net.minecraft.entity.monster.EntityPigZombie>
<net.minecraft.entity.monster.EntityPolarBear>
<AttackPower Probability="67">6</AttackPower>
<Evasion>5</Evasion>
<Category>animal</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntityPolarBear>
<net.minecraft.entity.monster.EntityShulker>
<AttackPower Probability="80">4</AttackPower>
<Evasion>15</Evasion>
<Category>monster</Category>
+ <Speed>10</Speed>
</net.minecraft.entity.monster.EntityShulker>
<net.minecraft.entity.monster.EntitySilverFish>
<AttackPower Probability="85">1</AttackPower>
<Evasion>37</Evasion>
<Category>monster</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntitySilverFish>
<net.minecraft.entity.monster.EntitySkeleton>
<AttackPower Probability="75" Variance="1">3</AttackPower>
<Evasion>13</Evasion>
<Category>monster</Category>
+ <Speed>30</Speed>
</net.minecraft.entity.monster.EntitySkeleton>
<net.minecraft.entity.monster.EntitySlime>
<AttackPower Probability="35">2</AttackPower>
<Evasion>10</Evasion>
<Category>monster</Category>
+ <Speed>30</Speed>
</net.minecraft.entity.monster.EntitySlime>
<net.minecraft.entity.monster.EntitySnowman>
<AttackPower Probability="80">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
+ <Speed>60</Speed>
</net.minecraft.entity.monster.EntitySnowman>
<net.minecraft.entity.monster.EntitySpider>
<AttackPower Probability="70">2</AttackPower>
<net.minecraft.entity.monster.EntityCaveSpider></net.minecraft.entity.monster.EntityCaveSpider>
</Conflicts>
<Category>monster</Category>
+ <Speed>70</Speed>
</net.minecraft.entity.monster.EntitySpider>
<net.minecraft.entity.monster.EntityStray>
<AttackPower Probability="75" Variance="1">3</AttackPower>
<AttackEffect Probability="90">slow</AttackEffect>
<Evasion>13</Evasion>
<Category>monster</Category>
+ <Speed>30</Speed>
</net.minecraft.entity.monster.EntityStray>
<net.minecraft.entity.monster.EntityVex>
<AttackPower Probability="65">9</AttackPower>
<Evasion>30</Evasion>
<Category>monster</Category>
+ <Speed>80</Speed>
</net.minecraft.entity.monster.EntityVex>
<net.minecraft.entity.monster.EntityVindicator>
<AttackPower Probability="70">13</AttackPower>
<Evasion>10</Evasion>
<Category>monster</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntityVindicator>
<net.minecraft.entity.monster.EntityWitch>
<AttackPower Probability="75" Variance="1">5</AttackPower>
<Evasion>8</Evasion>
<Category>monster</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.monster.EntityWitch>
<net.minecraft.entity.monster.EntityWitherSkeleton>
<AttackPower Probability="70">8</AttackPower>
<AttackEffect Probability="90">wither</AttackEffect>
<Evasion>7</Evasion>
<Category>monster</Category>
+ <Speed>65</Speed>
</net.minecraft.entity.monster.EntityWitherSkeleton>
<net.minecraft.entity.monster.EntityZombie>
<AttackPower Probability="70">3</AttackPower>
</Conflicts>
<Evasion>5</Evasion>
<Category>monster</Category>
+ <Speed>25</Speed>
</net.minecraft.entity.monster.EntityZombie>
<net.minecraft.entity.monster.EntityZombieVillager>
<AttackPower Probability="70">3</AttackPower>
<Evasion>5</Evasion>
<Category>monster</Category>
+ <Speed>25</Speed>
</net.minecraft.entity.monster.EntityZombieVillager>
<net.minecraft.entity.passive.EntityBat>
<AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion>
<Category>passive</Category>
+ <Speed>75</Speed>
</net.minecraft.entity.passive.EntityBat>
<net.minecraft.entity.passive.EntityChicken>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.passive.EntityChicken>
<net.minecraft.entity.passive.EntityCow>
<AttackPower Probability="50">0</AttackPower>
<net.minecraft.entity.passive.EntityMooshroom></net.minecraft.entity.passive.EntityMooshroom>
</Conflicts>
<Category>passive</Category>
+ <Speed>20</Speed>
</net.minecraft.entity.passive.EntityCow>
<net.minecraft.entity.passive.EntityDonkey>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>65</Speed>
</net.minecraft.entity.passive.EntityDonkey>
<net.minecraft.entity.passive.EntityHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>65</Speed>
</net.minecraft.entity.passive.EntityHorse>
<net.minecraft.entity.passive.EntityLlama>
<AttackPower Probability="70">1</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>50</Speed>
</net.minecraft.entity.passive.EntityLlama>
<net.minecraft.entity.passive.EntityMooshroom>
<AttackPower Probability="70">0</AttackPower>
<Evasion>1</Evasion>
<Category>passive</Category>
+ <Speed>20</Speed>
</net.minecraft.entity.passive.EntityMooshroom>
<net.minecraft.entity.passive.EntityMule>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>50</Speed>
</net.minecraft.entity.passive.EntityMule>
<net.minecraft.entity.passive.EntityOcelot>
<AttackPower Probability="70" Variance="1">1</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>75</Speed>
</net.minecraft.entity.passive.EntityOcelot>
<net.minecraft.entity.passive.EntityParrot>
<AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion>
<Category>passive</Category>
+ <Speed>70</Speed>
</net.minecraft.entity.passive.EntityParrot>
<net.minecraft.entity.passive.EntityPig>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
+ <Speed>30</Speed>
</net.minecraft.entity.passive.EntityPig>
<net.minecraft.entity.passive.EntityRabbit>
<AttackPower Probability="70">0</AttackPower>
<Evasion>40</Evasion>
<Category>passive</Category>
+ <Speed>75</Speed>
</net.minecraft.entity.passive.EntityRabbit>
<net.minecraft.entity.passive.EntitySheep>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
+ <Speed>30</Speed>
</net.minecraft.entity.passive.EntitySheep>
<net.minecraft.entity.passive.EntitySkeletonHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
+ <Speed>65</Speed>
</net.minecraft.entity.passive.EntitySkeletonHorse>
<net.minecraft.entity.passive.EntitySquid>
<AttackPower Probability="70">0</AttackPower>
<Evasion>15</Evasion>
<Category>passive</Category>
+ <Speed>40</Speed>
</net.minecraft.entity.passive.EntitySquid>
<net.minecraft.entity.passive.EntityVillager>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
+ <Speed>35</Speed>
</net.minecraft.entity.passive.EntityVillager>
<net.minecraft.entity.passive.EntityWolf>
<AttackPower Probability="70">4</AttackPower>
<Evasion>20</Evasion>
<Category>animal</Category>
+ <Speed>70</Speed>
</net.minecraft.entity.passive.EntityWolf>
<net.minecraft.entity.passive.EntityZombieHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>8</Evasion>
<Category>passive</Category>
+ <Speed>65</Speed>
</net.minecraft.entity.passive.EntityZombieHorse>
<net.minecraft.entity.boss.EntityDragon>
<AttackPower Probability="70" Variance="2">10</AttackPower>
<Evasion>27</Evasion>
<Category>boss</Category>
+ <Speed>63</Speed>
</net.minecraft.entity.boss.EntityDragon>
<net.minecraft.entity.boss.EntityWither>
<AttackPower Probability="70">8</AttackPower>
<Evasion>20</Evasion>
<AttackEffect Probability="90">wither</AttackEffect>
<Category>boss</Category>
+ <Speed>68</Speed>
</net.minecraft.entity.boss.EntityWither>
</EntityStats>
</TurnBasedMinecraftConfig>
\ No newline at end of file