WIP more work on setup and Battle logic

This commit is contained in:
Stephen Seo 2018-09-04 15:21:49 +09:00
parent 26c3356147
commit c8ce401e4d
8 changed files with 368 additions and 55 deletions

View file

@ -39,7 +39,7 @@ public class TurnBasedMinecraftMod
private static BattleManager battleManager; private static BattleManager battleManager;
private static int packetHandlerID = 0; private static int packetHandlerID = 0;
public static Entity attackingEntity; public static Entity attackingEntity;
private static Config config; public static Config config;
public static Battle currentBattle; public static Battle currentBattle;

View file

@ -7,6 +7,11 @@ import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Map; 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.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo; import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo;
@ -21,12 +26,13 @@ public class Battle
private final int id; private final int id;
private Map<Integer, Combatant> sideA; private Map<Integer, Combatant> sideA;
private Map<Integer, Combatant> sideB; private Map<Integer, Combatant> sideB;
private Map<Integer, EntityPlayer> players; private Map<Integer, Combatant> players;
private PriorityQueue<Combatant> turnOrderQueue;
private Instant lastUpdated; private Instant lastUpdated;
private State state; private State state;
private int playerCount; private AtomicInteger playerCount;
private int undecidedCount; private AtomicInteger undecidedCount;
private Duration timer; private Duration timer;
public enum State public enum State
@ -76,17 +82,26 @@ public class Battle
this.id = id; this.id = id;
this.sideA = new Hashtable<Integer, Combatant>(); this.sideA = new Hashtable<Integer, Combatant>();
this.sideB = new Hashtable<Integer, Combatant>(); this.sideB = new Hashtable<Integer, Combatant>();
players = new HashMap<Integer, EntityPlayer>(); players = new Hashtable<Integer, Combatant>();
playerCount = 0; turnOrderQueue = new PriorityQueue<Combatant>(new Combatant.CombatantComparator());
playerCount = new AtomicInteger(0);
undecidedCount = new AtomicInteger(0);
if(sideA != null) if(sideA != null)
{ {
for(Entity e : sideA) 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) if(e instanceof EntityPlayer)
{ {
++playerCount; newCombatant.recalcSpeedOnCompare = true;
players.put(e.getEntityId(), (EntityPlayer)e); playerCount.incrementAndGet();
players.put(e.getEntityId(), newCombatant);
} }
} }
} }
@ -94,18 +109,25 @@ public class Battle
{ {
for(Entity e : sideB) 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) if(e instanceof EntityPlayer)
{ {
++playerCount; newCombatant.recalcSpeedOnCompare = true;
players.put(e.getEntityId(), (EntityPlayer)e); playerCount.incrementAndGet();
players.put(e.getEntityId(), newCombatant);
} }
} }
} }
lastUpdated = null; lastUpdated = null;
state = State.DECISION; state = State.DECISION;
undecidedCount = playerCount; undecidedCount.set(playerCount.get());
timer = TurnBasedMinecraftMod.BattleDecisionTime; timer = TurnBasedMinecraftMod.BattleDecisionTime;
} }
@ -126,28 +148,42 @@ public class Battle
public void addCombatantToSideA(Entity e) 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) if(e instanceof EntityPlayer)
{ {
++playerCount; newCombatant.recalcSpeedOnCompare = true;
players.put(e.getEntityId(), (EntityPlayer)e); playerCount.incrementAndGet();
players.put(e.getEntityId(), newCombatant);
if(state == State.DECISION) if(state == State.DECISION)
{ {
++undecidedCount; undecidedCount.incrementAndGet();
} }
} }
} }
public void addCombatantToSideB(Entity e) 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) if(e instanceof EntityPlayer)
{ {
++playerCount; newCombatant.recalcSpeedOnCompare = true;
players.put(e.getEntityId(), (EntityPlayer)e); playerCount.incrementAndGet();
players.put(e.getEntityId(), newCombatant);
if(state == State.DECISION) if(state == State.DECISION)
{ {
++undecidedCount; undecidedCount.incrementAndGet();
} }
} }
} }
@ -157,8 +193,8 @@ public class Battle
sideA.clear(); sideA.clear();
sideB.clear(); sideB.clear();
players.clear(); players.clear();
playerCount = 0; playerCount.set(0);
undecidedCount = 0; undecidedCount.set(0);
} }
public Collection<Combatant> getSideA() public Collection<Combatant> getSideA()
@ -201,27 +237,20 @@ public class Battle
return combatant; return combatant;
} }
public void setDecision(int entityID, Decision decision) public void setDecision(int entityID, Decision decision, int targetEntityID)
{ {
if(state != State.DECISION) if(state != State.DECISION)
{ {
return; return;
} }
Combatant combatant = sideA.get(entityID); Combatant combatant = players.get(entityID);
if(combatant == null)
{
combatant = sideB.get(entityID);
if(combatant == null) if(combatant == null)
{ {
return; return;
} }
}
if(combatant.entity instanceof EntityPlayer)
{
combatant.decision = decision; combatant.decision = decision;
--undecidedCount; combatant.targetEntityID = targetEntityID;
} undecidedCount.decrementAndGet();
} }
public State getState() public State getState()
@ -236,9 +265,9 @@ public class Battle
return; return;
} }
PacketBattleInfo infoPacket = new PacketBattleInfo(getSideAIDs(), getSideBIDs()); 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);
} }
} }
@ -263,15 +292,29 @@ public class Battle
{ {
case DECISION: case DECISION:
timer = timer.minus(dt); timer = timer.minus(dt);
if(timer.isNegative() || timer.isZero() || undecidedCount <= 0) if(timer.isNegative() || timer.isZero() || undecidedCount.get() <= 0)
{ {
state = State.ATTACK; state = State.ATTACK;
timer = TurnBasedMinecraftMod.BattleDecisionTime; timer = TurnBasedMinecraftMod.BattleDecisionTime;
turnOrderQueue.clear();
for(Combatant c : sideA.values())
{
turnOrderQueue.add(c);
}
for(Combatant c : sideB.values())
{
turnOrderQueue.add(c);
}
update(Duration.ZERO); update(Duration.ZERO);
} }
break; break;
case ATTACK: case ATTACK:
// TODO Combatant next = turnOrderQueue.poll();
while(next != null)
{
// TODO attack per entity here
next = turnOrderQueue.poll();
}
break; break;
case HEALTH_CHECK: case HEALTH_CHECK:
// TODO // TODO

View file

@ -5,6 +5,7 @@ import java.util.Collection;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Map; import java.util.Map;
import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleEntered; import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleEntered;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler; import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
@ -36,6 +37,12 @@ public class BattleManager
*/ */
public boolean checkAttack(final LivingAttackEvent event) 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 // check if one is in battle
Entity inBattle = null; Entity inBattle = null;
Entity notInBattle = null; Entity notInBattle = null;

View file

@ -1,31 +1,126 @@
package com.seodisparate.TurnBasedMinecraft.common; package com.seodisparate.TurnBasedMinecraft.common;
import java.util.Comparator;
import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import net.minecraft.entity.Entity; 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 class Combatant
{ {
public Entity entity; public Entity entity;
public Battle.Decision decision; public Battle.Decision decision;
public int itemToUse; public int itemToUse;
public float speed; public EntityInfo entityInfo;
public boolean recalcSpeedOnCompare;
public int targetEntityID;
public Combatant() public Combatant()
{ {
decision = Battle.Decision.UNDECIDED; decision = Battle.Decision.UNDECIDED;
speed = 0.5f; recalcSpeedOnCompare = false;
} }
public Combatant(Entity e) public Combatant(Entity e, EntityInfo entityInfo)
{ {
entity = e; entity = e;
decision = Battle.Decision.UNDECIDED; 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; @Override
decision = Battle.Decision.UNDECIDED; public int compare(Combatant c0, Combatant c1)
this.speed = speed; {
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;
}
}
} }
} }

View file

@ -24,9 +24,12 @@ import com.seodisparate.TurnBasedMinecraft.common.EntityInfo.Category;
public class Config public class Config
{ {
private Map<Class, EntityInfo> entityInfoMap; private Map<String, EntityInfo> entityInfoMap;
private Set<EntityInfo.Category> ignoreBattleTypes; private Set<EntityInfo.Category> ignoreBattleTypes;
private Logger logger; private Logger logger;
private int playerSpeed;
private int playerHasteSpeed;
private int playerSlowSpeed;
private enum ConfigParseResult private enum ConfigParseResult
{ {
@ -36,7 +39,7 @@ public class Config
public Config(Logger logger) public Config(Logger logger)
{ {
entityInfoMap = new HashMap<Class, EntityInfo>(); entityInfoMap = new HashMap<String, EntityInfo>();
ignoreBattleTypes = new HashSet<EntityInfo.Category>(); ignoreBattleTypes = new HashSet<EntityInfo.Category>();
this.logger = logger; this.logger = logger;
@ -65,6 +68,7 @@ public class Config
ConfigParseResult result = parseConfig(configFile); ConfigParseResult result = parseConfig(configFile);
if(result == ConfigParseResult.IS_OLD) if(result == ConfigParseResult.IS_OLD)
{ {
logger.warn("Config file " + TurnBasedMinecraftMod.CONFIG_FILENAME + " is older version, renaming...");
moveOldConfig(); moveOldConfig();
writeConfig(); writeConfig();
ConfigParseResult resultSecond = parseConfig(configFile); ConfigParseResult resultSecond = parseConfig(configFile);
@ -109,8 +113,10 @@ public class Config
File configFile = new File(TurnBasedMinecraftMod.CONFIG_FILE_PATH); File configFile = new File(TurnBasedMinecraftMod.CONFIG_FILE_PATH);
if(configFile.exists()) if(configFile.exists())
{ {
configFile.renameTo(new File(TurnBasedMinecraftMod.CONFIG_DIRECTORY + "_" configFile.renameTo(new File(TurnBasedMinecraftMod.CONFIG_DIRECTORY
+ DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(Instant.now()))); + "TBM_Config_"
+ DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(Instant.now())
+ ".xml"));
} }
} }
@ -149,6 +155,28 @@ public class Config
} }
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("IgnoreBattleTypes"))); } 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")) else if(xmlReader.getLocalName().equals("EntityStats"))
{ {
do do
@ -179,6 +207,10 @@ public class Config
{ {
eInfo.attackProbability = Integer.parseInt(xmlReader.getAttributeValue(i)); 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()); eInfo.attackPower = Integer.parseInt(xmlReader.getElementText());
} }
@ -230,9 +262,20 @@ public class Config
} }
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("Conflicts"))); } 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))); } 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"))); } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("EntityStats")));
} }
@ -242,4 +285,51 @@ public class Config
fis.close(); fis.close();
return ConfigParseResult.SUCCESS; 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;
}
} }

