]> git.seodisparate.com - TurnBasedMinecraftMod/commitdiff
Add battle cooldown
authorStephen Seo <seo.disparate@gmail.com>
Wed, 17 Oct 2018 09:28:47 +0000 (18:28 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Wed, 17 Oct 2018 09:28:47 +0000 (18:28 +0900)
Cooldown (default 5 seconds) prevents an entity that left battle from
attacking or being-attacked for the duration of the cooldown.

src/main/java/com/seodisparate/TurnBasedMinecraft/client/ClientProxy.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/AttackEventHandler.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/Battle.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleManager.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/BattleUpdater.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/Combatant.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/CommandTBMEnableAll.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/Config.java
src/main/resources/assets/TurnBasedMinecraft/TBM_Config.xml

index 35a13679724baf4acb2d73b1e244e576f51e9532..3089355eb8b102f8ef596657156b8e48888c31fe 100644 (file)
@@ -224,6 +224,6 @@ public class ClientProxy extends CommonProxy
     @Override
     public void createLocalBattle(int id)
     {
-        localBattle = new Battle(id, null, null, false);
+        localBattle = new Battle(null, id, null, null, false);
     }
 }
index 4a33b592090fdd480cfd8940b4c81db2fca09a6c..ecf3f47caad144ef26f5715013fa5a19f6685b79 100644 (file)
@@ -64,13 +64,20 @@ public class AttackEventHandler
         {
             return;
         }
-        
-        if(!isAttackerValid(event)
+        Config config = TurnBasedMinecraftMod.proxy.getConfig();
+        BattleManager battleManager = TurnBasedMinecraftMod.proxy.getBattleManager();
+        if((event.getEntity() != null && battleManager.isRecentlyLeftBattle(event.getEntity().getEntityId()))
+                || (event.getSource().getTrueSource() != null && battleManager.isRecentlyLeftBattle(event.getSource().getTrueSource().getEntityId())))
+        {
+            event.setCanceled(true);
+            return;
+        }
+        else if(!isAttackerValid(event)
                 && event.getEntity() != null
                 && event.getSource().getTrueSource() != null
-                && !TurnBasedMinecraftMod.proxy.getConfig().getBattleIgnoringPlayers().contains(event.getSource().getTrueSource().getEntityId())
-                && !TurnBasedMinecraftMod.proxy.getConfig().getBattleIgnoringPlayers().contains(event.getEntity().getEntityId())
-                && TurnBasedMinecraftMod.proxy.getBattleManager().checkAttack(event))
+                && !config.getBattleIgnoringPlayers().contains(event.getSource().getTrueSource().getEntityId())
+                && !config.getBattleIgnoringPlayers().contains(event.getEntity().getEntityId())
+                && battleManager.checkAttack(event))
         {
 //            TurnBasedMinecraftMod.logger.debug("Canceled LivingAttackEvent between " + TurnBasedMinecraftMod.commonProxy.getAttackingEntity() + " and " + event.getEntity());
             event.setCanceled(true);
@@ -88,14 +95,19 @@ public class AttackEventHandler
     @SubscribeEvent
     public void entityTargeted(LivingSetAttackTargetEvent event)
     {
-        if(event.getEntity().world.isRemote || TurnBasedMinecraftMod.proxy.getConfig().isOldBattleBehaviorEnabled())
+        Config config = TurnBasedMinecraftMod.proxy.getConfig();
+        BattleManager battleManager = TurnBasedMinecraftMod.proxy.getBattleManager();
+        if(event.getEntity().world.isRemote
+                || config.isOldBattleBehaviorEnabled()
+                || (event.getEntity() != null && battleManager.isRecentlyLeftBattle(event.getEntity().getEntityId()))
+                || (event.getTarget() != null && battleManager.isRecentlyLeftBattle(event.getTarget().getEntityId())))
         {
             return;
         }
         else if(event.getEntity() != null
                 && event.getTarget() != null
-                && !TurnBasedMinecraftMod.proxy.getConfig().getBattleIgnoringPlayers().contains(event.getEntity().getEntityId())
-                && !TurnBasedMinecraftMod.proxy.getConfig().getBattleIgnoringPlayers().contains(event.getTarget().getEntityId()))
+                && !config.getBattleIgnoringPlayers().contains(event.getEntity().getEntityId())
+                && !config.getBattleIgnoringPlayers().contains(event.getTarget().getEntityId()))
         {
             TurnBasedMinecraftMod.proxy.getBattleManager().checkTargeted(event);
         }
index d40ca3f441ea640dc44e3482c8744f42a5e500af..3960512b3a522a68e628fdfa298b2f032f64b2a8 100644 (file)
@@ -49,6 +49,8 @@ public class Battle
     private boolean isServer;
     private boolean battleEnded;
     
+    private BattleManager battleManager;
+    
     public enum State
     {
         DECISION(0),
@@ -118,8 +120,9 @@ public class Battle
         }
     }
 
