]> git.seodisparate.com - TurnBasedMinecraftMod/commitdiff
Implement use of vanilla bow/arrows in battle
authorStephen Seo <seo.disparate@gmail.com>
Mon, 17 Sep 2018 06:49:10 +0000 (15:49 +0900)
committerStephen Seo <seo.disparate@gmail.com>
Mon, 17 Sep 2018 06:49:10 +0000 (15:49 +0900)
src/main/java/com/seodisparate/TurnBasedMinecraft/common/AttackEventHandler.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/AttackerViaBow.java [new file with mode: 0644]
src/main/java/com/seodisparate/TurnBasedMinecraft/common/Battle.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/Combatant.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/EntityInfo.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/TurnBasedMinecraftMod.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/Utility.java
src/main/java/com/seodisparate/TurnBasedMinecraft/common/networking/PacketBattleMessage.java

index 485e8ee6452711d70c9fc579b16ff54361c48cb6..01ac49ea24b636b473970f57f2586c63ba8c3f8b 100644 (file)
@@ -1,10 +1,60 @@
 package com.seodisparate.TurnBasedMinecraft.common;
 
+import java.util.ArrayDeque;
+import java.util.Queue;
+
+import com.seodisparate.TurnBasedMinecraft.common.networking.PacketBattleMessage;
+
 import net.minecraftforge.event.entity.living.LivingAttackEvent;
 import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
 
 public class AttackEventHandler
 {
+    private boolean isAttackerValid(LivingAttackEvent event)
+    {
+        if(event.getSource().getTrueSource() == null)
+        {
+            return false;
+        }
+        else if(event.getSource().getTrueSource().equals(TurnBasedMinecraftMod.attackingEntity))
+        {
+            return true;
+        }
+        else
+        {
+            Queue<AttackerViaBow> removeQueue = new ArrayDeque<AttackerViaBow>();
+            final long now = System.nanoTime();
+            boolean isValid = false;
+            synchronized(TurnBasedMinecraftMod.attackerViaBow)
+            {
+                for(AttackerViaBow attacker : TurnBasedMinecraftMod.attackerViaBow)
+                {
+                    if(now - attacker.attackTime >= AttackerViaBow.ATTACK_TIMEOUT)
+                    {
+                        removeQueue.add(attacker);
+                    }
+                    else if(event.getSource().getTrueSource().equals(attacker.entity) && event.getSource().isProjectile())
+                    {
+                        removeQueue.add(attacker);
+                        isValid = true;
+                        Battle b = TurnBasedMinecraftMod.battleManager.getBattleByID(attacker.battleID);
+                        if(b != null)
+                        {
+                            b.sendMessageToAllPlayers(PacketBattleMessage.MessageType.ARROW_HIT, attacker.entity.getEntityId(), event.getEntity().getEntityId(), 0);
+                        }
+                    }
+                }
+                AttackerViaBow next = removeQueue.poll();
+                while(next != null)
+                {
+                    TurnBasedMinecraftMod.attackerViaBow.remove(next);
+                    next = removeQueue.poll();
+                }
+            }
+            return isValid;
+        }
+    }
+    
     @SubscribeEvent
     public void entityAttacked(LivingAttackEvent event)
     {
@@ -17,7 +67,7 @@ public class AttackEventHandler
             TurnBasedMinecraftMod.battleManager = new BattleManager(TurnBasedMinecraftMod.logger);
         }
         
-        if(!(event.getSource().getTrueSource() == null || event.getSource().getTrueSource().equals(TurnBasedMinecraftMod.attackingEntity)) && TurnBasedMinecraftMod.battleManager.checkAttack(event))
+        if(!isAttackerValid(event) && event.getEntity() != null && event.getSource().getTrueSource() != null && TurnBasedMinecraftMod.battleManager.checkAttack(event))
         {
 //            TurnBasedMinecraftMod.logger.debug("Canceled LivingAttackEvent between " + TurnBasedMinecraftMod.attackingEntity + " and " + event.getEntity());
             event.setCanceled(true);
diff --git a/src/main/java/com/seodisparate/TurnBasedMinecraft/common/AttackerViaBow.java b/src/main/java/com/seodisparate/TurnBasedMinecraft/common/AttackerViaBow.java
new file mode 100644 (file)
index 0000000..7cdaca7
--- /dev/null
@@ -0,0 +1,26 @@
+package com.seodisparate.TurnBasedMinecraft.common;
+
+import net.minecraft.entity.Entity;
+
+public class AttackerViaBow
+{
+    public static long ATTACK_TIMEOUT = 10000000000L;
+    
+    public Entity entity;
+    public long attackTime;
+    public int battleID;
+    
+    public AttackerViaBow()
+    {
+        entity = null;
+        attackTime = 0;
+        battleID = -1;
+    }
+    
+    public AttackerViaBow(Entity entity, int battleID)
+    {
+        this.entity = entity;
+        attackTime = System.nanoTime();
+        this.battleID = battleID;
+    }
+}
index 5ae47bc5f5aa3ee5d6a1a06921221e81b3b353f6..ee2e2b46c2dc35d004eeb1e13bda7e09fa6463a8 100644 (file)
@@ -20,6 +20,7 @@ import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.entity.player.EntityPlayerMP;
 import net.minecraft.init.Items;
 import net.minecraft.item.Item;
+import net.minecraft.item.ItemBow;
 import net.minecraft.item.ItemFood;
 import net.minecraft.item.ItemLingeringPotion;
 import net.minecraft.item.ItemPotion;
@@ -135,6 +136,7 @@ public class Battle
                 }
                 Combatant newCombatant = new Combatant(e, entityInfo);
                 newCombatant.isSideA = true;
+                newCombatant.battleID = getId();
                 this.sideA.put(e.getEntityId(), newCombatant);
                 if(e instanceof EntityPlayer)
                 {
@@ -155,6 +157,7 @@ public class Battle
                 }
                 Combatant newCombatant = new Combatant(e, entityInfo);
                 newCombatant.isSideA = false;
+                newCombatant.battleID = getId();
                 this.sideB.put(e.getEntityId(), newCombatant);
                 if(e instanceof EntityPlayer)
                 {
@@ -236,6 +239,7 @@ public class Battle
         }
         Combatant newCombatant = new Combatant(e, entityInfo);
         newCombatant.isSideA = true;
+        newCombatant.battleID = getId();
         sideA.put(e.getEntityId(), newCombatant);
         if(e instanceof EntityPlayer)
         {
@@ -267,6 +271,7 @@ public class Battle
         }
         Combatant newCombatant = new Combatant(e, entityInfo);
         newCombatant.isSideA = false;
+        newCombatant.battleID = getId();
         sideB.put(e.getEntityId(), newCombatant);
         if(e instanceof EntityPlayer)
         {
@@ -404,7 +409,7 @@ public class Battle
         }
     }
     