View file

@ -1,19 +1,23 @@
package com.seodisparate.TurnBasedMinecraft.common; package com.seodisparate.TurnBasedMinecraft.common;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
public class EntityInfo public class EntityInfo
{ {
public Class classType; public Class classType;
public List<Class> conflictingTypes; public List<Class> conflictingTypes;
public boolean ignoreBattle;
public int attackPower; public int attackPower;
public int attackProbability; public int attackProbability;
public int attackVariance;
public Effect attackEffect; public Effect attackEffect;
public int attackEffectProbability; public int attackEffectProbability;
public int defenseDamage; public int defenseDamage;
public int defenseDamageProbability; public int defenseDamageProbability;
public int evasion; public int evasion;
public int speed;
public Category category; public Category category;
public enum Category public enum Category
@ -193,13 +197,16 @@ public class EntityInfo
{ {
classType = null; classType = null;
conflictingTypes = new ArrayList<Class>(); conflictingTypes = new ArrayList<Class>();
ignoreBattle = false;
attackPower = 0; attackPower = 0;
attackProbability = 70; attackProbability = 70;
attackVariance = 0;
attackEffect = Effect.UNKNOWN; attackEffect = Effect.UNKNOWN;
attackEffectProbability = 50; attackEffectProbability = 50;
defenseDamage = 0; defenseDamage = 0;
defenseDamageProbability = 0; defenseDamageProbability = 0;
evasion = 15; evasion = 15;
speed = 50;
category = Category.UNKNOWN; category = Category.UNKNOWN;
} }
@ -212,13 +219,16 @@ public class EntityInfo
{ {
newEntityInfo.conflictingTypes.add(c); newEntityInfo.conflictingTypes.add(c);
} }
newEntityInfo.ignoreBattle = ignoreBattle;
newEntityInfo.attackPower = attackPower; newEntityInfo.attackPower = attackPower;
newEntityInfo.attackProbability = attackProbability; newEntityInfo.attackProbability = attackProbability;
newEntityInfo.attackVariance = attackVariance;
newEntityInfo.attackEffect = attackEffect; newEntityInfo.attackEffect = attackEffect;
newEntityInfo.attackEffectProbability = attackEffectProbability; newEntityInfo.attackEffectProbability = attackEffectProbability;
newEntityInfo.defenseDamage = defenseDamage; newEntityInfo.defenseDamage = defenseDamage;
newEntityInfo.defenseDamageProbability = defenseDamageProbability; newEntityInfo.defenseDamageProbability = defenseDamageProbability;
newEntityInfo.evasion = evasion; newEntityInfo.evasion = evasion;
newEntityInfo.speed = speed;
newEntityInfo.category = category; newEntityInfo.category = category;
return newEntityInfo; return newEntityInfo;
} }