-    public Battle(int id, Collection<Entity> sideA, Collection<Entity> sideB, boolean isServer)
+    public Battle(BattleManager battleManager, int id, Collection<Entity> sideA, Collection<Entity> sideB, boolean isServer)
     {
+        this.battleManager = battleManager;
         this.isServer = isServer;
         this.id = id;
         this.sideA = new Hashtable<Integer, Combatant>();
@@ -515,16 +518,12 @@ public class Battle
      */
     private boolean healthCheck()
     {
-        Queue<Integer> removeQueue = new ArrayDeque<Integer>();
+        Queue<Combatant> removeQueue = new ArrayDeque<Combatant>();
         for(Combatant c : sideA.values())
         {
             if(!c.entity.isEntityAlive())
             {
-                removeQueue.add(c.entity.getEntityId());
-                if(c.entity instanceof EntityPlayer)
-                {
-                    TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, c.entity.getEntityId(), 0, 0), (EntityPlayerMP)c.entity);
-                }
+                removeQueue.add(c);
                 String category = new String();
                 if(c.entityInfo != null)
                 {
@@ -541,11 +540,7 @@ public class Battle
         {
             if(!c.entity.isEntityAlive())
             {
-                removeQueue.add(c.entity.getEntityId());
-                if(c.entity instanceof EntityPlayer)
-                {
-                    TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, c.entity.getEntityId(), 0, 0), (EntityPlayerMP)c.entity);
-                }
+                removeQueue.add(c);
                 String category = new String();
                 if(c.entityInfo != null)
                 {
@@ -559,14 +554,9 @@ public class Battle
             }
         }
         boolean didRemove = !removeQueue.isEmpty();
-        for(Integer toRemove = removeQueue.poll(); toRemove != null; toRemove = removeQueue.poll())
+        for(Combatant toRemove = removeQueue.poll(); toRemove != null; toRemove = removeQueue.poll())
         {
-            sideA.remove(toRemove);
-            sideB.remove(toRemove);
-            if(players.remove(toRemove) != null)
-            {
-                playerCount.decrementAndGet();
-            }
+            removeCombatant(toRemove);
         }
         if(players.isEmpty() || sideA.isEmpty() || sideB.isEmpty())
         {
@@ -586,24 +576,20 @@ public class Battle
      */
     private boolean isCreativeCheck()
     {
-        Queue<Integer> removeQueue = new ArrayDeque<Integer>();
+        Queue<Combatant> removeQueue = new ArrayDeque<Combatant>();
         for(Combatant c : players.values())
         {
             if(c.entity != null && ((EntityPlayer)c.entity).isCreative())
             {
-                TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, c.entity.getEntityId(), 0, 0), (EntityPlayerMP)c.entity);
-                removeQueue.add(c.entity.getEntityId());
+                removeQueue.add(c);
             }
         }
         boolean didRemove = false;
-        for(Integer toRemove = removeQueue.poll(); toRemove != null; toRemove = removeQueue.poll())
+        for(Combatant toRemove = removeQueue.poll(); toRemove != null; toRemove = removeQueue.poll())
         {
             didRemove = true;
-            sideA.remove(toRemove);
-            sideB.remove(toRemove);
-            players.remove(toRemove);
-            playerCount.decrementAndGet();
-            sendMessageToAllPlayers(PacketBattleMessage.MessageType.BECAME_CREATIVE, toRemove, 0, 0);
+            removeCombatant(toRemove);
+            sendMessageToAllPlayers(PacketBattleMessage.MessageType.BECAME_CREATIVE, toRemove.entity.getEntityId(), 0, 0);
         }
         if(didRemove)
         {
@@ -640,6 +626,18 @@ public class Battle
         }
     }
     
+    private void removeCombatant(Combatant c)
+    {
+        sideA.remove(c.entity.getEntityId());
+        sideB.remove(c.entity.getEntityId());
+        if(players.remove(c.entity.getEntityId()) != null)
+        {
+            playerCount.decrementAndGet();
+            TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, 0, 0, 0), (EntityPlayerMP)c.entity);
+        }
+        battleManager.addRecentlyLeftBattle(c);
+    }
+    
     /**
      * @return True if battle has ended
      */
@@ -651,6 +649,13 @@ public class Battle
         }
         else if(battleEnded)
         {
+            Collection<Combatant> combatants = new ArrayList<Combatant>();
+            combatants.addAll(sideA.values());
+            combatants.addAll(sideB.values());
+            for(Combatant c : combatants)
+            {
+                removeCombatant(c);
+            }
             return true;
         }
         long nextInstant = System.nanoTime();
