diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/TurnBasedMinecraftMod.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/TurnBasedMinecraftMod.java index 0e12d64..eb76f1f 100644 --- a/src/main/java/com/seodisparate/TurnBasedMinecraft/TurnBasedMinecraftMod.java +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/TurnBasedMinecraftMod.java @@ -1,11 +1,15 @@ package com.seodisparate.TurnBasedMinecraft; -import net.minecraft.init.Blocks; +import org.apache.logging.log4j.Logger; + +import com.seodisparate.TurnBasedMinecraft.common.BattleManager; + +import net.minecraft.entity.Entity; +import net.minecraftforge.event.entity.living.LivingAttackEvent; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; -import org.apache.logging.log4j.Logger; @Mod(modid = TurnBasedMinecraftMod.MODID, name = TurnBasedMinecraftMod.NAME, version = TurnBasedMinecraftMod.VERSION) public class TurnBasedMinecraftMod @@ -15,6 +19,9 @@ public class TurnBasedMinecraftMod public static final String VERSION = "1.0"; private static Logger logger; + private static BattleManager battleManager; + + public static Entity attackingEntity; @EventHandler public void preInit(FMLPreInitializationEvent event) @@ -25,7 +32,16 @@ public class TurnBasedMinecraftMod @EventHandler public void init(FMLInitializationEvent event) { - // some example code - logger.info("DIRT BLOCK >> {}", Blocks.DIRT.getRegistryName()); + battleManager = new BattleManager(); + } + + @EventHandler + public void entityAttacked(LivingAttackEvent event) + { + if(!event.getEntity().equals(attackingEntity) && battleManager.checkAttack(event)) + { + logger.debug("Canceled LivingAttackEvent between " + attackingEntity + " and " + event.getEntity()); + event.setCanceled(true); + } } } diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Battle.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Battle.java new file mode 100644 index 0000000..e72a906 --- /dev/null +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/Battle.java @@ -0,0 +1,79 @@ +package com.seodisparate.TurnBasedMinecraft.common; + +import java.time.Duration; +import java.time.Instant; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Map; + +import net.minecraft.entity.Entity; + +public class Battle +{ + private int id; + private Map sideA; + private Map sideB; + + private Instant lastUpdated; + + public Battle(int id, Collection sideA, Collection sideB) + { + this.id = id; + this.sideA = new Hashtable(); + this.sideB = new Hashtable(); + for(Entity e : sideA) + { + this.sideA.put(e.getEntityId(), e); + } + for(Entity e : sideB) + { + this.sideB.put(e.getEntityId(), e); + } + + lastUpdated = null; + } + + public int getId() + { + return id; + } + + public boolean hasCombatant(int entityID) + { + return sideA.containsKey(entityID) || sideB.containsKey(entityID); + } + + public boolean hasCombatantInSideA(int entityID) + { + return sideA.containsKey(entityID); + } + + public void addCombatantToSideA(Entity e) + { + sideA.put(e.getEntityId(), e); + } + + public void addCombatantToSideB(Entity e) + { + sideB.put(e.getEntityId(), e); + } + + public void update() + { + if(lastUpdated == null) + { + lastUpdated = Instant.now(); + update(Duration.ZERO); + } + else + { + Instant now = Instant.now(); + update(Duration.between(lastUpdated, now)); + lastUpdated = now; + } + } + + private void update(Duration dt) + { + } +} diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java new file mode 100644 index 0000000..991cae7 --- /dev/null +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java @@ -0,0 +1,106 @@ +package com.seodisparate.TurnBasedMinecraft.common; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Hashtable; +import java.util.Map; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraftforge.event.entity.living.LivingAttackEvent; + +public class BattleManager +{ + private int IDCounter = 0; + protected Map battleMap; + private Thread updaterThread; + + public BattleManager() + { + battleMap = new Hashtable(); + updaterThread = new Thread(new BattleUpdater(this)); + updaterThread.start(); + } + + /** + * Either creates a new Battle, adds a combatant to an existing Battle, or does + * nothing, depending on if a player is involved and/or an entity is currently + * in battle. + * + * @param event + * @return True if event should be canceled + */ + public boolean checkAttack(final LivingAttackEvent event) + { + // check if one is in battle + Entity inBattle = null; + Entity notInBattle = null; + Battle battle = null; + for(Battle b : battleMap.values()) + { + if(b.hasCombatant(event.getSource().getTrueSource().getEntityId())) + { + inBattle = event.getSource().getTrueSource(); + battle = b; + break; + } + } + if(inBattle != null) + { + notInBattle = event.getEntity(); + } else + { + notInBattle = event.getSource().getTrueSource(); + } + for(Battle b : battleMap.values()) + { + if(b.hasCombatant(event.getEntity().getEntityId())) + { + if(inBattle != null) + { + // both combatants in battle + return true; + } + inBattle = event.getEntity(); + battle = b; + break; + } + } + if(inBattle == null) + { + // neither entity is in battle + if(event.getEntity() instanceof EntityPlayer || event.getSource().getTrueSource() instanceof EntityPlayer) + { + // at least one of the entities is a player, create Battle + Collection sideA = new ArrayList(1); + Collection sideB = new ArrayList(1); + sideA.add(event.getEntity()); + sideB.add(event.getSource().getTrueSource()); + createBattle(sideA, sideB); + } + return false; + } + + // at this point only one entity is in battle, so add entity to other side + if(battle.hasCombatantInSideA(inBattle.getEntityId())) + { + battle.addCombatantToSideB(notInBattle); + } + else + { + battle.addCombatantToSideA(notInBattle); + } + return true; + } + + private Battle createBattle(Collection sideA, Collection sideB) + { + while(battleMap.containsKey(IDCounter)) + { + ++IDCounter; + } + Battle newBattle = new Battle(IDCounter, sideA, sideB); + battleMap.put(IDCounter, newBattle); + return newBattle; + } +} diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java new file mode 100644 index 0000000..4f52dc1 --- /dev/null +++ b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java @@ -0,0 +1,21 @@ +package com.seodisparate.TurnBasedMinecraft.common; + +public class BattleUpdater implements Runnable +{ + BattleManager manager; + + public BattleUpdater(BattleManager manager) + { + this.manager = manager; + } + + @Override + public void run() + { + for(Battle e : manager.battleMap.values()) + { + e.update(); + } + try { Thread.sleep(250); } catch (Exception e) { /* ignored */ } + } +} \ No newline at end of file