-    private void sendMessageToAllPlayers(PacketBattleMessage.MessageType type, int from, int to, int amount)
+    protected void sendMessageToAllPlayers(PacketBattleMessage.MessageType type, int from, int to, int amount)
     {
         if(!isServer)
         {
@@ -419,7 +424,7 @@ public class Battle
         }
     }
     
-    private void sendMessageToAllPlayers(PacketBattleMessage.MessageType type, int from, int to, int amount, String custom)
+    protected void sendMessageToAllPlayers(PacketBattleMessage.MessageType type, int from, int to, int amount, String custom)
     {
         if(!isServer)
         {
@@ -631,6 +636,32 @@ public class Battle
                             {
                                 break;
                             }
+                            ItemStack heldItemStack = ((EntityPlayer)next.entity).getHeldItemMainhand();
+                            if(heldItemStack.getItem() instanceof ItemBow)
+                            {
+                                if(Utility.doesPlayerHaveArrows((EntityPlayer)next.entity))
+                                {
+                                    final Entity nextEntity = next.entity;
+                                    final Entity targetEntity = target.entity;
+                                    next.entity.getServer().addScheduledTask(() -> {
+                                        // have player look at attack target
+                                        ((EntityPlayerMP)nextEntity).connection.setPlayerLocation(nextEntity.posX, nextEntity.posY, nextEntity.posZ, Utility.yawDirection(nextEntity.posX, nextEntity.posZ, targetEntity.posX, targetEntity.posZ), Utility.pitchDirection(nextEntity.posX, nextEntity.posY, nextEntity.posZ, targetEntity.posX, targetEntity.posY, targetEntity.posZ));
+                                        ItemBow itemBow = (ItemBow)heldItemStack.getItem();
+                                        synchronized(TurnBasedMinecraftMod.attackerViaBow)
+                                        {
+                                            TurnBasedMinecraftMod.attackerViaBow.add(new AttackerViaBow(nextEntity, getId()));
+                                        }
+                                        itemBow.onPlayerStoppedUsing(((EntityPlayer)nextEntity).getHeldItemMainhand(), nextEntity.getEntityWorld(), (EntityLivingBase)nextEntity, (int)(Math.random() * (itemBow.getMaxItemUseDuration(heldItemStack)) / 3));
+                                        sendMessageToAllPlayers(PacketBattleMessage.MessageType.FIRED_ARROW, nextEntity.getEntityId(), targetEntity.getEntityId(), 0);
+                                    });
+                                }
+                                else
+                                {
+                                    sendMessageToAllPlayers(PacketBattleMessage.MessageType.BOW_NO_AMMO, next.entity.getEntityId(), 0, 0);
+                                }
+                                next = turnOrderQueue.poll();
+                                continue;
+                            }
                             int hitChance = TurnBasedMinecraftMod.config.getPlayerAttackProbability();
                             if(target.entity instanceof EntityPlayer)
                             {
@@ -649,12 +680,11 @@ public class Battle
                                 if(target.remainingDefenses <= 0)
                                 {
                                     // attack
-                                    // TODO damage via bow and arrow
-                                    // have player look at attack target
                                     final Entity nextEntity = next.entity;
                                     final Entity targetEntity = target.entity;
                                     final EntityInfo targetEntityInfo = target.entityInfo;
                                     next.entity.getServer().addScheduledTask(() -> {
+                                        // have player look at attack target
                                         ((EntityPlayerMP)nextEntity).connection.setPlayerLocation(nextEntity.posX, nextEntity.posY, nextEntity.posZ, Utility.yawDirection(nextEntity.posX, nextEntity.posZ, targetEntity.posX, targetEntity.posZ), Utility.pitchDirection(nextEntity.posX, nextEntity.posY, nextEntity.posZ, targetEntity.posX, targetEntity.posY, targetEntity.posZ));
                                         TurnBasedMinecraftMod.attackingEntity = nextEntity;
                                         TurnBasedMinecraftMod.attackingDamage = 0;
index 6490e26a9da7543530c239cdfb3da4b0aaf8b4a3..80f2c1ff4e05153204e508252cc7bc4b81ed56ba 100644 (file)
@@ -18,6 +18,7 @@ public class Combatant
     public int targetEntityID;
     public boolean isSideA;
     public int remainingDefenses;
+    public int battleID;
     
     public Combatant()
     {
index 62d9086eadc5b85fbbccaaa4c46f47adb7f7604b..7efc7f26a3d23638cdbdf1ec6e09b04c65f26543 100644 (file)
@@ -1,8 +1,5 @@
 package com.seodisparate.TurnBasedMinecraft.common;
 
-import java.util.ArrayList;
-import java.util.List;
-
 import net.minecraft.entity.EntityLivingBase;
 import net.minecraft.init.MobEffects;
 import net.minecraft.potion.PotionEffect;
index 8d3d2a3ef1f02dd5580eb1329bb136df29dcabae..966602f2b355583cd3d6e312812dd6adbed97296 100644 (file)
@@ -1,6 +1,8 @@
 package com.seodisparate.TurnBasedMinecraft.common;
 
 import java.time.Duration;
+import java.util.HashSet;
+import java.util.Set;
 
 import org.apache.logging.log4j.Logger;
 
@@ -45,6 +47,7 @@ public class TurnBasedMinecraftMod
     private static int packetHandlerID = 0;
     protected static Entity attackingEntity;
     protected static int attackingDamage = 0;
+    protected static Set<AttackerViaBow> attackerViaBow;
     protected static Config config;
     
     public static Battle currentBattle = null;
@@ -64,6 +67,7 @@ public class TurnBasedMinecraftMod
     {
         currentBattle = null;
         battleManager = null;
+        attackerViaBow = new HashSet<AttackerViaBow>();
         commonProxy.setLogger(logger);
         
         // register packets
index 9fc88c72a1da93a70ae6f2900e39c2ea963ce632..73a66d9660cb481f4fe30a0a97193177715d0597 100644 (file)
@@ -1,5 +1,8 @@
 package com.seodisparate.TurnBasedMinecraft.common;
 
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.item.ItemArrow;
+
 public class Utility
 {
     public static float yawDirection(double posX, double posZ, double targetX, double targetZ)
@@ -28,4 +31,16 @@ public class Utility
             return (float)(-Math.atan(diffY / distance) * 180.0 / Math.PI);
         }
     }
+    
+    public static boolean doesPlayerHaveArrows(EntityPlayer player)
+    {
+        for(int i = 0; i < player.inventory.getSizeInventory(); ++i)
+        {
+            if(player.inventory.getStackInSlot(i).getItem() instanceof ItemArrow)
+            {
+                return true;
+            }
+        }
+        return false;
+    }
 }
index 2de9f30f2c48a886aaa98465124903f121795f2b..a88b7b4b04af26f4b6ffcffee20cb92d450110e1 100644 (file)
@@ -34,7 +34,10 @@ public class PacketBattleMessage implements IMessage
         TURN_END(12),
         SWITCHED_ITEM(13),
         WAS_AFFECTED(14),
-        BECAME_CREATIVE(15);
+        BECAME_CREATIVE(15),
+        FIRED_ARROW(16),
+        ARROW_HIT(17),
+        BOW_NO_AMMO(18);
         
         private int value;
         private static Map<Integer, MessageType> map = new HashMap<Integer, MessageType>();
@@ -326,6 +329,15 @@ public class PacketBattleMessage implements IMessage
             case BECAME_CREATIVE:
                 TurnBasedMinecraftMod.commonProxy.displayString(from + " entered creative mode and left battle!");
                 break;
+            case FIRED_ARROW:
+                TurnBasedMinecraftMod.commonProxy.displayString(from + " let loose an arrow towards " + to + "!");
+                break;
+            case ARROW_HIT:
+                TurnBasedMinecraftMod.commonProxy.displayString(to + " was hit by " + from + "'s arrow!");
+                break;
+            case BOW_NO_AMMO:
+                TurnBasedMinecraftMod.commonProxy.displayString(from + " tried to use their bow but ran out of ammo!");
+                break;
             }
             return null;
         }