@@ -663,6 +668,13 @@ public class Battle
     {
         if(battleEnded)
         {
+            Collection<Combatant> combatants = new ArrayList<Combatant>();
+            combatants.addAll(sideA.values());
+            combatants.addAll(sideB.values());
+            for(Combatant c : combatants)
+            {
+                removeCombatant(c);
+            }
             return true;
         }
         boolean combatantsChanged = false;
@@ -1066,14 +1078,6 @@ public class Battle
                         if((int)(Math.random() * 100) < fleeProbability)
                         {
                             // flee success
-                            if(next.isSideA)
-                            {
-                                sideA.remove(next.entity.getEntityId());
-                            }
-                            else
-                            {
-                                sideB.remove(next.entity.getEntityId());
-                            }
                             combatantsChanged = true;
                             String fleeingCategory = new String();
                             if(next.entityInfo != null)
@@ -1085,12 +1089,7 @@ public class Battle
                                 fleeingCategory = "player";
                             }
                             sendMessageToAllPlayers(PacketBattleMessage.MessageType.FLEE, next.entity.getEntityId(), 0, 1, fleeingCategory);
-                            if(next.entity instanceof EntityPlayer)
-                            {
-                                players.remove(next.entity.getEntityId());
-                                playerCount.decrementAndGet();
-                                TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketBattleMessage(PacketBattleMessage.MessageType.ENDED, 0, 0, 0), (EntityPlayerMP)next.entity);
-                            }
+                            removeCombatant(next);
                         }
                         else
                         {
@@ -1180,6 +1179,16 @@ public class Battle
         {
             notifyPlayersBattleInfo();
         }
+        if(battleEnded)
+        {
+            Collection<Combatant> combatants = new ArrayList<Combatant>();
+            combatants.addAll(sideA.values());
+            combatants.addAll(sideB.values());
+            for(Combatant c : combatants)
+            {
+                removeCombatant(c);
+            }
+        }
         return battleEnded;
     } // update(final long dt)
 }
index 4532c4f93f2786980b572de55bf85105f8c73a6c..6fbb8f5a1317685815384e07612f974b3eed6369 100644 (file)
@@ -1,14 +1,22 @@
 package com.seodisparate.TurnBasedMinecraft.common;
 
+import java.util.ArrayDeque;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Hashtable;
 import java.util.Map;
+import java.util.Queue;
+import java.util.Set;
 
 import org.apache.logging.log4j.Logger;
 
+import com.seodisparate.TurnBasedMinecraft.common.networking.PacketGeneralMessage;
+
 import net.minecraft.entity.Entity;
 import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraftforge.event.entity.living.LivingAttackEvent;
 import net.minecraftforge.event.entity.living.LivingSetAttackTargetEvent;
 
@@ -19,6 +27,7 @@ public class BattleManager
     private Thread updaterThread;
     private BattleUpdater battleUpdater;
     private Logger logger;
+    private Map<Integer, Combatant> recentlyLeftBattle;
     
     public BattleManager(Logger logger)
     {
@@ -27,6 +36,7 @@ public class BattleManager
         battleUpdater = new BattleUpdater(this);
         updaterThread = new Thread(battleUpdater);
         updaterThread.start();
+        recentlyLeftBattle = new HashMap<Integer, Combatant>();
     }
     
     /**
@@ -245,7 +255,7 @@ public class BattleManager
         {
             ++IDCounter;
         }
-        Battle newBattle = new Battle(IDCounter, sideA, sideB, true);
+        Battle newBattle = new Battle(this, IDCounter, sideA, sideB, true);
         battleMap.put(IDCounter, newBattle);
         newBattle.notifyPlayersBattleInfo();
         return newBattle;
@@ -263,4 +273,50 @@ public class BattleManager
         updaterThread = null;
         battleMap.clear();
     }
+    
+    protected void addRecentlyLeftBattle(Combatant c)
+    {
+        c.time = System.nanoTime();
+        Config config = TurnBasedMinecraftMod.proxy.getConfig();
+        if(c.entity instanceof EntityPlayerMP)
+        {
+            TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketGeneralMessage("You just left battle! " + config.getLeaveBattleCooldownSeconds() + " seconds until you can attack/be-attacked again!"), (EntityPlayerMP)c.entity);
+        }
+        synchronized(recentlyLeftBattle)
+        {
+            recentlyLeftBattle.put(c.entity.getEntityId(), c);
+        }
+    }
+    
+    protected void updateRecentlyLeftBattle()
+    {
+        long current = System.nanoTime();
+        Queue<Combatant> removeQueue = new ArrayDeque<Combatant>();
+        synchronized(recentlyLeftBattle)
+        {
+            for(Combatant c : recentlyLeftBattle.values())
+            {
+                if(current - c.time > TurnBasedMinecraftMod.proxy.getConfig().getLeaveBattleCooldownNanos())
+                {
+                    removeQueue.add(c);
+                }
+            }
+            for(Combatant c = removeQueue.poll(); c != null; c = removeQueue.poll())
+            {
+                if(c.entity instanceof EntityPlayerMP)
+                {
+                    TurnBasedMinecraftMod.NWINSTANCE.sendTo(new PacketGeneralMessage("Timer ended, you can now attack/be-attacked again."), (EntityPlayerMP)c.entity);
+                }
+                recentlyLeftBattle.remove(c.entity.getEntityId());
+            }
+        }
+    }
+    
+    public boolean isRecentlyLeftBattle(int entityID)
+    {
+        synchronized(recentlyLeftBattle)
+        {
+            return recentlyLeftBattle.containsKey(entityID);
+        }
+    }
 }
\ No newline at end of file
index 8b8e4bae17d6e140ca1a226e4a1f46d7ead0b7fb..969818725ae59342e09f2c0d8dd731673b79fe58 100644 (file)
@@ -33,6 +33,7 @@ public class BattleUpdater implements Runnable
             {
                 manager.battleMap.remove(ended);
             }
+            manager.updateRecentlyLeftBattle();
             try { Thread.sleep(250); } catch (Throwable t) { /* ignored */ }
         }
     }
