import com.seodisparate.TurnBasedMinecraft.common.BattleManager;
import com.seodisparate.TurnBasedMinecraft.common.Config;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleDecision;
-import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleEntered;
-import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleExited;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo;
+import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleRequestInfo;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
private static BattleManager battleManager;
private static int packetHandlerID = 0;
public static Entity attackingEntity;
+ public static int attackingDamage = 0;
public static Config config;
public static Battle currentBattle;
}
// register packets
- PacketHandler.INSTANCE.registerMessage(
- PacketBattleEntered.HandlerBattleEntered.class,
- PacketBattleEntered.class,
- packetHandlerID++,
- Side.CLIENT);
- PacketHandler.INSTANCE.registerMessage(
- PacketBattleExited.HandlerBattleExited.class,
- PacketBattleExited.class,
- packetHandlerID++,
- Side.CLIENT);
PacketHandler.INSTANCE.registerMessage(
PacketBattleInfo.HandlerBattleInfo.class,
PacketBattleInfo.class,
PacketBattleDecision.class,
packetHandlerID++,
Side.SERVER);
+ PacketHandler.INSTANCE.registerMessage(
+ PacketBattleMessage.HandlerBattleMessage.class,
+ PacketBattleMessage.class,
+ packetHandlerID++,
+ Side.CLIENT);
}
@EventHandler
logger.debug("Canceled LivingAttackEvent between " + attackingEntity + " and " + event.getEntity());
event.setCanceled(true);
}
+ attackingDamage = (int) event.getAmount();
}
public static BattleManager getBattleManager()
import java.time.Duration;
import java.time.Instant;
+import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Collection;
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.Queue;
import java.util.concurrent.atomic.AtomicInteger;
import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleInfo;
+import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleMessage;
import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
import net.minecraft.entity.Entity;
private AtomicInteger undecidedCount;
private Duration timer;
+ private boolean isServer;
+ private boolean battleEnded;
+
public enum State
{
DECISION,
}
}
- public Battle(int id, Collection<Entity> sideA, Collection<Entity> sideB)
+ public Battle(int id, Collection<Entity> sideA, Collection<Entity> sideB, boolean isServer)
{
+ this.isServer = isServer;
this.id = id;
this.sideA = new Hashtable<Integer, Combatant>();
this.sideB = new Hashtable<Integer, Combatant>();
}
}
+ for(Combatant c : this.sideA.values())
+ {
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ENTERED, c.entity.getEntityId(), 0, id);
+ }
+ for(Combatant c : this.sideB.values())
+ {
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ENTERED, c.entity.getEntityId(), 0, id);
+ }
+
lastUpdated = null;
state = State.DECISION;
undecidedCount.set(playerCount.get());
timer = TurnBasedMinecraftMod.BattleDecisionTime;
+ battleEnded = false;
+
+ notifyPlayersBattleInfo();
}
public int getId()
return id;
}
+ public Entity getCombatantEntity(int entityID)
+ {
+ Combatant c = sideA.get(entityID);
+ if(c != null)
+ {
+ return c.entity;
+ }
+ c = sideB.get(entityID);
+ if(c != null)
+ {
+ return c.entity;
+ }
+ return null;
+ }
+
public boolean hasCombatant(int entityID)
{
return sideA.containsKey(entityID) || sideB.containsKey(entityID);
undecidedCount.incrementAndGet();
}
}
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ENTERED, newCombatant.entity.getEntityId(), 0, id);
+ notifyPlayersBattleInfo();
}
public void addCombatantToSideB(Entity e)
undecidedCount.incrementAndGet();
}
}
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ENTERED, newCombatant.entity.getEntityId(), 0, id);
+ notifyPlayersBattleInfo();
}
public void clearCombatants()
return state;
}
- public void notifyPlayersBattleInfo()
+ protected void notifyPlayersBattleInfo()
{
- if(TurnBasedMinecraftMod.getBattleManager() == null)
+ if(!isServer)
{
return;
}
}
}
- public void update()
+ /**
+ * @return True if battle has ended
+ */
+ public boolean update()
{
+ if(battleEnded)
+ {
+ return true;
+ }
if(lastUpdated == null)
{
lastUpdated = Instant.now();
- update(Duration.ZERO);
+ return update(Duration.ZERO);
}
else
{
Instant now = Instant.now();
- update(Duration.between(lastUpdated, now));
+ Duration dt = Duration.between(lastUpdated, now);
lastUpdated = now;
+ return update(dt);
}
}
- private void update(final Duration dt)
+ private void sendMessageToAllPlayers(PacketBattleMessage.MessageType type, int from, int to, int amount)
{
+ if(!isServer)
+ {
+ return;
+ }
+ for(Combatant p : players.values())
+ {
+ if(p.entity.isEntityAlive())
+ {
+ PacketHandler.INSTANCE.sendTo(new PacketBattleMessage(type, from, to, amount), (EntityPlayerMP)p.entity);
+ }
+ }
+ }
+
+ private boolean update(final Duration dt)
+ {
+ if(battleEnded)
+ {
+ return true;
+ }
switch(state)
{
case DECISION:
timer = timer.minus(dt);
if(timer.isNegative() || timer.isZero() || undecidedCount.get() <= 0)
{
+ for(Combatant c : sideA.values())
+ {
+ // picking decision for sideA non-players
+ if(!(c.entity instanceof EntityPlayer) && c.decision == Decision.UNDECIDED && c.entityInfo != null)
+ {
+ int percentage = (int)(Math.random() * 100);
+ if(percentage < c.entityInfo.decisionAttack)
+ {
+ c.decision = Decision.ATTACK;
+ }
+ else if(percentage - c.entityInfo.decisionAttack < c.entityInfo.decisionDefend)
+ {
+ c.decision = Decision.DEFEND;
+ }
+ else if(percentage - c.entityInfo.decisionAttack - c.entityInfo.decisionDefend < c.entityInfo.decisionFlee)
+ {
+ c.decision = Decision.FLEE;
+ }
+ }
+ }
+ for(Combatant c : sideB.values())
+ {
+ if(!(c.entity instanceof EntityPlayer) && c.decision == Decision.UNDECIDED && c.entityInfo != null)
+ {
+ int percentage = (int)(Math.random() * 100);
+ if(percentage < c.entityInfo.decisionAttack)
+ {
+ c.decision = Decision.ATTACK;
+ }
+ else if(percentage - c.entityInfo.decisionAttack < c.entityInfo.decisionDefend)
+ {
+ c.decision = Decision.DEFEND;
+ }
+ else if(percentage - c.entityInfo.decisionAttack - c.entityInfo.decisionDefend < c.entityInfo.decisionFlee)
+ {
+ c.decision = Decision.FLEE;
+ }
+ }
+ }
state = State.ACTION;
timer = TurnBasedMinecraftMod.BattleDecisionTime;
turnOrderQueue.clear();
turnOrderQueue.add(c);
}
update(Duration.ZERO);
- // TODO assign decisions to non-players
}
break;
case ACTION:
switch(next.decision)
{
case UNDECIDED:
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DID_NOTHING, next.entity.getEntityId(), 0, 0);
next = turnOrderQueue.poll();
continue;
case ATTACK:
TurnBasedMinecraftMod.attackingEntity = next.entity;
((EntityPlayer)next.entity).attackTargetEntityWithCurrentItem(target.entity);
TurnBasedMinecraftMod.attackingEntity = null;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ATTACK, next.entity.getEntityId(), target.entity.getEntityId(), TurnBasedMinecraftMod.attackingDamage);
if(!(target.entity instanceof EntityPlayer) && target.entityInfo.defenseDamage > 0)
{
if((int)(Math.random() * 100) < target.entityInfo.defenseDamageProbability)
TurnBasedMinecraftMod.attackingEntity = target.entity;
next.entity.attackEntityFrom(defenseDamageSource, target.entityInfo.defenseDamage);
TurnBasedMinecraftMod.attackingEntity = null;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DEFENSE_DAMAGE, target.entity.getEntityId(), next.entity.getEntityId(), target.entityInfo.defenseDamage);
}
}
}
{
// blocked
--target.remainingDefenses;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DEFEND, target.entity.getEntityId(), next.entity.getEntityId(), 0);
}
}
else
{
// miss
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.MISS, next.entity.getEntityId(), target.entity.getEntityId(), 0);
}
}
else
}
// attack
TurnBasedMinecraftMod.attackingEntity = next.entity;
- target.entity.attackEntityFrom(damageSource, next.entityInfo.attackPower);
+ target.entity.attackEntityFrom(damageSource, damageAmount);
TurnBasedMinecraftMod.attackingEntity = null;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ATTACK, next.entity.getEntityId(), target.entity.getEntityId(), damageAmount);
if(!(target.entity instanceof EntityPlayer) && target.entityInfo.defenseDamage > 0)
{
if((int)(Math.random() * 100) < target.entityInfo.defenseDamageProbability)
TurnBasedMinecraftMod.attackingEntity = target.entity;
next.entity.attackEntityFrom(defenseDamageSource, target.entityInfo.defenseDamage);
TurnBasedMinecraftMod.attackingEntity = null;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DEFENSE_DAMAGE, target.entity.getEntityId(), next.entity.getEntityId(), target.entityInfo.defenseDamage);
}
}
}
{
// blocked
--target.remainingDefenses;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DEFEND, target.entity.getEntityId(), next.entity.getEntityId(), 0);
}
}
else
{
// miss
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.MISS, next.entity.getEntityId(), target.entity.getEntityId(), 0);
}
}
break;
case DEFEND:
next.remainingDefenses = TurnBasedMinecraftMod.config.getDefenseDuration();
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DEFENDING, next.entity.getEntityId(), 0, 0);
break;
case FLEE:
int fastestEnemySpeed = 0;
{
sideB.remove(next.entity.getEntityId());
}
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.FLEE, next.entity.getEntityId(), 0, 1);
if(next.entity instanceof EntityPlayer)
{
players.remove(next.entity.getEntityId());
playerCount.decrementAndGet();
- // TODO notify player exited battle
+ PacketHandler.INSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, 0, 0, 0), (EntityPlayerMP)next.entity);
}
}
+ else
+ {
+ // flee fail
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.FLEE, next.entity.getEntityId(), 0, 0);
+ }
break;
case USE_ITEM:
break;
break;
}
case HEALTH_CHECK:
- // TODO
+ Queue<Integer> removeQueue = new ArrayDeque<Integer>();
+ for(Combatant c : sideA.values())
+ {
+ if(!c.entity.isEntityAlive())
+ {
+ removeQueue.add(c.entity.getEntityId());
+ if(c.entity instanceof EntityPlayer)
+ {
+ PacketHandler.INSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, c.entity.getEntityId(), 0, 0), (EntityPlayerMP)c.entity);
+ }
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DIED, c.entity.getEntityId(), 0, 0);
+ }
+ }
+ for(Combatant c : sideB.values())
+ {
+ if(!c.entity.isEntityAlive())
+ {
+ removeQueue.add(c.entity.getEntityId());
+ if(c.entity instanceof EntityPlayer)
+ {
+ PacketHandler.INSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, c.entity.getEntityId(), 0, 0), (EntityPlayerMP)c.entity);
+ }
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.DIED, c.entity.getEntityId(), 0, 0);
+ }
+ }
+ boolean didRemove = !removeQueue.isEmpty();
+ Integer toRemove = removeQueue.poll();
+ while(toRemove != null)
+ {
+ sideA.remove(toRemove);
+ sideB.remove(toRemove);
+ if(players.remove(toRemove) != null)
+ {
+ playerCount.decrementAndGet();
+ }
+ toRemove = removeQueue.poll();
+ }
+ if(players.isEmpty() || sideA.isEmpty() || sideB.isEmpty())
+ {
+ battleEnded = true;
+ sendMessageToAllPlayers(PacketBattleMessage.MessageType.ENDED, 0, 0, 0);
+ }
+ else if(didRemove)
+ {
+ notifyPlayersBattleInfo();
+ }
+ state = State.DECISION;
+ undecidedCount.set(playerCount.get());
+ timer = TurnBasedMinecraftMod.BattleDecisionTime;
break;
}
+ return battleEnded;
}
}
import java.util.Map;
import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
-import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleEntered;
-import com.seodisparate.TurnBasedMinecraft.common.networking.PacketHandler;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraftforge.event.entity.living.LivingAttackEvent;
public class BattleManager
{
battle.addCombatantToSideA(notInBattle);
}
-
- if(notInBattle instanceof EntityPlayerMP)
- {
- PacketHandler.INSTANCE.sendTo(new PacketBattleEntered(IDCounter), (EntityPlayerMP)notInBattle);
- }
-
- battle.notifyPlayersBattleInfo();
+
return true;
}
{
++IDCounter;
}
- Battle newBattle = new Battle(IDCounter, sideA, sideB);
+ Battle newBattle = new Battle(IDCounter, sideA, sideB, true);
battleMap.put(IDCounter, newBattle);
- for(Entity e : sideA)
- {
- if(e instanceof EntityPlayerMP)
- {
- PacketHandler.INSTANCE.sendTo(new PacketBattleEntered(IDCounter), (EntityPlayerMP)e);
- }
- }
- for(Entity e : sideB)
- {
- if(e instanceof EntityPlayerMP)
- {
- PacketHandler.INSTANCE.sendTo(new PacketBattleEntered(IDCounter), (EntityPlayerMP)e);
- }
- }
newBattle.notifyPlayersBattleInfo();
return newBattle;
}
package com.seodisparate.TurnBasedMinecraft.common;
+import java.util.ArrayDeque;
+import java.util.Queue;
+
public class BattleUpdater implements Runnable
{
private BattleManager manager;
@Override
public void run()
{
+ Queue<Integer> endedQueue = new ArrayDeque<Integer>();
+ Integer ended;
while(isRunning)
{
for(Battle e : manager.battleMap.values())
{
- e.update();
+ if(e.update())
+ {
+ endedQueue.add(e.getId());
+ }
+ }
+ ended = endedQueue.poll();
+ while(ended != null)
+ {
+ manager.battleMap.remove(ended);
+ ended = endedQueue.poll();
}
try { Thread.sleep(250); } catch (Exception e) { /* ignored */ }
}
private Map<String, EntityInfo> entityInfoMap;
private Set<EntityInfo.Category> ignoreBattleTypes;
private Logger logger;
- private int playerSpeed;
- private int playerHasteSpeed;
- private int playerSlowSpeed;
+ private int playerSpeed = 50;
+ private int playerHasteSpeed = 80;
+ private int playerSlowSpeed = 20;
private int playerAttackProbability = 100;
private int playerEvasion = 10;
private int defenseDuration = 1;
{
eInfo.speed = Integer.parseInt(xmlReader.getElementText());
}
+ else if(xmlReader.getLocalName().equals("Decision"))
+ {
+ do
+ {
+ xmlReader.next();
+ if(xmlReader.isStartElement())
+ {
+ if(xmlReader.getLocalName().equals("Attack"))
+ {
+ eInfo.decisionAttack = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("Defend"))
+ {
+ eInfo.decisionDefend = Integer.parseInt(xmlReader.getElementText());
+ }
+ else if(xmlReader.getLocalName().equals("Flee"))
+ {
+ eInfo.decisionFlee = Integer.parseInt(xmlReader.getElementText());
+ }
+ }
+ } while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals("Decision")));
+ }
}
} while(!(xmlReader.isEndElement() && xmlReader.getLocalName().equals(classType)));
entityInfoMap.put(eInfo.classType.getName(), eInfo);
protected EntityInfo getMatchingEntityInfo(Object entity)
{
+ if(entity == null)
+ {
+ return null;
+ }
EntityInfo matching = entityInfoMap.get(entity.getClass().getName());
if(matching.classType.isInstance(entity))
{
public int evasion;
public int speed;
public Category category;
+ public int decisionAttack;
+ public int decisionDefend;
+ public int decisionFlee;
public enum Category
{
evasion = 15;
speed = 50;
category = Category.UNKNOWN;
+ decisionAttack = 70;
+ decisionDefend = 20;
+ decisionFlee = 10;
}
public EntityInfo clone()
newEntityInfo.evasion = evasion;
newEntityInfo.speed = speed;
newEntityInfo.category = category;
+ newEntityInfo.decisionAttack = decisionAttack;
+ newEntityInfo.decisionDefend = decisionDefend;
+ newEntityInfo.decisionFlee = decisionFlee;
return newEntityInfo;
}
}
+++ /dev/null
-package com.seodisparate.TurnBasedMinecraft.common.networking;
-
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
-import com.seodisparate.TurnBasedMinecraft.common.Battle;
-
-import io.netty.buffer.ByteBuf;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
-import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
-
-public class PacketBattleEntered implements IMessage
-{
- private int battleID;
-
- public PacketBattleEntered() {}
-
- public PacketBattleEntered(int battleID)
- {
- this.battleID = battleID;
- }
-
- @Override
- public void fromBytes(ByteBuf buf)
- {
- battleID = buf.readInt();
- }
-
- @Override
- public void toBytes(ByteBuf buf)
- {
- buf.writeInt(battleID);
- }
-
- public static class HandlerBattleEntered implements IMessageHandler<PacketBattleEntered, IMessage>
- {
- @Override
- public IMessage onMessage(PacketBattleEntered message, MessageContext ctx)
- {
- TurnBasedMinecraftMod.currentBattle = new Battle(message.battleID, null, null);
- return null;
- }
- }
-}
+++ /dev/null
-package com.seodisparate.TurnBasedMinecraft.common.networking;
-
-import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
-
-import io.netty.buffer.ByteBuf;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
-import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
-
-public class PacketBattleExited implements IMessage
-{
- @Override
- public void fromBytes(ByteBuf buf)
- {
- }
-
- @Override
- public void toBytes(ByteBuf buf)
- {
- }
-
- public static class HandlerBattleExited implements IMessageHandler<PacketBattleExited, IMessage>
- {
- @Override
- public IMessage onMessage(PacketBattleExited message, MessageContext ctx)
- {
- TurnBasedMinecraftMod.currentBattle = null;
- return null;
- }
- }
-}
--- /dev/null
+package com.seodisparate.TurnBasedMinecraft.common.networking;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import com.seodisparate.TurnBasedMinecraft.TurnBasedMinecraftMod;
+import com.seodisparate.TurnBasedMinecraft.common.Battle;
+
+import io.netty.buffer.ByteBuf;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.Entity;
+import net.minecraft.entity.EntityLiving;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.scoreboard.ScorePlayerTeam;
+import net.minecraft.util.text.TextComponentString;
+import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
+import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
+import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
+
+public class PacketBattleMessage implements IMessage
+{
+ public enum MessageType
+ {
+ ENTERED(0),
+ FLEE(1),
+ DIED(2),
+ ENDED(3),
+ ATTACK(4),
+ DEFEND(5),
+ DEFENSE_DAMAGE(6),
+ MISS(7),
+ DEFENDING(8),
+ DID_NOTHING(9);
+
+ private int value;
+ private static Map<Integer, MessageType> map = new HashMap<Integer, MessageType>();
+
+ private MessageType(int value)
+ {
+ this.value = value;
+ }
+
+ public int getValue()
+ {
+ return value;
+ }
+
+ static
+ {
+ for(MessageType type : MessageType.values())
+ {
+ map.put(type.getValue(), type);
+ }
+ }
+
+ public static MessageType valueOf(int value)
+ {
+ return map.get(value);
+ }
+ }
+
+ MessageType messageType;
+ int entityIDFrom;
+ int entityIDTo;
+ int amount;
+
+ public PacketBattleMessage() {}
+
+ public PacketBattleMessage(MessageType messageType, int entityIDFrom, int entityIDTo, int amount)
+ {
+ this.messageType = messageType;
+ this.entityIDFrom = entityIDFrom;
+ this.entityIDTo = entityIDTo;
+ this.amount = amount;
+ }
+
+ @Override
+ public void fromBytes(ByteBuf buf)
+ {
+ messageType = MessageType.valueOf(buf.readInt());
+ entityIDFrom = buf.readInt();
+ entityIDTo = buf.readInt();
+ amount = buf.readInt();
+ }
+
+ @Override
+ public void toBytes(ByteBuf buf)
+ {
+ buf.writeInt(messageType.getValue());
+ buf.writeInt(entityIDFrom);
+ buf.writeInt(entityIDTo);
+ buf.writeInt(amount);
+ }
+
+ public static class HandlerBattleMessage implements IMessageHandler<PacketBattleMessage, IMessage>
+ {
+ @Override
+ public IMessage onMessage(PacketBattleMessage message, MessageContext ctx)
+ {
+ Entity fromEntity = Minecraft.getMinecraft().world.getEntityByID(message.entityIDFrom);
+ String from = "Unknown";
+ if(fromEntity != null)
+ {
+ if(fromEntity.hasCustomName())
+ {
+ from = fromEntity.getCustomNameTag();
+ }
+ else if(fromEntity instanceof EntityPlayer)
+ {
+ from = ScorePlayerTeam.formatPlayerName(fromEntity.getTeam(), fromEntity.getName());
+ }
+ else
+ {
+ from = fromEntity.getName();
+ }
+ }
+ else if(TurnBasedMinecraftMod.currentBattle != null)
+ {
+ fromEntity = TurnBasedMinecraftMod.currentBattle.getCombatantEntity(message.entityIDFrom);
+ if(fromEntity != null)
+ {
+ if(fromEntity.hasCustomName())
+ {
+ from = fromEntity.getCustomNameTag();
+ }
+ else if(fromEntity instanceof EntityPlayer)
+ {
+ from = ScorePlayerTeam.formatPlayerName(fromEntity.getTeam(), fromEntity.getName());
+ }
+ else
+ {
+ from = fromEntity.getName();
+ }
+ }
+ }
+ Entity toEntity = Minecraft.getMinecraft().world.getEntityByID(message.entityIDTo);
+ String to = "Unknown";
+ if(toEntity != null)
+ {
+ if(toEntity.hasCustomName())
+ {
+ to = toEntity.getCustomNameTag();
+ }
+ else if(toEntity instanceof EntityPlayer)
+ {
+ to = ScorePlayerTeam.formatPlayerName(toEntity.getTeam(), toEntity.getName());
+ }
+ else
+ {
+ to = toEntity.getName();
+ }
+ }
+ else if(TurnBasedMinecraftMod.currentBattle != null)
+ {
+ toEntity = TurnBasedMinecraftMod.currentBattle.getCombatantEntity(message.entityIDTo);
+ if(toEntity != null)
+ {
+ if(toEntity.hasCustomName())
+ {
+ to = toEntity.getCustomNameTag();
+ }
+ else if(toEntity instanceof EntityPlayer)
+ {
+ to = ScorePlayerTeam.formatPlayerName(toEntity.getTeam(), toEntity.getName());
+ }
+ else
+ {
+ to = toEntity.getName();
+ }
+ }
+ }
+
+ switch(message.messageType)
+ {
+ case ENTERED:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " entered battle!"));
+ if(TurnBasedMinecraftMod.currentBattle == null || TurnBasedMinecraftMod.currentBattle.getId() != message.amount)
+ {
+ TurnBasedMinecraftMod.currentBattle = new Battle(message.amount, null, null, false);
+ }
+ break;
+ case FLEE:
+ if(message.amount != 0)
+ {
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " fled battle!"));
+ }
+ else
+ {
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " tried to flee battle but failed!"));
+ }
+ break;
+ case DIED:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " died in battle!"));
+ break;
+ case ENDED:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ "Battle has ended!"));
+ TurnBasedMinecraftMod.currentBattle = null;
+ // TODO kick player out of battle
+ break;
+ case ATTACK:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " attacked " + to + " and dealt " + message.amount + " damage!"));
+ break;
+ case DEFEND:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " blocked " + to + "'s attack!"));
+ break;
+ case DEFENSE_DAMAGE:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " retaliated from " + to + "'s attack and dealt " + message.amount + " damage!"));
+ break;
+ case MISS:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " attacked " + to + " but missed!"));
+ break;
+ case DEFENDING:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " is defending!"));
+ break;
+ case DID_NOTHING:
+ Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(new TextComponentString(
+ from + " did nothing!"));
+ break;
+ }
+ return null;
+ }
+ }
+}
<!-- 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). -->
+ <!-- Decision: Lists percentages of what action taken by the entity, one of Attack, Defend, or Flee. If the sum is less than 100, the mob has a chance to do nothing with the remaining percentage -->
<net.minecraft.entity.monster.EntityBlaze>
<AttackPower Probability="50">5</AttackPower>
<AttackEffect Probability="75">fire</AttackEffect>
<Evasion>5</Evasion>
<Category>monster</Category>
<Speed>45</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityBlaze>
<net.minecraft.entity.monster.EntityCaveSpider>
<AttackPower Probability="75">2</AttackPower>
<Evasion>35</Evasion>
<Category>monster</Category>
<Speed>75</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityCaveSpider>
<net.minecraft.entity.monster.EntityCreeper>
<IgnoreBattle>true</IgnoreBattle>
<Evasion>5</Evasion>
<Category>monster</Category>
<Speed>25</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityCreeper>
<net.minecraft.entity.monster.EntityElderGuardian>
<AttackPower Probability="65">8</AttackPower>
<Evasion>25</Evasion>
<Category>monster</Category>
<Speed>45</Speed>
+ <Decision>
+ <Attack>80</Attack>
+ <Defend>20</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityElderGuardian>
<net.minecraft.entity.monster.EntityEnderman>
<AttackPower Probability="80">7</AttackPower>
<Evasion>40</Evasion>
<Category>monster</Category>
<Speed>70</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityEnderman>
<net.minecraft.entity.monster.EntityEndermite>
<AttackPower Probability="80">2</AttackPower>
<Evasion>40</Evasion>
<Category>monster</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityEndermite>
<net.minecraft.entity.monster.EntityEvoker>
<AttackPower Probability="60">6</AttackPower>
<Evasion>35</Evasion>
<Category>monster</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityEvoker>
<net.minecraft.entity.monster.EntityGhast>
<IgnoreBattle>true</IgnoreBattle>
<Evasion>35</Evasion>
<Category>monster</Category>
<Speed>60</Speed>
+ <Decision>
+ <Attack>75</Attack>
+ <Defend>0</Defend>
+ <Flee>25</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityGhast>
<net.minecraft.entity.monster.EntityGiantZombie>
<AttackPower Probability="35">11</AttackPower>
<Evasion>2</Evasion>
<Category>monster</Category>
<Speed>45</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityGiantZombie>
<net.minecraft.entity.monster.EntityGuardian>
<AttackPower Probability="55">6</AttackPower>
<Evasion>25</Evasion>
<Category>monster</Category>
<Speed>50</Speed>
+ <Decision>
+ <Attack>80</Attack>
+ <Defend>20</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityGuardian>
<net.minecraft.entity.monster.EntityHusk>
<AttackPower Probability="70">3</AttackPower>
<Evasion>5</Evasion>
<Category>monster</Category>
<Speed>25</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</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>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityIronGolem>
<net.minecraft.entity.monster.EntityMagmaCube>
<AttackPower Probability="35">3</AttackPower>
<Evasion>12</Evasion>
<Category>monster</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityMagmaCube>
<net.minecraft.entity.monster.EntityPigZombie>
<AttackPower Probability="70">8</AttackPower>
<Evasion>10</Evasion>
<Category>monster</Category>
<Speed>50</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityPigZombie>
<net.minecraft.entity.monster.EntityPolarBear>
<AttackPower Probability="67">6</AttackPower>
<Evasion>5</Evasion>
<Category>animal</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityPolarBear>
<net.minecraft.entity.monster.EntityShulker>
<AttackPower Probability="80">4</AttackPower>
<Evasion>15</Evasion>
<Category>monster</Category>
<Speed>10</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityShulker>
<net.minecraft.entity.monster.EntitySilverFish>
<AttackPower Probability="85">1</AttackPower>
<Evasion>37</Evasion>
<Category>monster</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</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>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntitySkeleton>
<net.minecraft.entity.monster.EntitySlime>
<AttackPower Probability="35">2</AttackPower>
<Evasion>10</Evasion>
<Category>monster</Category>
<Speed>30</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntitySlime>
<net.minecraft.entity.monster.EntitySnowman>
<AttackPower Probability="80">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
<Speed>60</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntitySnowman>
<net.minecraft.entity.monster.EntitySpider>
<AttackPower Probability="70">2</AttackPower>
</Conflicts>
<Category>monster</Category>
<Speed>70</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntitySpider>
<net.minecraft.entity.monster.EntityStray>
<AttackPower Probability="75" Variance="1">3</AttackPower>
<Evasion>13</Evasion>
<Category>monster</Category>
<Speed>30</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityStray>
<net.minecraft.entity.monster.EntityVex>
<AttackPower Probability="65">9</AttackPower>
<Evasion>30</Evasion>
<Category>monster</Category>
<Speed>80</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityVex>
<net.minecraft.entity.monster.EntityVindicator>
<AttackPower Probability="70">13</AttackPower>
<Evasion>10</Evasion>
<Category>monster</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</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>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityWitch>
<net.minecraft.entity.monster.EntityWitherSkeleton>
<AttackPower Probability="70">8</AttackPower>
<Evasion>7</Evasion>
<Category>monster</Category>
<Speed>65</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityWitherSkeleton>
<net.minecraft.entity.monster.EntityZombie>
<AttackPower Probability="70">3</AttackPower>
<Evasion>5</Evasion>
<Category>monster</Category>
<Speed>25</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityZombie>
<net.minecraft.entity.monster.EntityZombieVillager>
<AttackPower Probability="70">3</AttackPower>
<Evasion>5</Evasion>
<Category>monster</Category>
<Speed>25</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.monster.EntityZombieVillager>
<net.minecraft.entity.passive.EntityBat>
<AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion>
<Category>passive</Category>
<Speed>75</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityBat>
<net.minecraft.entity.passive.EntityChicken>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityChicken>
<net.minecraft.entity.passive.EntityCow>
<AttackPower Probability="50">0</AttackPower>
</Conflicts>
<Category>passive</Category>
<Speed>20</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>10</Defend>
+ <Flee>80</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityCow>
<net.minecraft.entity.passive.EntityDonkey>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
<Speed>65</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityDonkey>
<net.minecraft.entity.passive.EntityHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
<Speed>65</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityHorse>
<net.minecraft.entity.passive.EntityLlama>
<AttackPower Probability="70">1</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
<Speed>50</Speed>
+ <Decision>
+ <Attack>65</Attack>
+ <Defend>0</Defend>
+ <Flee>25</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityLlama>
<net.minecraft.entity.passive.EntityMooshroom>
<AttackPower Probability="70">0</AttackPower>
<Evasion>1</Evasion>
<Category>passive</Category>
<Speed>20</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>10</Defend>
+ <Flee>80</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityMooshroom>
<net.minecraft.entity.passive.EntityMule>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
<Speed>50</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</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>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityOcelot>
<net.minecraft.entity.passive.EntityParrot>
<AttackPower Probability="70">0</AttackPower>
<Evasion>35</Evasion>
<Category>passive</Category>
<Speed>70</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityParrot>
<net.minecraft.entity.passive.EntityPig>
<AttackPower Probability="70">0</AttackPower>
<Evasion>10</Evasion>
<Category>passive</Category>
<Speed>30</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>5</Defend>
+ <Flee>85</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityPig>
<net.minecraft.entity.passive.EntityRabbit>
<AttackPower Probability="70">0</AttackPower>
<Evasion>40</Evasion>
<Category>passive</Category>
<Speed>75</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>100</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityRabbit>
<net.minecraft.entity.passive.EntitySheep>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
<Speed>30</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntitySheep>
<net.minecraft.entity.passive.EntitySkeletonHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
<Speed>65</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntitySkeletonHorse>
<net.minecraft.entity.passive.EntitySquid>
<AttackPower Probability="70">0</AttackPower>
<Evasion>15</Evasion>
<Category>passive</Category>
<Speed>40</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntitySquid>
<net.minecraft.entity.passive.EntityVillager>
<AttackPower Probability="70">0</AttackPower>
<Evasion>5</Evasion>
<Category>passive</Category>
<Speed>35</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>10</Defend>
+ <Flee>80</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityVillager>
<net.minecraft.entity.passive.EntityWolf>
<AttackPower Probability="70">4</AttackPower>
<Evasion>20</Evasion>
<Category>animal</Category>
<Speed>70</Speed>
+ <Decision>
+ <Attack>80</Attack>
+ <Defend>15</Defend>
+ <Flee>5</Flee>
+ </Decision>
</net.minecraft.entity.passive.EntityWolf>
<net.minecraft.entity.passive.EntityZombieHorse>
<AttackPower Probability="70">0</AttackPower>
<Evasion>8</Evasion>
<Category>passive</Category>
<Speed>65</Speed>
+ <Decision>
+ <Attack>0</Attack>
+ <Defend>0</Defend>
+ <Flee>90</Flee>
+ </Decision>
</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>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.boss.EntityDragon>
<net.minecraft.entity.boss.EntityWither>
<AttackPower Probability="70">8</AttackPower>
<AttackEffect Probability="90">wither</AttackEffect>
<Category>boss</Category>
<Speed>68</Speed>
+ <Decision>
+ <Attack>100</Attack>
+ <Defend>0</Defend>
+ <Flee>0</Flee>
+ </Decision>
</net.minecraft.entity.boss.EntityWither>
</EntityStats>
</TurnBasedMinecraftConfig>
\ No newline at end of file