View file

@ -14,13 +14,15 @@ public class PacketBattleDecision implements IMessage
{ {
private int battleID; private int battleID;
private Battle.Decision decision; private Battle.Decision decision;
private int targetEntityID;
public PacketBattleDecision() {} public PacketBattleDecision() {}
public PacketBattleDecision(int battleID, Battle.Decision decision) public PacketBattleDecision(int battleID, Battle.Decision decision, int targetEntityID)
{ {
this.battleID = battleID; this.battleID = battleID;
this.decision = decision; this.decision = decision;
this.targetEntityID = targetEntityID;
} }
@Override @Override
@ -28,6 +30,7 @@ public class PacketBattleDecision implements IMessage
{ {
battleID = buf.readInt(); battleID = buf.readInt();
decision = Decision.valueOf(buf.readInt()); decision = Decision.valueOf(buf.readInt());
targetEntityID = buf.readInt();
} }
@Override @Override
@ -35,6 +38,7 @@ public class PacketBattleDecision implements IMessage
{ {
buf.writeInt(battleID); buf.writeInt(battleID);
buf.writeInt(decision.getValue()); buf.writeInt(decision.getValue());
buf.writeInt(targetEntityID);
} }
public static class HandleBattleDecision implements IMessageHandler<PacketBattleDecision, IMessage> public static class HandleBattleDecision implements IMessageHandler<PacketBattleDecision, IMessage>
@ -46,7 +50,7 @@ public class PacketBattleDecision implements IMessage
if(b != null) if(b != null)
{ {
EntityPlayerMP player = ctx.getServerHandler().player; EntityPlayerMP player = ctx.getServerHandler().player;
b.setDecision(player.getEntityId(), message.decision); b.setDecision(player.getEntityId(), message.decision, message.targetEntityID);
} }
return null; return null;
} }

