--- /dev/null
+package com.seodisparate.TurnBasedMinecraft.common;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Instant;
+import java.time.format.DateTimeFormatter;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.stream.FactoryConfigurationError;
+import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamReader;
+
+import org.apache.logging.log4j.Logger;
+
+import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
+import com.seodisparate.TurnBasedMinecraft.common.EntityInfo.Category;
+
+public class Config
+{
+ private Map<Class, EntityInfo> entityInfoMap;
+ private Set<EntityInfo.Category> ignoreBattleTypes;
+ private Logger logger;
+
+ private enum ConfigParseResult
+ {
+ IS_OLD,
+ SUCCESS
+ }
+
+ public Config(Logger logger)
+ {
+ entityInfoMap = new HashMap<Class, EntityInfo>();
+ ignoreBattleTypes = new HashSet<EntityInfo.Category>();
+ this.logger = logger;
+
+ try
+ {
+ File testLoad = new File(TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ if(!testLoad.exists())
+ {
+ writeConfig();
+ }
+ }
+ catch (Exception e)
+ {
+ logger.error("Failed to check/create-new config file");
+ }
+
+ // parse xml
+ File configFile = new File(TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ if(!configFile.exists() || !configFile.canRead())
+ {
+ logger.error("Failed to read/parse config file " + TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ return;
+ }
+ try
+ {
+ ConfigParseResult result = parseConfig(configFile);
+ if(result == ConfigParseResult.IS_OLD)
+ {
+ moveOldConfig();
+ writeConfig();
+ ConfigParseResult resultSecond = parseConfig(configFile);
+ if(resultSecond != ConfigParseResult.SUCCESS)
+ {
+ logger.error("Failed to parse config file " + TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ }
+ }
+ else if(result != ConfigParseResult.SUCCESS)
+ {
+ logger.error("Failed to parse config file " + TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ }
+ } catch (Exception e)
+ {
+ logger.error("Failed to parse config file " + TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ }
+ }
+
+ private void writeConfig() throws IOException
+ {
+ File configFile = new File(TurnBasedMinecraftMod.CONFIG_FILE_PATH);
+ File dirs = configFile.getParentFile();
+ dirs.mkdirs();
+ InputStream configStream = this.getClass().getResourceAsStream(TurnBasedMinecraftMod.CONFIG_FILENAME);
+ FileOutputStream configOutput = new FileOutputStream(configFile);
+ byte[] buf = new byte[4096];
+ int read = 0;
+ while(read != -1)
+ {
+ read = configStream.read(buf);
+ if(read > 0)
+ {
+ configOutput.write(buf, 0, read);
+ }
+ }
+ configStream.close();
+ configOutput.close();
+ }
+
+ private void moveOldConfig()
+ {
+ 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())));
+ }
+ }
+
+ private ConfigParseResult parseConfig(File configFile) throws XMLStreamException, FactoryConfigurationError, IOException
+ {
+ FileInputStream fis = new FileInputStream(configFile);
+ XMLStreamReader xmlReader = XMLInputFactory.newInstance().createXMLStreamReader(fis);
+ while(xmlReader.hasNext())
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ if(xmlReader.getLocalName().equals("TurnBasedMinecraftConfig"))
+ {
+ continue;
+ }
+ else if(xmlReader.getLocalName().equals("Version"))
+ {
+ if(Integer.parseInt(xmlReader.getElementText()) < TurnBasedMinecraftMod.CONFIG_FILE_VERSION)
+ {
+ logger.info("Config file is older version, moving it and writing a new one in its place");
+ xmlReader.close();
+ fis.close();
+ return ConfigParseResult.IS_OLD;
+ }
+ continue;
+ }
+ else if(xmlReader.getLocalName().equals("IgnoreBattleTypes"))
+ {
+ do
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ ignoreBattleTypes.add(Category.fromString(xmlReader.getLocalName()));
+ }
+ } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("IgnoreBattleTypes")));
+ }
+ else if(xmlReader.getLocalName().equals("EntityStats"))
+ {
+ do
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ String classType = xmlReader.getLocalName();
+ EntityInfo eInfo = new EntityInfo();
+ try
+ {
+ eInfo.classType = Class.forName(classType);
+ } catch (ClassNotFoundException e)
+ {
+ logger.error("Failed to get class of name " + classType);
+ continue;
+ }
+ do
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ if(xmlReader.getLocalName().equals("AttackPower"))
+ {
+ for(int i = 0; i < xmlReader.getAttributeCount(); ++i)
+ {
+ if(xmlReader.getAttributeLocalName(i).equals("Probability"))
+ {
+ eInfo.attackProbability = Integer.parseInt(xmlReader.getAttributeValue(i));
+ }
+ }
+ eInfo.attackPower = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("AttackEffect"))
+ {
+ for(int i = 0; i < xmlReader.getAttributeCount(); ++i)
+ {
+ if(xmlReader.getAttributeLocalName(i).equals("Probability"))
+ {
+ eInfo.attackEffectProbability = Integer.parseInt(xmlReader.getAttributeValue(i));
+ }
+ }
+ eInfo.attackEffect = EntityInfo.Effect.fromString(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("Evasion"))
+ {
+ eInfo.evasion = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("DefenseDamage"))
+ {
+ for(int i = 0; i < xmlReader.getAttributeCount(); ++i)
+ {
+ if(xmlReader.getAttributeLocalName(i).equals("Probability"))
+ {
+ eInfo.defenseDamageProbability = Integer.parseInt(xmlReader.getAttributeValue(i));
+ }
+ }
+ eInfo.defenseDamage = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("Category"))
+ {
+ eInfo.category = Category.fromString(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("Conflicts"))
+ {
+ do
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ try
+ {
+ Class conflictingType = Class.forName(xmlReader.getLocalName());
+ eInfo.conflictingTypes.add(conflictingType);
+ } catch(ClassNotFoundException e)
+ {
+ logger.warn("Invalid conflicting type for entity " + eInfo.classType.getName());
+ }
+ }
+ } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("Conflicts")));
+ }
+ }
+ } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals(classType)));
+ entityInfoMap.put(eInfo.classType, eInfo);
+ }
+ } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("EntityStats")));
+ }
+ }
+ }
+ xmlReader.close();
+ fis.close();
+ return ConfigParseResult.SUCCESS;
+ }
+}
--- /dev/null
+package com.seodisparate.TurnBasedMinecraft.common;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class EntityInfo
+{
+ public Class classType;
+ public List<Class> conflictingTypes;
+ public int attackPower;
+ public int attackProbability;
+ public Effect attackEffect;
+ public int attackEffectProbability;
+ public int defenseDamage;
+ public int defenseDamageProbability;
+ public int evasion;
+ public Category category;
+
+ public enum Category
+ {
+ MONSTER,
+ PASSIVE,
+ ANIMAL,
+ BOSS,
+ UNKNOWN;
+
+ public static Category fromString(String c)
+ {
+ c = c.toLowerCase();
+ if(c.equals("monster"))
+ {
+ return MONSTER;
+ }
+ else if(c.equals("passive"))
+ {
+ return PASSIVE;
+ }
+ else if(c.equals("animal"))
+ {
+ return ANIMAL;
+ }
+ else if(c.equals("boss"))
+ {
+ return BOSS;
+ }
+ else
+ {
+ return UNKNOWN;
+ }
+ }
+ }
+
+ public enum Effect
+ {
+ SPEED,
+ SLOW,
+ HASTE,
+ MINING_FATIGUE,
+ STRENGTH,
+ JUMP_BOOST,
+ NAUSEA,
+ REGENERATION,
+ RESISTANCE,
+ FIRE_RESISTANCE,
+ WATER_BREATHING,
+ INVISIBILITY,
+ BLINDNESS,
+ NIGHT_VISION,
+ HUNGER,
+ WEAKNESS,
+ POISON,
+ WITHER,
+ ABSORPTION,
+ SATURATION,
+ GLOWING,
+ LEVITATION,
+ LUCK,
+ UNLUCK,
+ FIRE,
+ UNKNOWN;
+
+ public static Effect fromString(String c)
+ {
+ c = c.toLowerCase();
+ if(c.equals("speed"))
+ {
+ return SPEED;
+ }
+ else if(c.equals("slow"))
+ {
+ return SLOW;
+ }
+ else if(c.equals("haste"))
+ {
+ return HASTE;
+ }
+ else if(c.equals("mining_fatigue") || c.equals("fatigue"))
+ {
+ return MINING_FATIGUE;
+ }
+ else if(c.equals("strength"))
+ {
+ return STRENGTH;
+ }
+ else if(c.equals("jump_boost"))
+ {
+ return JUMP_BOOST;
+ }
+ else if(c.equals("nausea"))
+ {
+ return NAUSEA;
+ }
+ else if(c.equals("regeneration"))
+ {
+ return REGENERATION;
+ }
+ else if(c.equals("resistance"))
+ {
+ return RESISTANCE;
+ }
+ else if(c.equals("fire_resistance"))
+ {
+ return FIRE_RESISTANCE;
+ }
+ else if(c.equals("water_breathing"))
+ {
+ return WATER_BREATHING;
+ }
+ else if(c.equals("invisibility"))
+ {
+ return INVISIBILITY;
+ }
+ else if(c.equals("blindness") || c.equals("blind"))
+ {
+ return BLINDNESS;
+ }
+ else if(c.equals("night_vision"))
+ {
+ return NIGHT_VISION;
+ }
+ else if(c.equals("hunger"))
+ {
+ return HUNGER;
+ }
+ else if(c.equals("weakness"))
+ {
+ return WEAKNESS;
+ }
+ else if(c.equals("poison"))
+ {
+ return POISON;
+ }
+ else if(c.equals("wither"))
+ {
+ return WITHER;
+ }
+ else if(c.equals("absorption"))
+ {
+ return ABSORPTION;
+ }
+ else if(c.equals("saturation"))
+ {
+ return SATURATION;
+ }
+ else if(c.equals("glowing"))
+ {
+ return GLOWING;
+ }
+ else if(c.equals("levitation"))
+ {
+ return LEVITATION;
+ }
+ else if(c.equals("luck"))
+ {
+ return LUCK;
+ }
+ else if(c.equals("unluck"))
+ {
+ return UNLUCK;
+ }
+ else if(c.equals("fire"))
+ {
+ return FIRE;
+ }
+ else
+ {
+ return UNKNOWN;
+ }
+ }
+ }
+
+ public EntityInfo()
+ {
+ classType = null;
+ conflictingTypes = new ArrayList<Class>();
+ attackPower = 0;
+ attackProbability = 70;
+ attackEffect = Effect.UNKNOWN;
+ attackEffectProbability = 50;
+ defenseDamage = 0;
+ defenseDamageProbability = 0;
+ evasion = 15;
+ category = Category.UNKNOWN;
+ }
+
+ public EntityInfo clone()
+ {
+ EntityInfo newEntityInfo = new EntityInfo();
+ newEntityInfo.classType = classType;
+ newEntityInfo.conflictingTypes = new ArrayList<Class>();
+ for(Class c : conflictingTypes)
+ {
+ newEntityInfo.conflictingTypes.add(c);
+ }
+ newEntityInfo.attackPower = attackPower;
+ newEntityInfo.attackProbability = attackProbability;
+ newEntityInfo.attackEffect = attackEffect;
+ newEntityInfo.attackEffectProbability = attackEffectProbability;
+ newEntityInfo.defenseDamage = defenseDamage;
+ newEntityInfo.defenseDamageProbability = defenseDamageProbability;
+ newEntityInfo.evasion = evasion;
+ newEntityInfo.category = category;
+ return newEntityInfo;
+ }
+}
<AttackPower Probability="50">5</AttackPower>
<AttackEffect Probability="75">fire</AttackEffect>
<Evasion>5</Evasion>
+ <Category>monster</Category>
</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>
</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>
</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>
</net.minecraft.entity.monster.EntityElderGuardian>
<net.minecraft.entity.monster.EntityEnderman>
<AttackPower Probability="80">7</AttackPower>
<Evasion>40</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityEnderman>
<net.minecraft.entity.monster.EntityEndermite>
<AttackPower Probability="80">2</AttackPower>
<Evasion>40</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityEndermite>
<net.minecraft.entity.monster.EntityEvoker>
<AttackPower Probability="60">6</AttackPower>
<Evasion>35</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityEvoker>
<net.minecraft.entity.monster.EntityGhast>
<IgnoreBattle>true</IgnoreBattle>
<AttackPower Probability="20">13</AttackPower>
<Evasion>35</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityGhast>
<net.minecraft.entity.monster.EntityGiantZombie>
<AttackPower Probability="35">11</AttackPower>
<Evasion>2</Evasion>
+ <Category>monster</Category>
</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>
</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>
</net.minecraft.entity.monster.EntityHusk>
<net.minecraft.entity.monster.EntityIronGolem>
<AttackPower Probability="85" Variance="7">14</AttackPower>
<Evasion>5</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityIronGolem>
<net.minecraft.entity.monster.EntityMagmaCube>
<AttackPower Probability="35">3</AttackPower>
<Evasion>12</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityMagmaCube>
<net.minecraft.entity.monster.EntityPigZombie>
<AttackPower Probability="70">8</AttackPower>
<Evasion>10</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityPigZombie>
<net.minecraft.entity.monster.EntityPolarBear>
<AttackPower Probability="67">6</AttackPower>
<Evasion>5</Evasion>
+ <Category>animal</Category>
</net.minecraft.entity.monster.EntityPolarBear>
<net.minecraft.entity.monster.EntityShulker>
<AttackPower Probability="80">4</AttackPower>
<Evasion>15</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityShulker>
<net.minecraft.entity.monster.EntitySilverFish>
<AttackPower Probability="85">1</AttackPower>
<Evasion>37</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntitySilverFish>
<net.minecraft.entity.monster.EntitySkeleton>
<AttackPower Probability="75" Variance="1">3</AttackPower>
<Evasion>13</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntitySkeleton>
<net.minecraft.entity.monster.EntitySlime>
<AttackPower Probability="35">2</AttackPower>
<Evasion>10</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntitySlime>
- <net.minecraft.entity.monster.EntitySnowman
- Passive="true">
+ <net.minecraft.entity.monster.EntitySnowman>
<AttackPower Probability="80">0</AttackPower>
<Evasion>5</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.monster.EntitySnowman>
<net.minecraft.entity.monster.EntitySpider>
<AttackPower Probability="70">2</AttackPower>
<Conflicts>
<net.minecraft.entity.monster.EntityCaveSpider></net.minecraft.entity.monster.EntityCaveSpider>
</Conflicts>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntitySpider>
<net.minecraft.entity.monster.EntityStray>
<AttackPower Probability="75" Variance="1">3</AttackPower>
- <AttackEffect Probability="90">slowness</AttackEffect>
+ <AttackEffect Probability="90">slow</AttackEffect>
<Evasion>13</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityStray>
<net.minecraft.entity.monster.EntityVex>
<AttackPower Probability="65">9</AttackPower>
<Evasion>30</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityVex>
<net.minecraft.entity.monster.EntityVindicator>
<AttackPower Probability="70">13</AttackPower>
<Evasion>10</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityVindicator>
<net.minecraft.entity.monster.EntityWitch>
<AttackPower Probability="75" Variance="1">5</AttackPower>
<Evasion>8</Evasion>
+ <Category>monster</Category>
</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>
</net.minecraft.entity.monster.EntityWitherSkeleton>
<net.minecraft.entity.monster.EntityZombie>
<AttackPower Probability="70">3</AttackPower>
<net.minecraft.entity.monster.EntityZombieVillager></net.minecraft.entity.monster.EntityZombieVillager>
</Conflicts>
<Evasion>5</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityZombie>
<net.minecraft.entity.monster.EntityZombieVillager>
<AttackPower Probability="70">3</AttackPower>
<Evasion>5</Evasion>
+ <Category>monster</Category>
</net.minecraft.entity.monster.EntityZombieVillager>
- <net.minecraft.entity.passive.EntityBat
- Passive="true">
+ <net.minecraft.entity.passive.EntityBat>
<AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityBat>
- <net.minecraft.entity.passive.EntityChicken
- Passive="true">
+ <net.minecraft.entity.passive.EntityChicken>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityChicken>
- <net.minecraft.entity.passive.EntityCow
- Passive="true">
+ <net.minecraft.entity.passive.EntityCow>
<AttackPower Probability="50">0</AttackPower>
<Evasion>1</Evasion>
<Conflicts>
<net.minecraft.entity.passive.EntityMooshroom></net.minecraft.entity.passive.EntityMooshroom>
</Conflicts>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityCow>
- <net.minecraft.entity.passive.EntityDonkey
- Passive="true">
+ <net.minecraft.entity.passive.EntityDonkey>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityDonkey>
- <net.minecraft.entity.passive.EntityHorse
- Passive="true">
+ <net.minecraft.entity.passive.EntityHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityHorse>
- <net.minecraft.entity.passive.EntityLlama
- Passive="true">
+ <net.minecraft.entity.passive.EntityLlama>
<AttackPower Probability="70">1</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityLlama>
- <net.minecraft.entity.passive.EntityMooshroom
- Passive="true">
+ <net.minecraft.entity.passive.EntityMooshroom>
<AttackPower Probability="70">0</AttackPower>
<Evasion>1</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityMooshroom>
- <net.minecraft.entity.passive.EntityMule
- Passive="true">
+ <net.minecraft.entity.passive.EntityMule>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityMule>
- <net.minecraft.entity.passive.EntityOcelot
- Passive="true">
+ <net.minecraft.entity.passive.EntityOcelot>
<AttackPower Probability="70" Variance="1">1</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityOcelot>
- <net.minecraft.entity.passive.EntityParrot
- Passive="true">
+ <net.minecraft.entity.passive.EntityParrot>
<AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityParrot>
- <net.minecraft.entity.passive.EntityPig
- Passive="true">
+ <net.minecraft.entity.passive.EntityPig>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityPig>
- <net.minecraft.entity.passive.EntityRabbit
- Passive="true">
+ <net.minecraft.entity.passive.EntityRabbit>
<AttackPower Probability="70">0</AttackPower>
<Evasion>40</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityRabbit>
- <net.minecraft.entity.passive.EntitySheep
- Passive="true">
+ <net.minecraft.entity.passive.EntitySheep>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntitySheep>
- <net.minecraft.entity.passive.EntitySkeletonHorse
- Passive="true">
+ <net.minecraft.entity.passive.EntitySkeletonHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntitySkeletonHorse>
- <net.minecraft.entity.passive.EntitySquid
- Passive="true">
+ <net.minecraft.entity.passive.EntitySquid>
<AttackPower Probability="70">0</AttackPower>
<Evasion>15</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntitySquid>
- <net.minecraft.entity.passive.EntityVillager
- Passive="true">
+ <net.minecraft.entity.passive.EntityVillager>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityVillager>
<net.minecraft.entity.passive.EntityWolf>
<AttackPower Probability="70">4</AttackPower>
<Evasion>20</Evasion>
+ <Category>animal</Category>
</net.minecraft.entity.passive.EntityWolf>
- <net.minecraft.entity.passive.EntityZombieHorse
- Passive="true">
+ <net.minecraft.entity.passive.EntityZombieHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>8</Evasion>
+ <Category>passive</Category>
</net.minecraft.entity.passive.EntityZombieHorse>
- <net.minecraft.entity.boss.EntityDragon
- Boss="true">
+ <net.minecraft.entity.boss.EntityDragon>
<AttackPower Probability="70" Variance="2">10</AttackPower>
<Evasion>27</Evasion>
+ <Category>boss</Category>
</net.minecraft.entity.boss.EntityDragon>
- <net.minecraft.entity.boss.EntityWither
- Boss="true">
+ <net.minecraft.entity.boss.EntityWither>
<AttackPower Probability="70">8</AttackPower>
<Evasion>20</Evasion>
<AttackEffect Probability="90">wither</AttackEffect>
+ <Category>boss</Category>
</net.minecraft.entity.boss.EntityWither>
</EntityStats>
</TurnBasedMinecraftConfig>
\ No newline at end of file