index 559aa49ea5bf8016b615087958785e0130568c02..16368b4ca9928cf118371262df4ce3f925d131e2 100644 (file)
@@ -24,6 +24,7 @@ public class Combatant
     public double z;
     public float yaw;
     public float pitch;
+    public long time;
     
     public Combatant()
     {
index 77d2f0af11529804b333622e7caa5fb857e74d54..303ddb9f2749bcf488ec6b97bacab9e78a6e80e4 100644 (file)
@@ -5,7 +5,6 @@ import com.seodisparate.TurnBasedMinecraft.common.networking.PacketGeneralMessag
 import net.minecraft.command.CommandBase;
 import net.minecraft.command.CommandException;
 import net.minecraft.command.ICommandSender;
-import net.minecraft.entity.Entity;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.server.MinecraftServer;
 
index 7e868b0c8eb66b7c3c341c9147ab20727e7de756..143694b09095b6b72738fe47d725ebdc46c7a685 100644 (file)
@@ -8,7 +8,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.time.LocalDateTime;
 import java.time.format.DateTimeFormatter;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.Map;
@@ -49,6 +48,7 @@ public class Config
     private boolean onlyOPsSelfDisableTB = true;
     private boolean battleDisabledForAll = false;
     private boolean oldBattleBehaviorEnabled = false;
+    private int leaveBattleCooldownSeconds = 5;
     
     public Config(Logger logger)
     {
@@ -175,6 +175,18 @@ public class Config
                 {
                     continue;
                 }
+                else if(xmlReader.getLocalName().equals("LeaveBattleCooldown"))
+                {
+                    leaveBattleCooldownSeconds = Integer.parseInt(xmlReader.getElementText());
+                    if(leaveBattleCooldownSeconds <= 0)
+                    {
+                        leaveBattleCooldownSeconds = 1;
+                    }
+                    else if(leaveBattleCooldownSeconds > 10)
+                    {
+                        leaveBattleCooldownSeconds = 10;
+                    }
+                }
                 else if(xmlReader.getLocalName().equals("OldBattleBehavior"))
                 {
                     if(xmlReader.getElementText().toLowerCase().equals("false"))
@@ -634,4 +646,14 @@ public class Config
     {
         return oldBattleBehaviorEnabled;
     }
+    
+    public int getLeaveBattleCooldownSeconds()
+    {
+        return leaveBattleCooldownSeconds;
+    }
+    
+    public long getLeaveBattleCooldownNanos()
+    {
+        return (long)leaveBattleCooldownSeconds * 1000000000L;
+    }
 }
index 750d4a3b42f3627ad6843aa74588fc1d84eb2e20..17c08380ddd69981eb6e48e3ba6b574c19049c8c 100644 (file)
@@ -1,6 +1,8 @@
 <TurnBasedMinecraftConfig>
        <!-- If the mod has a newer version config, it will rename the existing config and place the new config -->
        <Version>5</Version>
+       <!-- Number of seconds that an entity cannot enter battle after having just left one. Minimum 1, maximum 10-->
+       <LeaveBattleCooldown>5</LeaveBattleCooldown>
        <!-- If not "false", uses old battle behavior where battles only start on attack/hit. Otherwise, battles can
        start when a hostile mob targets a player or another entity in battle. -->
        <OldBattleBehavior>false</OldBattleBehavior>