View file

@ -1,116 +1,152 @@
<TurnBasedMinecraftConfig> <TurnBasedMinecraftConfig>
<!-- If the mod has a newer version config, it will rename the existing config and place the new config -->
<Version>1</Version> <Version>1</Version>
<!-- Types that will not initiate battle with player. They are listed as "Category" per EntiytStats entity. -->
<IgnoreBattleTypes> <IgnoreBattleTypes>
<Passive></Passive> <Passive></Passive>
<Boss></Boss> <Boss></Boss>
</IgnoreBattleTypes> </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> <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> <net.minecraft.entity.monster.EntityBlaze>
<AttackPower Probability="50">5</AttackPower> <AttackPower Probability="50">5</AttackPower>
<AttackEffect Probability="75">fire</AttackEffect> <AttackEffect Probability="75">fire</AttackEffect>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>45</Speed>
</net.minecraft.entity.monster.EntityBlaze> </net.minecraft.entity.monster.EntityBlaze>
<net.minecraft.entity.monster.EntityCaveSpider> <net.minecraft.entity.monster.EntityCaveSpider>
<AttackPower Probability="75">2</AttackPower> <AttackPower Probability="75">2</AttackPower>
<AttackEffect Probability="90">poison</AttackEffect> <AttackEffect Probability="90">poison</AttackEffect>
<Evasion>35</Evasion> <Evasion>35</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>75</Speed>
</net.minecraft.entity.monster.EntityCaveSpider> </net.minecraft.entity.monster.EntityCaveSpider>
<net.minecraft.entity.monster.EntityCreeper> <net.minecraft.entity.monster.EntityCreeper>
<IgnoreBattle>true</IgnoreBattle> <IgnoreBattle>true</IgnoreBattle>
<AttackPower Probability="17" Variance="7">15</AttackPower> <AttackPower Probability="17" Variance="7">15</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>25</Speed>
</net.minecraft.entity.monster.EntityCreeper> </net.minecraft.entity.monster.EntityCreeper>
<net.minecraft.entity.monster.EntityElderGuardian> <net.minecraft.entity.monster.EntityElderGuardian>
<AttackPower Probability="65">8</AttackPower> <AttackPower Probability="65">8</AttackPower>
<DefenseDamage Probability="35">2</DefenseDamage> <DefenseDamage Probability="35">2</DefenseDamage>
<Evasion>25</Evasion> <Evasion>25</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>45</Speed>
</net.minecraft.entity.monster.EntityElderGuardian> </net.minecraft.entity.monster.EntityElderGuardian>
<net.minecraft.entity.monster.EntityEnderman> <net.minecraft.entity.monster.EntityEnderman>
<AttackPower Probability="80">7</AttackPower> <AttackPower Probability="80">7</AttackPower>
<Evasion>40</Evasion> <Evasion>40</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>70</Speed>
</net.minecraft.entity.monster.EntityEnderman> </net.minecraft.entity.monster.EntityEnderman>
<net.minecraft.entity.monster.EntityEndermite> <net.minecraft.entity.monster.EntityEndermite>
<AttackPower Probability="80">2</AttackPower> <AttackPower Probability="80">2</AttackPower>
<Evasion>40</Evasion> <Evasion>40</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntityEndermite> </net.minecraft.entity.monster.EntityEndermite>
<net.minecraft.entity.monster.EntityEvoker> <net.minecraft.entity.monster.EntityEvoker>
<AttackPower Probability="60">6</AttackPower> <AttackPower Probability="60">6</AttackPower>
<Evasion>35</Evasion> <Evasion>35</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntityEvoker> </net.minecraft.entity.monster.EntityEvoker>
<net.minecraft.entity.monster.EntityGhast> <net.minecraft.entity.monster.EntityGhast>
<IgnoreBattle>true</IgnoreBattle> <IgnoreBattle>true</IgnoreBattle>
<AttackPower Probability="20">13</AttackPower> <AttackPower Probability="20">13</AttackPower>
<Evasion>35</Evasion> <Evasion>35</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>60</Speed>
</net.minecraft.entity.monster.EntityGhast> </net.minecraft.entity.monster.EntityGhast>
<net.minecraft.entity.monster.EntityGiantZombie> <net.minecraft.entity.monster.EntityGiantZombie>
<AttackPower Probability="35">11</AttackPower> <AttackPower Probability="35">11</AttackPower>
<Evasion>2</Evasion> <Evasion>2</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>45</Speed>
</net.minecraft.entity.monster.EntityGiantZombie> </net.minecraft.entity.monster.EntityGiantZombie>
<net.minecraft.entity.monster.EntityGuardian> <net.minecraft.entity.monster.EntityGuardian>
<AttackPower Probability="55">6</AttackPower> <AttackPower Probability="55">6</AttackPower>
<DefenseDamage Probability="30">2</DefenseDamage> <DefenseDamage Probability="30">2</DefenseDamage>
<Evasion>25</Evasion> <Evasion>25</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>50</Speed>
</net.minecraft.entity.monster.EntityGuardian> </net.minecraft.entity.monster.EntityGuardian>
<net.minecraft.entity.monster.EntityHusk> <net.minecraft.entity.monster.EntityHusk>
<AttackPower Probability="70">3</AttackPower> <AttackPower Probability="70">3</AttackPower>
<AttackEffect Probability="95">hunger</AttackEffect> <AttackEffect Probability="95">hunger</AttackEffect>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>25</Speed>
</net.minecraft.entity.monster.EntityHusk> </net.minecraft.entity.monster.EntityHusk>
<net.minecraft.entity.monster.EntityIronGolem> <net.minecraft.entity.monster.EntityIronGolem>
<AttackPower Probability="85" Variance="7">14</AttackPower> <AttackPower Probability="85" Variance="7">14</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>45</Speed>
</net.minecraft.entity.monster.EntityIronGolem> </net.minecraft.entity.monster.EntityIronGolem>
<net.minecraft.entity.monster.EntityMagmaCube> <net.minecraft.entity.monster.EntityMagmaCube>
<AttackPower Probability="35">3</AttackPower> <AttackPower Probability="35">3</AttackPower>
<Evasion>12</Evasion> <Evasion>12</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntityMagmaCube> </net.minecraft.entity.monster.EntityMagmaCube>
<net.minecraft.entity.monster.EntityPigZombie> <net.minecraft.entity.monster.EntityPigZombie>
<AttackPower Probability="70">8</AttackPower> <AttackPower Probability="70">8</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>50</Speed>
</net.minecraft.entity.monster.EntityPigZombie> </net.minecraft.entity.monster.EntityPigZombie>
<net.minecraft.entity.monster.EntityPolarBear> <net.minecraft.entity.monster.EntityPolarBear>
<AttackPower Probability="67">6</AttackPower> <AttackPower Probability="67">6</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>animal</Category> <Category>animal</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntityPolarBear> </net.minecraft.entity.monster.EntityPolarBear>
<net.minecraft.entity.monster.EntityShulker> <net.minecraft.entity.monster.EntityShulker>
<AttackPower Probability="80">4</AttackPower> <AttackPower Probability="80">4</AttackPower>
<Evasion>15</Evasion> <Evasion>15</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>10</Speed>
</net.minecraft.entity.monster.EntityShulker> </net.minecraft.entity.monster.EntityShulker>
<net.minecraft.entity.monster.EntitySilverFish> <net.minecraft.entity.monster.EntitySilverFish>
<AttackPower Probability="85">1</AttackPower> <AttackPower Probability="85">1</AttackPower>
<Evasion>37</Evasion> <Evasion>37</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntitySilverFish> </net.minecraft.entity.monster.EntitySilverFish>
<net.minecraft.entity.monster.EntitySkeleton> <net.minecraft.entity.monster.EntitySkeleton>
<AttackPower Probability="75" Variance="1">3</AttackPower> <AttackPower Probability="75" Variance="1">3</AttackPower>
<Evasion>13</Evasion> <Evasion>13</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>30</Speed>
</net.minecraft.entity.monster.EntitySkeleton> </net.minecraft.entity.monster.EntitySkeleton>
<net.minecraft.entity.monster.EntitySlime> <net.minecraft.entity.monster.EntitySlime>
<AttackPower Probability="35">2</AttackPower> <AttackPower Probability="35">2</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>30</Speed>
</net.minecraft.entity.monster.EntitySlime> </net.minecraft.entity.monster.EntitySlime>
<net.minecraft.entity.monster.EntitySnowman> <net.minecraft.entity.monster.EntitySnowman>
<AttackPower Probability="80">0</AttackPower> <AttackPower Probability="80">0</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>60</Speed>
</net.minecraft.entity.monster.EntitySnowman> </net.minecraft.entity.monster.EntitySnowman>
<net.minecraft.entity.monster.EntitySpider> <net.minecraft.entity.monster.EntitySpider>
<AttackPower Probability="70">2</AttackPower> <AttackPower Probability="70">2</AttackPower>
@ -119,33 +155,39 @@
<net.minecraft.entity.monster.EntityCaveSpider></net.minecraft.entity.monster.EntityCaveSpider> <net.minecraft.entity.monster.EntityCaveSpider></net.minecraft.entity.monster.EntityCaveSpider>
</Conflicts> </Conflicts>
<Category>monster</Category> <Category>monster</Category>
<Speed>70</Speed>
</net.minecraft.entity.monster.EntitySpider> </net.minecraft.entity.monster.EntitySpider>
<net.minecraft.entity.monster.EntityStray> <net.minecraft.entity.monster.EntityStray>
<AttackPower Probability="75" Variance="1">3</AttackPower> <AttackPower Probability="75" Variance="1">3</AttackPower>
<AttackEffect Probability="90">slow</AttackEffect> <AttackEffect Probability="90">slow</AttackEffect>
<Evasion>13</Evasion> <Evasion>13</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>30</Speed>
</net.minecraft.entity.monster.EntityStray> </net.minecraft.entity.monster.EntityStray>
<net.minecraft.entity.monster.EntityVex> <net.minecraft.entity.monster.EntityVex>
<AttackPower Probability="65">9</AttackPower> <AttackPower Probability="65">9</AttackPower>
<Evasion>30</Evasion> <Evasion>30</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>80</Speed>
</net.minecraft.entity.monster.EntityVex> </net.minecraft.entity.monster.EntityVex>
<net.minecraft.entity.monster.EntityVindicator> <net.minecraft.entity.monster.EntityVindicator>
<AttackPower Probability="70">13</AttackPower> <AttackPower Probability="70">13</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntityVindicator> </net.minecraft.entity.monster.EntityVindicator>
<net.minecraft.entity.monster.EntityWitch> <net.minecraft.entity.monster.EntityWitch>
<AttackPower Probability="75" Variance="1">5</AttackPower> <AttackPower Probability="75" Variance="1">5</AttackPower>
<Evasion>8</Evasion> <Evasion>8</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>35</Speed>
</net.minecraft.entity.monster.EntityWitch> </net.minecraft.entity.monster.EntityWitch>
<net.minecraft.entity.monster.EntityWitherSkeleton> <net.minecraft.entity.monster.EntityWitherSkeleton>
<AttackPower Probability="70">8</AttackPower> <AttackPower Probability="70">8</AttackPower>
<AttackEffect Probability="90">wither</AttackEffect> <AttackEffect Probability="90">wither</AttackEffect>
<Evasion>7</Evasion> <Evasion>7</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>65</Speed>
</net.minecraft.entity.monster.EntityWitherSkeleton> </net.minecraft.entity.monster.EntityWitherSkeleton>
<net.minecraft.entity.monster.EntityZombie> <net.minecraft.entity.monster.EntityZombie>
<AttackPower Probability="70">3</AttackPower> <AttackPower Probability="70">3</AttackPower>
@ -155,21 +197,25 @@
</Conflicts> </Conflicts>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>25</Speed>
</net.minecraft.entity.monster.EntityZombie> </net.minecraft.entity.monster.EntityZombie>
<net.minecraft.entity.monster.EntityZombieVillager> <net.minecraft.entity.monster.EntityZombieVillager>
<AttackPower Probability="70">3</AttackPower> <AttackPower Probability="70">3</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>monster</Category> <Category>monster</Category>
<Speed>25</Speed>
</net.minecraft.entity.monster.EntityZombieVillager> </net.minecraft.entity.monster.EntityZombieVillager>
<net.minecraft.entity.passive.EntityBat> <net.minecraft.entity.passive.EntityBat>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion> <Evasion>35</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>75</Speed>
</net.minecraft.entity.passive.EntityBat> </net.minecraft.entity.passive.EntityBat>
<net.minecraft.entity.passive.EntityChicken> <net.minecraft.entity.passive.EntityChicken>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>35</Speed>
</net.minecraft.entity.passive.EntityChicken> </net.minecraft.entity.passive.EntityChicken>
<net.minecraft.entity.passive.EntityCow> <net.minecraft.entity.passive.EntityCow>
<AttackPower Probability="50">0</AttackPower> <AttackPower Probability="50">0</AttackPower>
@ -178,92 +224,110 @@
<net.minecraft.entity.passive.EntityMooshroom></net.minecraft.entity.passive.EntityMooshroom> <net.minecraft.entity.passive.EntityMooshroom></net.minecraft.entity.passive.EntityMooshroom>
</Conflicts> </Conflicts>
<Category>passive</Category> <Category>passive</Category>
<Speed>20</Speed>
</net.minecraft.entity.passive.EntityCow> </net.minecraft.entity.passive.EntityCow>
<net.minecraft.entity.passive.EntityDonkey> <net.minecraft.entity.passive.EntityDonkey>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>65</Speed>
</net.minecraft.entity.passive.EntityDonkey> </net.minecraft.entity.passive.EntityDonkey>
<net.minecraft.entity.passive.EntityHorse> <net.minecraft.entity.passive.EntityHorse>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>65</Speed>
</net.minecraft.entity.passive.EntityHorse> </net.minecraft.entity.passive.EntityHorse>
<net.minecraft.entity.passive.EntityLlama> <net.minecraft.entity.passive.EntityLlama>
<AttackPower Probability="70">1</AttackPower> <AttackPower Probability="70">1</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>50</Speed>
</net.minecraft.entity.passive.EntityLlama> </net.minecraft.entity.passive.EntityLlama>
<net.minecraft.entity.passive.EntityMooshroom> <net.minecraft.entity.passive.EntityMooshroom>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>1</Evasion> <Evasion>1</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>20</Speed>
</net.minecraft.entity.passive.EntityMooshroom> </net.minecraft.entity.passive.EntityMooshroom>
<net.minecraft.entity.passive.EntityMule> <net.minecraft.entity.passive.EntityMule>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>50</Speed>
</net.minecraft.entity.passive.EntityMule> </net.minecraft.entity.passive.EntityMule>
<net.minecraft.entity.passive.EntityOcelot> <net.minecraft.entity.passive.EntityOcelot>
<AttackPower Probability="70" Variance="1">1</AttackPower> <AttackPower Probability="70" Variance="1">1</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>75</Speed>
</net.minecraft.entity.passive.EntityOcelot> </net.minecraft.entity.passive.EntityOcelot>
<net.minecraft.entity.passive.EntityParrot> <net.minecraft.entity.passive.EntityParrot>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion> <Evasion>35</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>70</Speed>
</net.minecraft.entity.passive.EntityParrot> </net.minecraft.entity.passive.EntityParrot>
<net.minecraft.entity.passive.EntityPig> <net.minecraft.entity.passive.EntityPig>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion> <Evasion>10</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>30</Speed>
</net.minecraft.entity.passive.EntityPig> </net.minecraft.entity.passive.EntityPig>
<net.minecraft.entity.passive.EntityRabbit> <net.minecraft.entity.passive.EntityRabbit>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>40</Evasion> <Evasion>40</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>75</Speed>
</net.minecraft.entity.passive.EntityRabbit> </net.minecraft.entity.passive.EntityRabbit>
<net.minecraft.entity.passive.EntitySheep> <net.minecraft.entity.passive.EntitySheep>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>30</Speed>
</net.minecraft.entity.passive.EntitySheep> </net.minecraft.entity.passive.EntitySheep>
<net.minecraft.entity.passive.EntitySkeletonHorse> <net.minecraft.entity.passive.EntitySkeletonHorse>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>65</Speed>
</net.minecraft.entity.passive.EntitySkeletonHorse> </net.minecraft.entity.passive.EntitySkeletonHorse>
<net.minecraft.entity.passive.EntitySquid> <net.minecraft.entity.passive.EntitySquid>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>15</Evasion> <Evasion>15</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>40</Speed>
</net.minecraft.entity.passive.EntitySquid> </net.minecraft.entity.passive.EntitySquid>
<net.minecraft.entity.passive.EntityVillager> <net.minecraft.entity.passive.EntityVillager>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion> <Evasion>5</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>35</Speed>
</net.minecraft.entity.passive.EntityVillager> </net.minecraft.entity.passive.EntityVillager>
<net.minecraft.entity.passive.EntityWolf> <net.minecraft.entity.passive.EntityWolf>
<AttackPower Probability="70">4</AttackPower> <AttackPower Probability="70">4</AttackPower>
<Evasion>20</Evasion> <Evasion>20</Evasion>
<Category>animal</Category> <Category>animal</Category>
<Speed>70</Speed>
</net.minecraft.entity.passive.EntityWolf> </net.minecraft.entity.passive.EntityWolf>
<net.minecraft.entity.passive.EntityZombieHorse> <net.minecraft.entity.passive.EntityZombieHorse>
<AttackPower Probability="70">0</AttackPower> <AttackPower Probability="70">0</AttackPower>
<Evasion>8</Evasion> <Evasion>8</Evasion>
<Category>passive</Category> <Category>passive</Category>
<Speed>65</Speed>
</net.minecraft.entity.passive.EntityZombieHorse> </net.minecraft.entity.passive.EntityZombieHorse>
<net.minecraft.entity.boss.EntityDragon> <net.minecraft.entity.boss.EntityDragon>
<AttackPower Probability="70" Variance="2">10</AttackPower> <AttackPower Probability="70" Variance="2">10</AttackPower>
<Evasion>27</Evasion> <Evasion>27</Evasion>
<Category>boss</Category> <Category>boss</Category>
<Speed>63</Speed>
</net.minecraft.entity.boss.EntityDragon> </net.minecraft.entity.boss.EntityDragon>
<net.minecraft.entity.boss.EntityWither> <net.minecraft.entity.boss.EntityWither>
<AttackPower Probability="70">8</AttackPower> <AttackPower Probability="70">8</AttackPower>
<Evasion>20</Evasion> <Evasion>20</Evasion>
<AttackEffect Probability="90">wither</AttackEffect> <AttackEffect Probability="90">wither</AttackEffect>
<Category>boss</Category> <Category>boss</Category>
<Speed>68</Speed>
</net.minecraft.entity.boss.EntityWither> </net.minecraft.entity.boss.EntityWither>
</EntityStats> </EntityStats>
</TurnBasedMinecraftConfig> </TurnBasedMinecraftConfig>