From fd5004b1a2f3a938f9346ae843642480598f86b9 Mon Sep 17 00:00:00 2001
From: Sollace <sollacea@gmail.com>
Date: Sat, 23 Feb 2019 17:09:30 +0200
Subject: [PATCH] Skeleton disguises will now have their arms in the correct
 pose when holding a bow

---
 .../unicopia/mixin/FieldAccessor.java         | 40 +++++++++++++++++++
 .../unicopia/mixin/MixinEntity.java           | 29 ++------------
 .../unicopia/spell/SpellDisguise.java         |  8 ++++
 3 files changed, 51 insertions(+), 26 deletions(-)
 create mode 100644 src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java

diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java b/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java
new file mode 100644
index 00000000..141dfe75
--- /dev/null
+++ b/src/main/java/com/minelittlepony/unicopia/mixin/FieldAccessor.java
@@ -0,0 +1,40 @@
+package com.minelittlepony.unicopia.mixin;
+
+import java.lang.reflect.Field;
+
+public class FieldAccessor<Owner, Type> {
+
+    private boolean init;
+    private Field field;
+
+    private final Class<Owner> ownerClass;
+
+    private final int fieldIndex;
+
+    FieldAccessor(Class<Owner> type, int index) {
+        ownerClass = type;
+        fieldIndex = index;
+    }
+
+    void set(Owner instance, Type value) {
+        init = false;
+        field = null;
+        init();
+
+        try {
+            if (field != null) {
+                field.set(instance, value);
+            }
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            e.printStackTrace();
+        }
+    }
+
+    private void init() {
+        if (!init && field == null) {
+            Field[] fields = ownerClass.getDeclaredFields();
+            field = fields[fieldIndex < 0 ? (fields.length + fieldIndex) : fieldIndex];
+            field.setAccessible(true);
+        }
+    }
+}
diff --git a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java
index 68f22406..2367cdf0 100644
--- a/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java
+++ b/src/main/java/com/minelittlepony/unicopia/mixin/MixinEntity.java
@@ -1,7 +1,5 @@
 package com.minelittlepony.unicopia.mixin;
 
-import java.lang.reflect.Field;
-
 import com.minelittlepony.unicopia.forgebullshit.FUF;
 
 import net.minecraft.entity.Entity;
@@ -19,33 +17,12 @@ public interface MixinEntity {
         public static DataParameter<Byte> getModelFlag() {
             return PLAYER_MODEL_FLAG;
         }
-
     }
-    abstract class Shulker extends EntityShulker {
-        private Shulker() { super(null);}
-
-        private static boolean __init;
-        private static Field __peekAmount = null;
+    abstract class Shulker {
+        private static final FieldAccessor<EntityShulker, Float> __peekAmount = new FieldAccessor<>(EntityShulker.class, 8);
 
         public static void setPeek(EntityShulker shulker, float peekAmount) {
-            initFields();
-
-            try {
-                if (__peekAmount != null) {
-                    __peekAmount.set(shulker, peekAmount);
-                }
-            } catch (IllegalArgumentException | IllegalAccessException e) {
-                e.printStackTrace();
-            }
-
-        }
-
-        private static void initFields() {
-            if (!__init && __peekAmount == null) {
-                Field[] fields = EntityShulker.class.getDeclaredFields();
-                __peekAmount = fields[fields.length - 3];
-                __peekAmount.setAccessible(true);
-            }
+            __peekAmount.set(shulker, peekAmount);
         }
     }
 
diff --git a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java
index 69151744..19149883 100644
--- a/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java
+++ b/src/main/java/com/minelittlepony/unicopia/spell/SpellDisguise.java
@@ -23,6 +23,7 @@ import net.minecraft.entity.EntityHanging;
 import net.minecraft.entity.EntityList;
 import net.minecraft.entity.EntityLiving;
 import net.minecraft.entity.EntityLivingBase;
+import net.minecraft.entity.IRangedAttackMob;
 import net.minecraft.entity.boss.EntityDragon;
 import net.minecraft.entity.item.EntityFallingBlock;
 import net.minecraft.entity.item.EntityMinecart;
@@ -33,6 +34,7 @@ import net.minecraft.entity.passive.EntityTameable;
 import net.minecraft.entity.player.EntityPlayer;
 import net.minecraft.entity.projectile.EntityShulkerBullet;
 import net.minecraft.inventory.EntityEquipmentSlot;
+import net.minecraft.item.EnumAction;
 import net.minecraft.item.ItemStack;
 import net.minecraft.nbt.NBTTagCompound;
 import net.minecraft.tileentity.TileEntitySkull;
@@ -263,6 +265,12 @@ public class SpellDisguise extends AbstractSpell implements IAttachedEffect, ISu
             }
         }
 
+        if (to instanceof IRangedAttackMob) {
+            ItemStack activeItem = from.getActiveItemStack();
+
+            ((IRangedAttackMob)to).setSwingingArms(!activeItem.isEmpty() && activeItem.getItemUseAction() == EnumAction.BOW);
+        }
+
         if (to instanceof EntityTameable) {
             ((EntityTameable)to).setSitting(from.isSneaking());
         }