diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java
index 53e4a9d5..a941a067 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/ConfigOptions.java
@@ -174,7 +174,7 @@ public void setDefaults() {
set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".interactMenu", true);
set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".startFollowDistance", 12);
set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".stopFollowDistance", 4);
- set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".teleportDistance", 30);
+ set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".teleportDistance", 40);
/*set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".attack.canDamagePlayers", false);
set("pets." + petType.toString().toLowerCase().replace("_", " ") + ".attack.lockRange", 10);
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/PetItem.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/PetItem.java
index ad6a649b..8d6abca9 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/PetItem.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/config/PetItem.java
@@ -30,8 +30,10 @@ public enum PetItem {
CREEPER(PetType.CREEPER, Material.getMaterial(383), (short) 50, "Creeper Pet", "creeper"),
ENDERDRAGON(PetType.ENDERDRAGON, Material.getMaterial(122), (short) 0, "EnderDragon Pet", "enderdragon"),
ENDERMAN(PetType.ENDERMAN, Material.getMaterial(383), (short) 58, "Enderman Pet", "enderman"),
+ ENDERMITE(PetType.ENDERMITE, Material.getMaterial(383), (short) 67, "Endermite Pet", "endermite"),
GHAST(PetType.GHAST, Material.getMaterial(383), (short) 56, "Ghast Pet", "ghast"),
GIANT(PetType.GIANT, Material.getMaterial(383), (short) 54, "Giant Pet", "giant"),
+ GUARDIAN(PetType.GUARDIAN, Material.getMaterial(383), (short) 68, "Guardian Pet", "guardian"),
HORSE(PetType.HORSE, Material.getMaterial(383), (short) 100, "Horse Pet", "horse"),
HUMAN(PetType.HUMAN, Material.SKULL_ITEM, (short) 3, "Human Pet", "human"),
IRONGOLEM(PetType.IRONGOLEM, Material.getMaterial(86), (short) 0, "Iron Golem Pet", "irongolem"),
@@ -40,6 +42,7 @@ public enum PetItem {
OCELOT(PetType.OCELOT, Material.getMaterial(383), (short) 98, "Ocelot Pet", "ocelot"),
PIG(PetType.PIG, Material.getMaterial(383), (short) 90, "Pig Pet", "pig"),
PIGZOMBIE(PetType.PIGZOMBIE, Material.getMaterial(383), (short) 57, "PigZombie Pet", "pigzombie"),
+ RABBIT(PetType.RABBIT, Material.getMaterial(383), (short) 101, "Rabbit Pet", "rabbit"),
SHEEP(PetType.SHEEP, Material.getMaterial(383), (short) 91, "Sheep Pet", "sheep"),
SILVERFISH(PetType.SILVERFISH, Material.getMaterial(383), (short) 60, "Silverfish Pet", "silverfish"),
SKELETON(PetType.SKELETON, Material.getMaterial(383), (short) 51, "Skeleton Pet", "skeleton"),
@@ -86,4 +89,4 @@ public short getData() {
public String getName() {
return name;
}
-}
\ No newline at end of file
+}
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/IEntityPet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/IEntityPet.java
index fe1682ef..4b09efeb 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/IEntityPet.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/IEntityPet.java
@@ -46,5 +46,9 @@ public interface IEntityPet {
public LivingEntity getTarget();
+ void resetEntitySize();
+
+ void setEntitySize(float width, float height);
+
public IPet getPet();
}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetData.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetData.java
index e0724f08..2d3ef412 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetData.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetData.java
@@ -25,11 +25,12 @@ public enum PetData {
ANGRY("angry", Type.BOOLEAN),
BABY("baby", Type.BOOLEAN),
- BLACK("black", Type.COLOUR, Type.CAT, Type.HORSE_VARIANT),
+ BLACK("black", Type.COLOUR, Type.CAT, Type.HORSE_VARIANT, Type.RABBIT_TYPE),
+ BLACK_AND_WHITE("blackandwhite", Type.RABBIT_TYPE),
BLACKSMITH("blacksmith", Type.PROF),
BLACKSPOT("blackSpot", Type.HORSE_MARKING),
BLUE("blue", Type.COLOUR),
- BROWN("brown", Type.COLOUR, Type.HORSE_VARIANT),
+ BROWN("brown", Type.COLOUR, Type.HORSE_VARIANT, Type.RABBIT_TYPE),
BUTCHER("butcher", Type.PROF),
CHESTED("chested", Type.BOOLEAN),
CHESTNUT("chestnut", Type.HORSE_VARIANT),
@@ -38,12 +39,14 @@ public enum PetData {
DARKBROWN("darkbrown", Type.HORSE_VARIANT),
DIAMOND("diamond", Type.HORSE_ARMOUR),
DONKEY("donkey", Type.HORSE_TYPE),
+ ELDER("elder", Type.BOOLEAN),
FARMER("farmer", Type.PROF),
FIRE("fire", Type.BOOLEAN),
GRAY("gray", Type.COLOUR, Type.HORSE_VARIANT),
GREEN("green", Type.COLOUR),
GOLD("gold", Type.HORSE_ARMOUR),
IRON("iron", Type.HORSE_ARMOUR),
+ THE_KILLER_BUNNY("killerbunny", Type.RABBIT_TYPE),
LARGE("large", Type.SIZE),
LIBRARIAN("librarian", Type.PROF),
LIGHTBLUE("lightBlue", Type.COLOUR),
@@ -61,6 +64,7 @@ public enum PetData {
PURPLE("purple", Type.COLOUR),
RED("red", Type.CAT, Type.COLOUR),
SADDLE("saddle", Type.BOOLEAN),
+ SALT_AND_PEPPER("saltandpepper", Type.RABBIT_TYPE),
SCREAMING("screaming", Type.BOOLEAN),
SHEARED("sheared", Type.BOOLEAN),
SHIELD("shield", Type.BOOLEAN),
@@ -73,7 +77,7 @@ public enum PetData {
VILLAGER("villager", Type.BOOLEAN),
WHITEPATCH("whitePatch", Type.HORSE_MARKING),
WHITESPOT("whiteSpot", Type.HORSE_MARKING),
- WHITE("white", Type.COLOUR, Type.HORSE_VARIANT),
+ WHITE("white", Type.COLOUR, Type.HORSE_VARIANT, Type.RABBIT_TYPE),
WILD("wild", Type.CAT),
WITHER("wither", Type.BOOLEAN),
YELLOW("yellow", Type.COLOUR),
@@ -101,6 +105,6 @@ public boolean isType(Type t) {
}
public enum Type {
- BOOLEAN, COLOUR, CAT, SIZE, PROF, HORSE_TYPE, HORSE_VARIANT, HORSE_MARKING, HORSE_ARMOUR
+ BOOLEAN, COLOUR, CAT, SIZE, PROF, HORSE_TYPE, HORSE_VARIANT, HORSE_MARKING, HORSE_ARMOUR, RABBIT_TYPE
}
-}
\ No newline at end of file
+}
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetType.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetType.java
index 4428b35c..47757543 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetType.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/PetType.java
@@ -33,8 +33,10 @@ public enum PetType {
CREEPER("Creeper", 50, "Creeper Pet", 20D, 6D, EntityType.CREEPER, PetData.POWER),
ENDERDRAGON("EnderDragon", 63, "EnderDragon Pet", 200D, 0D, EntityType.ENDER_DRAGON),
ENDERMAN("Enderman", 58, "Enderman Pet", 40D, 6D, EntityType.ENDERMAN, PetData.SCREAMING),
+ ENDERMITE("Endermite", 67, "Endermite Pet", 2D, 2D, EntityType.ENDERMITE),
GHAST("Ghast", 56, "Ghast Pet", 10D, 7D, EntityType.GHAST),
GIANT("Giant", 53, "Giant Pet", 100D, 0D, EntityType.GIANT),
+ GUARDIAN("Guardian", 68, "Guardian Pet", 20D, 10D, EntityType.GUARDIAN, PetData.ELDER),
MAGMACUBE("MagmaCube", 62, "Magma Cube Pet", 20D, 5D, EntityType.MAGMA_CUBE, PetData.SMALL, PetData.MEDIUM, PetData.LARGE),
PIGZOMBIE("PigZombie", 57, "Pig Zombie Pet", 20D, 6D, EntityType.PIG_ZOMBIE, PetData.BABY),
SILVERFISH("Silverfish", 60, "Silverfish Pet", 8D, 4D, EntityType.SILVERFISH),
@@ -60,6 +62,7 @@ public enum PetType {
MUSHROOMCOW("MushroomCow", 96, "Mushroom Cow Pet", 10D, 3D, EntityType.MUSHROOM_COW, PetData.BABY),
OCELOT("Ocelot", 98, "Ocelot Pet", 10D, 4D, EntityType.OCELOT, PetData.BABY, PetData.BLACK, PetData.RED, PetData.SIAMESE, PetData.WILD),
PIG("Pig", 90, "Pig Pet", 10D, 3D, EntityType.PIG, PetData.BABY, PetData.SADDLE),
+ RABBIT("Rabbit", 101, "Rabbit Pet", 8D, 3D, EntityType.RABBIT, PetData.BABY, PetData.BROWN, PetData.WHITE, PetData.BLACK, PetData.BLACK_AND_WHITE, PetData.SALT_AND_PEPPER, PetData.THE_KILLER_BUNNY),
SHEEP("Sheep", 91, "Sheep Pet", 8D, 3D, EntityType.SHEEP, PetData.BABY, PetData.SHEARED,
PetData.BLACK, PetData.BLUE, PetData.BROWN,
PetData.CYAN, PetData.GRAY, PetData.GREEN,
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/SizeCategory.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/SizeCategory.java
index f5c05f11..bdfadfaa 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/SizeCategory.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/SizeCategory.java
@@ -21,15 +21,15 @@
public enum SizeCategory {
- TINY(1),
- REGULAR(1),
- LARGE(3),
- GIANT(4),
- OVERSIZE(10);
+ TINY(1.5F),
+ REGULAR(1.5F),
+ LARGE(4),
+ GIANT(5),
+ OVERSIZE(12);
- private int modifier;
+ private float modifier;
- SizeCategory(int modifier) {
+ SizeCategory(float modifier) {
this.modifier = modifier;
}
@@ -42,6 +42,6 @@ public float getStopWalk(PetType petType) {
}
public float getTeleport(PetType petType) {
- return (EchoPet.getConfig().getInt("pets." + petType.toString().toLowerCase().replace("_", " ") + ".teleportDistance", 30) * this.modifier) / 2;
+ return (EchoPet.getConfig().getInt("pets." + petType.toString().toLowerCase().replace("_", " ") + ".teleportDistance", 40) * this.modifier) / 2;
}
}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityEndermitePet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityEndermitePet.java
new file mode 100644
index 00000000..609f0fd5
--- /dev/null
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityEndermitePet.java
@@ -0,0 +1,24 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.api.entity.type.nms;
+
+import com.dsh105.echopet.compat.api.entity.IEntityPet;
+
+public interface IEntityEndermitePet extends IEntityPet {
+
+}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityGuardianPet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityGuardianPet.java
new file mode 100644
index 00000000..fa123665
--- /dev/null
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityGuardianPet.java
@@ -0,0 +1,27 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.api.entity.type.nms;
+
+import com.dsh105.echopet.compat.api.entity.IEntityPet;
+
+public interface IEntityGuardianPet extends IEntityPet {
+
+ boolean isElder();
+
+ void setElder(boolean flag);
+}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityRabbitPet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityRabbitPet.java
new file mode 100644
index 00000000..a69c506e
--- /dev/null
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/nms/IEntityRabbitPet.java
@@ -0,0 +1,28 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.api.entity.type.nms;
+
+import com.dsh105.echopet.compat.api.entity.IEntityAgeablePet;
+import org.bukkit.entity.Rabbit;
+
+public interface IEntityRabbitPet extends IEntityAgeablePet {
+
+ Rabbit.Type getRabbitType();
+
+ void setRabbitType(Rabbit.Type type);
+}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IEndermitePet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IEndermitePet.java
new file mode 100644
index 00000000..cd409811
--- /dev/null
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IEndermitePet.java
@@ -0,0 +1,24 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.api.entity.type.pet;
+
+import com.dsh105.echopet.compat.api.entity.IPet;
+
+public interface IEndermitePet extends IPet {
+
+}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IGuardianPet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IGuardianPet.java
new file mode 100644
index 00000000..9dc8a8e8
--- /dev/null
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IGuardianPet.java
@@ -0,0 +1,27 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.api.entity.type.pet;
+
+import com.dsh105.echopet.compat.api.entity.IPet;
+
+public interface IGuardianPet extends IPet {
+
+ boolean isElder();
+
+ void setElder(boolean flag);
+}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IRabbitPet.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IRabbitPet.java
new file mode 100644
index 00000000..679f8b09
--- /dev/null
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/entity/type/pet/IRabbitPet.java
@@ -0,0 +1,28 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.api.entity.type.pet;
+
+import com.dsh105.echopet.compat.api.entity.IAgeablePet;
+import org.bukkit.entity.Rabbit;
+
+public interface IRabbitPet extends IAgeablePet {
+
+ void setRabbitType(Rabbit.Type type);
+
+ Rabbit.Type getRabbitType();
+}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/MenuUtil.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/MenuUtil.java
index f62590c9..87fad9f6 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/MenuUtil.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/MenuUtil.java
@@ -102,6 +102,13 @@ public static ArrayList createOptionList(PetType pt) {
options.add(new MenuOption(i++, MenuItem.HORSE_VARIANT));
options.add(new MenuOption(i++, MenuItem.HORSE_MARKING));
}
+ if (pt == PetType.GUARDIAN) {
+ options.add(new MenuOption(i++, MenuItem.ELDER));
+ }
+ if (pt == PetType.RABBIT) {
+ options.add(new MenuOption(i++, MenuItem.BABY));
+ options.add(new MenuOption(i++, MenuItem.RABBIT_TYPE));
+ }
return options;
}
}
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenu.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenu.java
index ab22c759..53be2d1e 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenu.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenu.java
@@ -70,6 +70,7 @@ public enum DataMenuType {
HORSE_TYPE,
HORSE_VARIANT,
HORSE_MARKING,
- HORSE_ARMOUR
+ HORSE_ARMOUR,
+ RABBIT_TYPE
}
}
\ No newline at end of file
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenuItem.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenuItem.java
index 11b3b339..ff579037 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenuItem.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/DataMenuItem.java
@@ -88,6 +88,13 @@ public enum DataMenuItem {
GOLD(DataMenuType.HORSE_ARMOUR, PetData.GOLD, Material.getMaterial(418), 1, (short) 0, "Gold", "Armour"),
DIAMOND(DataMenuType.HORSE_ARMOUR, PetData.DIAMOND, Material.getMaterial(419), 1, (short) 0, "Diamond", "Armour"),
+ BROWN_RABBIT(DataMenuType.RABBIT_TYPE, PetData.BROWN, Material.WOOL, 1, (short) 12, "Brown", "Bunny type"),
+ WHITE_RABBIT(DataMenuType.RABBIT_TYPE, PetData.WHITE, Material.WOOL, 1, (short) 0, "White", "Bunny type"),
+ BLACK_RABBIT(DataMenuType.HORSE_ARMOUR, PetData.BLACK, Material.WOOL, 1, (short) 15, "Black", "Bunny type"),
+ BLACK_AND_WHITE_RABBIT(DataMenuType.RABBIT_TYPE, PetData.BLACK_AND_WHITE, Material.WOOL, 1, (short) 7, "Black and White", "Bunny type"),
+ SALT_AND_PEPPER_RABBIT(DataMenuType.RABBIT_TYPE, PetData.SALT_AND_PEPPER, Material.WOOL, 1, (short) 4, "Salt and Pepper", "Bunny type"),
+ KILLER_BUNNY(DataMenuType.RABBIT_TYPE, PetData.THE_KILLER_BUNNY, Material.WOOL, 1, (short) 14, "Killer Bunny", "Bunny type"),
+
BACK(DataMenuType.OTHER, null, Material.BOOK, 1, (short) 0, "Back", "Return to the main menu."),
CLOSE(DataMenuType.OTHER, null, Material.BOOK, 1, (short) 0, "Close", "Close the Pet Menu");
diff --git a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/MenuItem.java b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/MenuItem.java
index 88dc5292..11aeae41 100644
--- a/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/MenuItem.java
+++ b/modules/API/src/main/java/com/dsh105/echopet/compat/api/util/menu/MenuItem.java
@@ -33,6 +33,7 @@ public enum MenuItem {
HORSE_VARIANT(Material.LEASH, 1, (short) 0, DataMenuType.HORSE_VARIANT, "Variant", "Horse"),
HORSE_MARKING(Material.INK_SACK, 1, (short) 0, DataMenuType.HORSE_MARKING, "Marking", "Horse"),
HORSE_ARMOUR(Material.IRON_CHESTPLATE, 1, (short) 0, DataMenuType.HORSE_ARMOUR, "Armour", "Horse"),
+ RABBIT_TYPE(Material.RABBIT_HIDE, 1, (short) 0, DataMenuType.RABBIT_TYPE, "Bunny type", "Rabbit"),
CHESTED(Material.CHEST, 1, (short) 0, DataMenuType.BOOLEAN, "Chested", "Horse"),
FIRE(Material.FIREBALL, 1, (short) 0, DataMenuType.BOOLEAN, "Fire", "Blaze"),
SADDLE(Material.SADDLE, 1, (short) 0, DataMenuType.BOOLEAN, "Saddle", "Horse", "Pig"),
@@ -48,6 +49,7 @@ public enum MenuItem {
TAMED(Material.BONE, 1, (short) 0, DataMenuType.BOOLEAN, "Tamed", "Wolf"),
WITHER(Material.getMaterial(397), 1, (short) 1, DataMenuType.BOOLEAN, "Wither", "Skeleton"),
VILLAGER(Material.EMERALD, 1, (short) 0, DataMenuType.BOOLEAN, "Villager", "Zombie", "PigZombie"),
+ ELDER(Material.SEA_LANTERN, 1, (short) 0, DataMenuType.BOOLEAN, "Elder", "Guardian"),
COLOR(Material.WOOL, 1, (short) 0, DataMenuType.COLOR, "Color", "Sheep", "Wolf"),
PROFESSION(Material.IRON_AXE, 1, (short) 0, DataMenuType.PROFESSION, "Profession", "Villager"),
RIDE(Material.CARROT_STICK, 1, (short) 0, DataMenuType.BOOLEAN, "Ride Pet", "Control your pet."),
diff --git a/modules/EchoPet/pom.xml b/modules/EchoPet/pom.xml
index 36b40ebe..f15bd795 100644
--- a/modules/EchoPet/pom.xml
+++ b/modules/EchoPet/pom.xml
@@ -118,6 +118,18 @@
true
+
+ com.dsh105
+ EchoPet-v1_8_R2
+ v2
+
+
+ org.bukkit
+ craftbukkit
+
+
+ true
+
diff --git a/modules/EchoPet/src/main/java/com/dsh105/echopet/api/PetManager.java b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/PetManager.java
index 14de94fd..879d4c63 100644
--- a/modules/EchoPet/src/main/java/com/dsh105/echopet/api/PetManager.java
+++ b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/PetManager.java
@@ -30,6 +30,7 @@
import org.bukkit.configuration.ConfigurationSection;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
+import org.bukkit.entity.Rabbit;
import org.bukkit.entity.Villager.Profession;
import java.util.ArrayList;
@@ -543,7 +544,14 @@ public void setData(IPet pet, PetData pd, boolean b) {
if (pd == PetData.SHIELD) {
((IWitherPet) pet).setShielded(b);
}
+
+ if (pd == PetData.ELDER) {
+ ((IGuardianPet) pet).setElder(b);
+ }
+ if (pd.isType(PetData.Type.RABBIT_TYPE) && petType == PetType.RABBIT) {
+ ((IRabbitPet) pet).setRabbitType(Rabbit.Type.valueOf(pd.toString()));
+ }
if (petType == PetType.HORSE) {
if (pd == PetData.CHESTED) {
@@ -616,6 +624,11 @@ public void setData(IPet pet, PetData pd, boolean b) {
}
}
}
+
+ if (petType == PetType.GUARDIAN) {
+
+ }
+
ListIterator i = pet.getPetData().listIterator();
while (i.hasNext()) {
PetData petData = i.next();
diff --git a/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/EndermitePet.java b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/EndermitePet.java
new file mode 100644
index 00000000..07a82e88
--- /dev/null
+++ b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/EndermitePet.java
@@ -0,0 +1,32 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.api.pet.type;
+
+import com.dsh105.echopet.api.pet.Pet;
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.pet.IEndermitePet;
+import org.bukkit.entity.Player;
+
+@EntityPetType(petType = PetType.ENDERMITE)
+public class EndermitePet extends Pet implements IEndermitePet {
+
+ public EndermitePet(Player owner) {
+ super(owner);
+ }
+}
\ No newline at end of file
diff --git a/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/GuardianPet.java b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/GuardianPet.java
new file mode 100644
index 00000000..2266496c
--- /dev/null
+++ b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/GuardianPet.java
@@ -0,0 +1,48 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.api.pet.type;
+
+import com.dsh105.echopet.api.pet.Pet;
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityGuardianPet;
+import com.dsh105.echopet.compat.api.entity.type.pet.IGuardianPet;
+import org.bukkit.entity.Player;
+
+@EntityPetType(petType = PetType.GUARDIAN)
+public class GuardianPet extends Pet implements IGuardianPet {
+
+ public GuardianPet(Player owner) {
+ super(owner);
+ }
+
+ @Override
+ public boolean isElder() {
+ return ((IEntityGuardianPet) getEntityPet()).isElder();
+ }
+
+ @Override
+ public void setElder(boolean flag) {
+ if (!isElder() && flag) {
+ getEntityPet().setEntitySize(1.9975F, 1.9975F);
+ } else if (isElder() && !flag) {
+ getEntityPet().resetEntitySize();
+ }
+ ((IEntityGuardianPet) getEntityPet()).setElder(flag);
+ }
+}
\ No newline at end of file
diff --git a/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/RabbitPet.java b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/RabbitPet.java
new file mode 100644
index 00000000..1aaf8129
--- /dev/null
+++ b/modules/EchoPet/src/main/java/com/dsh105/echopet/api/pet/type/RabbitPet.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.api.pet.type;
+
+import com.dsh105.echopet.api.pet.Pet;
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityRabbitPet;
+import com.dsh105.echopet.compat.api.entity.type.pet.IRabbitPet;
+import org.bukkit.entity.Player;
+import org.bukkit.entity.Rabbit;
+
+@EntityPetType(petType = PetType.RABBIT)
+public class RabbitPet extends Pet implements IRabbitPet {
+
+ public RabbitPet(Player owner) {
+ super(owner);
+ }
+
+ @Override
+ public boolean isBaby() {
+ return ((IEntityRabbitPet) getEntityPet()).isBaby();
+ }
+
+ @Override
+ public void setBaby(boolean flag) {
+ ((IEntityRabbitPet) getEntityPet()).setBaby(flag);
+ }
+
+ @Override
+ public void setRabbitType(Rabbit.Type type) {
+ ((IEntityRabbitPet) getEntityPet()).setRabbitType(type);
+ }
+
+ @Override
+ public Rabbit.Type getRabbitType() {
+ return ((IEntityRabbitPet) getEntityPet()).getRabbitType();
+ }
+}
\ No newline at end of file
diff --git a/modules/v1_6_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_6_R3/entity/EntityPet.java b/modules/v1_6_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_6_R3/entity/EntityPet.java
index f1772149..027f2648 100644
--- a/modules/v1_6_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_6_R3/entity/EntityPet.java
+++ b/modules/v1_6_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_6_R3/entity/EntityPet.java
@@ -70,7 +70,7 @@ public EntityPet(World world, IPet pet) {
}
private void initiateEntityPet() {
- this.setSize();
+ this.resetEntitySize();
this.fireProof = true;
if (this.FIELD_JUMP == null) {
try {
@@ -103,13 +103,19 @@ public void resizeBoundingBox(boolean flag) {
}
}
- protected void setSize() {
+ @Override
+ public void resetEntitySize() {
EntitySize es = this.getClass().getAnnotation(EntitySize.class);
if (es != null) {
this.setSize(es.width(), es.height());
}
}
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
protected void setSize(float width, float height) {
this.a(width, height);
}
diff --git a/modules/v1_7_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R1/entity/EntityPet.java b/modules/v1_7_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R1/entity/EntityPet.java
index e49deae0..47a33ec2 100644
--- a/modules/v1_7_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R1/entity/EntityPet.java
+++ b/modules/v1_7_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R1/entity/EntityPet.java
@@ -70,7 +70,7 @@ public EntityPet(World world, IPet pet) {
}
private void initiateEntityPet() {
- this.setSize();
+ this.resetEntitySize();
this.fireProof = true;
if (this.FIELD_JUMP == null) {
try {
@@ -103,13 +103,19 @@ public void resizeBoundingBox(boolean flag) {
}
}
- protected void setSize() {
+ @Override
+ public void resetEntitySize() {
EntitySize es = this.getClass().getAnnotation(EntitySize.class);
if (es != null) {
this.setSize(es.width(), es.height());
}
}
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
protected void setSize(float width, float height) {
this.a(width, height);
}
diff --git a/modules/v1_7_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R2/entity/EntityPet.java b/modules/v1_7_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R2/entity/EntityPet.java
index d14608db..3dea83d2 100644
--- a/modules/v1_7_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R2/entity/EntityPet.java
+++ b/modules/v1_7_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R2/entity/EntityPet.java
@@ -70,7 +70,7 @@ public EntityPet(World world, IPet pet) {
}
private void initiateEntityPet() {
- this.setSize();
+ this.resetEntitySize();
this.fireProof = true;
if (this.FIELD_JUMP == null) {
try {
@@ -103,13 +103,19 @@ public void resizeBoundingBox(boolean flag) {
}
}
- protected void setSize() {
+ @Override
+ public void resetEntitySize() {
EntitySize es = this.getClass().getAnnotation(EntitySize.class);
if (es != null) {
this.setSize(es.width(), es.height());
}
}
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
protected void setSize(float width, float height) {
this.a(width, height);
}
diff --git a/modules/v1_7_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R3/entity/EntityPet.java b/modules/v1_7_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R3/entity/EntityPet.java
index be4a8fff..bfcba0b8 100644
--- a/modules/v1_7_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R3/entity/EntityPet.java
+++ b/modules/v1_7_R3/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R3/entity/EntityPet.java
@@ -69,7 +69,7 @@ public EntityPet(World world, IPet pet) {
}
private void initiateEntityPet() {
- this.setSize();
+ this.resetEntitySize();
this.fireProof = true;
if (this.FIELD_JUMP == null) {
try {
@@ -102,13 +102,19 @@ public void resizeBoundingBox(boolean flag) {
}
}
- protected void setSize() {
+ @Override
+ public void resetEntitySize() {
EntitySize es = this.getClass().getAnnotation(EntitySize.class);
if (es != null) {
this.setSize(es.width(), es.height());
}
}
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
protected void setSize(float width, float height) {
this.a(width, height);
}
diff --git a/modules/v1_7_R4/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R4/entity/EntityPet.java b/modules/v1_7_R4/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R4/entity/EntityPet.java
index 4c916862..f1e67b52 100644
--- a/modules/v1_7_R4/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R4/entity/EntityPet.java
+++ b/modules/v1_7_R4/src/main/java/com/dsh105/echopet/compat/nms/v1_7_R4/entity/EntityPet.java
@@ -69,7 +69,7 @@ public EntityPet(World world, IPet pet) {
}
private void initiateEntityPet() {
- this.setSize();
+ this.resetEntitySize();
this.fireProof = true;
if (this.FIELD_JUMP == null) {
try {
@@ -102,13 +102,19 @@ public void resizeBoundingBox(boolean flag) {
}
}
- protected void setSize() {
+ @Override
+ public void resetEntitySize() {
EntitySize es = this.getClass().getAnnotation(EntitySize.class);
if (es != null) {
this.setSize(es.width(), es.height());
}
}
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
protected void setSize(float width, float height) {
this.a(width, height);
}
diff --git a/modules/v1_8_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R1/entity/EntityPet.java b/modules/v1_8_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R1/entity/EntityPet.java
index 94a9ea91..a9ea67a7 100644
--- a/modules/v1_8_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R1/entity/EntityPet.java
+++ b/modules/v1_8_R1/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R1/entity/EntityPet.java
@@ -69,7 +69,7 @@ public EntityPet(World world, IPet pet) {
}
private void initiateEntityPet() {
- this.setSize();
+ this.resetEntitySize();
this.fireProof = true;
if (this.FIELD_JUMP == null) {
try {
@@ -102,13 +102,19 @@ public void resizeBoundingBox(boolean flag) {
}
}
- protected void setSize() {
+ @Override
+ public void resetEntitySize() {
EntitySize es = this.getClass().getAnnotation(EntitySize.class);
if (es != null) {
this.setSize(es.width(), es.height());
}
}
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
protected void setSize(float width, float height) {
this.a(width, height);
}
diff --git a/modules/v1_8_R2/pom.xml b/modules/v1_8_R2/pom.xml
new file mode 100644
index 00000000..e03c7660
--- /dev/null
+++ b/modules/v1_8_R2/pom.xml
@@ -0,0 +1,96 @@
+
+
+
+ 4.0.0
+
+ EchoPet-v1_8_R2
+ EchoPet for v1_8_R2
+ v2
+ jar
+
+
+ UTF-8
+
+
+
+ com.dsh105
+ EchoPet-Parent
+ v2
+ ../../
+
+
+
+
+ org.bukkit
+ bukkit
+ 1.8.3-R0.1-SNAPSHOT
+ jar
+
+
+ org.bukkit
+ craftbukkit
+ 1.8.3-R0.1-SNAPSHOT
+ jar
+
+
+ com.dsh105
+ EchoPet-API
+ v2
+
+
+ org.bukkit
+ craftbukkit
+
+
+
+
+
+
+ ../../target
+ src/main/java/
+ ${project.name}
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 2.4
+
+
+ maven-clean-plugin
+
+ true
+
+
+ target
+
+ **/*
+
+
+
+
+ 2.5
+
+
+
+
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/NMSEntityUtil.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/NMSEntityUtil.java
new file mode 100644
index 00000000..c4730305
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/NMSEntityUtil.java
@@ -0,0 +1,176 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2;
+
+import com.captainbern.minecraft.reflection.MinecraftReflection;
+import com.captainbern.reflection.ClassTemplate;
+import com.captainbern.reflection.Reflection;
+import com.captainbern.reflection.SafeField;
+import com.captainbern.reflection.SafeMethod;
+import com.captainbern.reflection.accessor.FieldAccessor;
+import com.captainbern.reflection.accessor.MethodAccessor;
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftLivingEntity;
+import org.bukkit.entity.LivingEntity;
+
+import java.util.List;
+
+import static com.captainbern.reflection.matcher.Matchers.withArguments;
+import static com.captainbern.reflection.matcher.Matchers.withType;
+
+/*
+ * From EntityAPI :)
+ */
+
+public class NMSEntityUtil {
+
+ public static NavigationAbstract getNavigation(LivingEntity livingEntity) {
+ if (livingEntity instanceof CraftLivingEntity) {
+ return getNavigation(((CraftLivingEntity) livingEntity).getHandle());
+ }
+ return null;
+ }
+
+ public static NavigationAbstract getNavigation(EntityLiving entityLiving) {
+ if (entityLiving instanceof EntityInsentient) {
+ return ((EntityInsentient) entityLiving).getNavigation();
+ }
+ return null;
+ }
+
+ public static EntitySenses getEntitySenses(LivingEntity livingEntity) {
+ if (livingEntity instanceof CraftLivingEntity) {
+ return getEntitySenses(((CraftLivingEntity) livingEntity).getHandle());
+ }
+ return null;
+ }
+
+ public static EntitySenses getEntitySenses(EntityLiving entityLiving) {
+ if (entityLiving instanceof EntityInsentient) {
+ return ((EntityInsentient) entityLiving).getEntitySenses();
+ }
+ return null;
+ }
+
+ public static ControllerJump getControllerJump(LivingEntity livingEntity) {
+ if (livingEntity instanceof CraftLivingEntity) {
+ return getControllerJump(((CraftLivingEntity) livingEntity).getHandle());
+ }
+ return null;
+ }
+
+ public static ControllerJump getControllerJump(EntityLiving entityLiving) {
+ if (entityLiving instanceof EntityInsentient) {
+ return ((EntityInsentient) entityLiving).getControllerJump();
+ }
+ return null;
+ }
+
+ public static ControllerMove getControllerMove(LivingEntity livingEntity) {
+ if (livingEntity instanceof CraftLivingEntity) {
+ return getControllerMove(((CraftLivingEntity) livingEntity).getHandle());
+ }
+ return null;
+ }
+
+ public static ControllerMove getControllerMove(EntityLiving entityLiving) {
+ if (entityLiving instanceof EntityInsentient) {
+ return ((EntityInsentient) entityLiving).getControllerMove();
+ }
+ return null;
+ }
+
+ public static ControllerLook getControllerLook(LivingEntity livingEntity) {
+ if (livingEntity instanceof CraftLivingEntity) {
+ return getControllerLook(((CraftLivingEntity) livingEntity).getHandle());
+ }
+ return null;
+ }
+
+ public static ControllerLook getControllerLook(EntityLiving entityLiving) {
+ if (entityLiving instanceof EntityInsentient) {
+ return ((EntityInsentient) entityLiving).getControllerLook();
+ }
+ return null;
+ }
+
+ public static boolean isInGuardedAreaOf(EntityLiving entityLiving, int x, int y, int z) {
+ // TODO: not used currently
+ return false;
+ /*if (entityLiving instanceof EntityCreature) {
+ return ((EntityCreature) entityLiving).d(new BlockPosition(x, y, z));
+ } else {
+ return false;
+ }*/
+ }
+
+ /*
+ * Hacky stuff to get around doTick() becoming final
+ */
+
+ protected static FieldAccessor GOALS;
+ protected static FieldAccessor ACTIVE_GOALS;
+
+ protected static MethodAccessor ADD_GOAL;
+
+ protected static FieldAccessor GOAL_SELECTOR;
+
+ public static void clearGoals(Object nmsEntityHandle) {
+ if (GOALS == null || ACTIVE_GOALS == null || GOAL_SELECTOR == null) {
+ initializeFields();
+ }
+
+ GOALS.get(GOAL_SELECTOR.get(nmsEntityHandle)).clear();
+ ACTIVE_GOALS.get(GOAL_SELECTOR.get(nmsEntityHandle)).clear();
+ }
+
+ protected static void initializeFields() {
+ try {
+
+ ClassTemplate goalTemplate = new Reflection().reflect(MinecraftReflection.getMinecraftClass("PathfinderGoalSelector"));
+
+ List> methodCandidates = goalTemplate.getSafeMethods(withArguments(int.class, MinecraftReflection.getMinecraftClass("PathfinderGoal")));
+ if (methodCandidates.size() > 0) {
+ ADD_GOAL = methodCandidates.get(0).getAccessor();
+ } else {
+ throw new RuntimeException("Failed to get the addGoal method!");
+ }
+
+ List> fieldCandidates = goalTemplate.getSafeFields(withType(List.class));
+ if (fieldCandidates.size() > 1) {
+ GOALS = fieldCandidates.get(0).getAccessor();
+ ACTIVE_GOALS = fieldCandidates.get(0).getAccessor();
+ } else {
+ throw new RuntimeException("Failed to initialize the goal-lists!");
+ }
+
+ // The GoalSelector
+ ClassTemplate entityTemplate = new Reflection().reflect(MinecraftReflection.getMinecraftClass("EntityInsentient"));
+ List> candidates = entityTemplate.getSafeFields(withType(goalTemplate.getReflectedClass()));
+
+ if (candidates.size() > 0) {
+ GOAL_SELECTOR = candidates.get(0).getAccessor(); // the normal selector is the first one
+ } else {
+ throw new RuntimeException("Failed to initialize the GoalSelector field for the entities");
+ }
+
+ } catch (Exception ಠ_ಠ) {
+ throw new RuntimeException("Failed to initialize the goal-related fields!", ಠ_ಠ);
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/SpawnUtil.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/SpawnUtil.java
new file mode 100644
index 00000000..653559d1
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/SpawnUtil.java
@@ -0,0 +1,61 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2;
+
+import com.dsh105.commodus.particle.Particle;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.event.PetPreSpawnEvent;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.api.util.ISpawnUtil;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+import org.bukkit.ChatColor;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_8_R2.CraftWorld;
+import org.bukkit.entity.Player;
+import org.bukkit.event.entity.CreatureSpawnEvent;
+
+public class SpawnUtil implements ISpawnUtil {
+
+ @Override
+ public EntityPet spawn(IPet pet, Player owner) {
+ Location l = owner.getLocation();
+ PetPreSpawnEvent spawnEvent = new PetPreSpawnEvent(pet, l);
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(spawnEvent);
+ if (spawnEvent.isCancelled()) {
+ owner.sendMessage(EchoPet.getPrefix() + ChatColor.YELLOW + "Pet spawn was cancelled externally.");
+ EchoPet.getManager().removePet(pet, true);
+ return null;
+ }
+ l = spawnEvent.getSpawnLocation();
+ World mcWorld = ((CraftWorld) l.getWorld()).getHandle();
+ EntityPet entityPet = (EntityPet) pet.getPetType().getNewEntityPetInstance(mcWorld, pet);
+
+ entityPet.setLocation(new Location(mcWorld.getWorld(), l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch()));
+ if (!l.getChunk().isLoaded()) {
+ l.getChunk().load();
+ }
+ if (!mcWorld.addEntity(entityPet, CreatureSpawnEvent.SpawnReason.CUSTOM)) {
+ owner.sendMessage(EchoPet.getPrefix() + ChatColor.YELLOW + "Failed to spawn pet entity.");
+ EchoPet.getManager().removePet(pet, true);
+ } else {
+ Particle.MAGIC_RUNES.builder().at(l).show();
+ }
+ return entityPet;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityAgeablePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityAgeablePet.java
new file mode 100644
index 00000000..0aab8843
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityAgeablePet.java
@@ -0,0 +1,95 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity;
+
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.SizeCategory;
+import net.minecraft.server.v1_8_R2.World;
+
+public abstract class EntityAgeablePet extends EntityPet {
+
+ private boolean ageLocked = true;
+
+ public EntityAgeablePet(World world) {
+ super(world);
+ }
+
+ public EntityAgeablePet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ public int getAge() {
+ return this.datawatcher.getByte(12);
+ }
+
+ public void setAge(int i) {
+ this.datawatcher.watch(12, (byte) (i < 0 ? -1 : (i >= 6000 ? 1 : 0)));
+ }
+
+ public boolean isAgeLocked() {
+ return ageLocked;
+ }
+
+ public void setAgeLocked(boolean ageLocked) {
+ this.ageLocked = ageLocked;
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(12, new Byte((byte) 0));
+ }
+
+ @Override
+ public void m() {
+ super.m();
+ if (!(this.world.isClientSide || this.ageLocked)) {
+ int i = this.getAge();
+
+ if (i < 0) {
+ ++i;
+ this.setAge(i);
+ } else if (i > 0) {
+ --i;
+ this.setAge(i);
+ }
+ }
+ }
+
+ public void setBaby(boolean flag) {
+ if (flag) {
+ this.datawatcher.watch(12, (byte) -1);
+ } else {
+ this.datawatcher.watch(12, (byte) 0);
+ }
+ }
+
+ @Override
+ public boolean isBaby() {
+ return this.datawatcher.getByte(12) < 0;
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ if (this.isBaby()) {
+ return SizeCategory.TINY;
+ } else {
+ return SizeCategory.REGULAR;
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityNoClipPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityNoClipPet.java
new file mode 100644
index 00000000..26ebcf01
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityNoClipPet.java
@@ -0,0 +1,37 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity;
+
+import com.dsh105.echopet.compat.api.entity.IPet;
+import net.minecraft.server.v1_8_R2.World;
+
+
+public abstract class EntityNoClipPet extends EntityPet {
+
+ public EntityNoClipPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ protected EntityNoClipPet(World world) {
+ super(world);
+ }
+
+ public void noClip(boolean flag) {
+ this.noclip = flag;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityPet.java
new file mode 100644
index 00000000..aeb8bf1b
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/EntityPet.java
@@ -0,0 +1,537 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity;
+
+import com.dsh105.commodus.IdentUtil;
+import com.dsh105.echopet.compat.api.ai.PetGoalSelector;
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.event.PetAttackEvent;
+import com.dsh105.echopet.compat.api.event.PetRideJumpEvent;
+import com.dsh105.echopet.compat.api.event.PetRideMoveEvent;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.api.util.Logger;
+import com.dsh105.echopet.compat.api.util.MenuUtil;
+import com.dsh105.echopet.compat.api.util.Perm;
+import com.dsh105.echopet.compat.api.util.menu.MenuOption;
+import com.dsh105.echopet.compat.api.util.menu.PetMenu;
+import com.dsh105.echopet.compat.nms.v1_8_R2.NMSEntityUtil;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.ai.PetGoalFloat;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.ai.PetGoalFollowOwner;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.ai.PetGoalLookAtPlayer;
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_8_R2.CraftWorld;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftCreature;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftLivingEntity;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer;
+import org.bukkit.entity.LivingEntity;
+import org.bukkit.entity.Player;
+import org.bukkit.util.Vector;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Random;
+
+public abstract class EntityPet extends EntityCreature implements IAnimal, IEntityPet {
+
+ protected IPet pet;
+ public PetGoalSelector petGoalSelector;
+
+ protected static Field FIELD_JUMP = null;
+ protected double jumpHeight;
+
+ protected float rideSpeed;
+ public EntityLiving goalTarget = null;
+ public boolean shouldVanish;
+
+ public EntityPet(World world) {
+ super(world);
+ }
+
+ public EntityPet(World world, IPet pet) {
+ super(world);
+ this.pet = pet;
+ this.initiateEntityPet();
+ }
+
+ private void initiateEntityPet() {
+ this.resetEntitySize();
+ this.fireProof = true;
+ if (this.FIELD_JUMP == null) {
+ try {
+ this.FIELD_JUMP = EntityLiving.class.getDeclaredField("aY");
+ this.FIELD_JUMP.setAccessible(true);
+ } catch (NoSuchFieldException e) {
+ e.printStackTrace();
+ }
+ }
+ this.getBukkitEntity().setMaxHealth(pet.getPetType().getMaxHealth());
+ this.setHealth((float) pet.getPetType().getMaxHealth());
+ this.jumpHeight = EchoPet.getOptions().getRideJumpHeight(this.getPet().getPetType());
+ this.rideSpeed = EchoPet.getOptions().getRideSpeed(this.getPet().getPetType());
+ this.setPathfinding();
+ }
+
+ public PetType getEntityPetType() {
+ EntityPetType entityPetType = this.getClass().getAnnotation(EntityPetType.class);
+ if (entityPetType != null) {
+ return entityPetType.petType();
+ }
+ return null;
+ }
+
+ @Override
+ public void resizeBoundingBox(boolean flag) {
+ EntitySize es = this.getClass().getAnnotation(EntitySize.class);
+ if (es != null) {
+ this.setSize(flag ? (es.width() / 2) : es.width(), flag ? (es.height() / 2) : es.height());
+ }
+ }
+
+ @Override
+ public void resetEntitySize() {
+ EntitySize es = this.getClass().getAnnotation(EntitySize.class);
+ if (es != null) {
+ this.setSize(es.width(), es.height());
+ }
+ }
+
+ @Override
+ public void setEntitySize(float width, float height) {
+ this.setSize(width, height);
+ }
+
+ @Override
+ public boolean isPersistent() {
+ return true;
+ }
+
+ public IPet getPet() {
+ return this.pet;
+ }
+
+ public Player getPlayerOwner() {
+ return pet.getOwner();
+ }
+
+ public Location getLocation() {
+ return this.pet.getLocation();
+ }
+
+ public void setVelocity(Vector vel) {
+ this.motX = vel.getX();
+ this.motY = vel.getY();
+ this.motZ = vel.getZ();
+ this.velocityChanged = true;
+ }
+
+ public Random random() {
+ return this.random;
+ }
+
+ @Override
+ public PetGoalSelector getPetGoalSelector() {
+ return petGoalSelector;
+ }
+
+ @Override
+ public boolean isDead() {
+ return dead;
+ }
+
+ @Override
+ public void setShouldVanish(boolean flag) {
+ this.shouldVanish = flag;
+ }
+
+ @Override
+ public void setTarget(LivingEntity livingEntity) {
+ this.setGoalTarget(((CraftLivingEntity) livingEntity).getHandle());
+ }
+
+ @Override
+ public LivingEntity getTarget() {
+ return (LivingEntity) this.getGoalTarget().getBukkitEntity();
+ }
+
+ public boolean attack(Entity entity) {
+ return this.attack(entity, (float) this.getPet().getPetType().getAttackDamage());
+ }
+
+ public boolean attack(Entity entity, float damage) {
+ return this.attack(entity, DamageSource.mobAttack(this), damage);
+ }
+
+ public boolean attack(Entity entity, DamageSource damageSource, float damage) {
+ PetAttackEvent attackEvent = new PetAttackEvent(this.getPet(), entity.getBukkitEntity(), damage);
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(attackEvent);
+ if (!attackEvent.isCancelled()) {
+ if (entity instanceof EntityPlayer) {
+ if (!(EchoPet.getConfig().getBoolean("canAttackPlayers", false))) {
+ return false;
+ }
+ }
+ return entity.damageEntity(damageSource, (float) attackEvent.getDamage());
+ }
+ return false;
+ }
+
+ public void setPathfinding() {
+ try {
+ NMSEntityUtil.clearGoals(this);
+ this.petGoalSelector = new PetGoalSelector();
+
+ petGoalSelector.addGoal(new PetGoalFloat(this), 0);
+ petGoalSelector.addGoal(new PetGoalFollowOwner(this, this.getSizeCategory().getStartWalk(getPet().getPetType()), this.getSizeCategory().getStopWalk(getPet().getPetType()), this.getSizeCategory().getTeleport(getPet().getPetType())), 1);
+ petGoalSelector.addGoal(new PetGoalLookAtPlayer(this, EntityHuman.class), 2);
+
+ } catch (Exception e) {
+ Logger.log(Logger.LogLevel.WARNING, "Could not add PetGoals to Pet AI.", e, true);
+ }
+ }
+
+ @Override
+ public CraftCreature getBukkitEntity() {
+ return (CraftCreature) super.getBukkitEntity();
+ }
+
+ // well then...it's now 'final'
+
+ /*
+ // Overriden from EntityInsentient - Most importantly overrides pathfinding selectors
+ @Override
+ protected final void doTick() {
+ super.doTick();
+ ++this.ticksFarFromPlayer;
+
+ this.D();
+
+ this.getEntitySenses().a();
+
+ // If this ever happens...
+ if (this.petGoalSelector == null) {
+ this.remove(false);
+ return;
+ }
+ this.petGoalSelector.updateGoals();
+
+ this.navigation.k();
+
+ this.E();
+
+ this.getControllerMove().c();
+
+ this.getControllerLook().a();
+
+ this.getControllerJump().b();
+ }
+ */
+
+ @Override
+ public boolean onInteract(Player p) {
+ if (IdentUtil.areIdentical(p, getPlayerOwner())) {
+ if (EchoPet.getConfig().getBoolean("pets." + this.getPet().getPetType().toString().toLowerCase().replace("_", " ") + ".interactMenu", true) && Perm.BASE_MENU.hasPerm(this.getPlayerOwner(), false, false)) {
+ ArrayList options = MenuUtil.createOptionList(getPet().getPetType());
+ int size = this.getPet().getPetType() == PetType.HORSE ? 18 : 9;
+ PetMenu menu = new PetMenu(getPet(), options, size);
+ menu.open(false);
+ }
+ return true;
+ }
+ return false;
+ }
+
+ @Override
+ public boolean a(EntityHuman human) {
+ return onInteract((Player) human.getBukkitEntity());
+ }
+
+ @Override
+ public void setPositionRotation(double d0, double d1, double d2, float f, float f1) {
+ super.setPositionRotation(d0, d1, d2, f, f1);
+ }
+
+ public void setLocation(Location l) {
+ this.setLocation(l.getX(), l.getY(), l.getZ(), l.getYaw(), l.getPitch());
+ this.world = ((CraftWorld) l.getWorld()).getHandle();
+ }
+
+ public void teleport(Location l) {
+ this.getPet().getCraftPet().teleport(l);
+ }
+
+ @Override
+ public void remove(boolean makeSound) {
+ if (this.bukkitEntity != null) {
+ bukkitEntity.remove();
+ }
+ if (makeSound) {
+ String sound = this.getDeathSound();
+ if (sound != null) {
+ makeSound(this.getDeathSound(), 1.0F, 1.0F);
+ }
+ }
+ }
+
+ public void onLive() {
+ if (this.pet == null) {
+ this.remove(false);
+ return;
+ }
+
+ if (this.getPlayerOwner() == null || !this.getPlayerOwner().isOnline()) {
+ EchoPet.getManager().removePet(this.getPet(), true);
+ return;
+ }
+
+ if (pet.isOwnerRiding() && this.passenger == null && !pet.isOwnerInMountingProcess()) {
+ pet.ownerRidePet(false);
+ }
+
+ if (((CraftPlayer) this.getPlayerOwner()).getHandle().isInvisible() != this.isInvisible() && !this.shouldVanish) {
+ this.setInvisible(!this.isInvisible());
+ }
+
+ if (((CraftPlayer) this.getPlayerOwner()).getHandle().isSneaking() != this.isSneaking()) {
+ this.setSneaking(!this.isSneaking());
+ }
+
+ if (((CraftPlayer) this.getPlayerOwner()).getHandle().isSprinting() != this.isSprinting()) {
+ this.setSprinting(!this.isSprinting());
+ }
+
+ if (this.getPet().isHat()) {
+ this.lastYaw = this.yaw = (this.getPet().getPetType() == PetType.ENDERDRAGON ? this.getPlayerOwner().getLocation().getYaw() - 180 : this.getPlayerOwner().getLocation().getYaw());
+ }
+
+ if (this.getPlayerOwner().isFlying() && EchoPet.getOptions().canFly(this.getPet().getPetType())) {
+ Location petLoc = this.getLocation();
+ Location ownerLoc = this.getPlayerOwner().getLocation();
+ Vector v = ownerLoc.toVector().subtract(petLoc.toVector());
+
+ double x = v.getX();
+ double y = v.getY();
+ double z = v.getZ();
+
+ Vector vo = this.getPlayerOwner().getLocation().getDirection();
+ if (vo.getX() > 0) {
+ x -= 1.5;
+ } else if (vo.getX() < 0) {
+ x += 1.5;
+ }
+ if (vo.getZ() > 0) {
+ z -= 1.5;
+ } else if (vo.getZ() < 0) {
+ z += 1.5;
+ }
+
+ this.setVelocity(new Vector(x, y, z).normalize().multiply(0.3F));
+ }
+ }
+
+ // EntityInsentient
+ @Override
+ public void g(float sideMot, float forwMot) {
+ if (this.passenger == null || !(this.passenger instanceof EntityHuman)) {
+ super.g(sideMot, forwMot);
+ this.S = 0.5F;
+ return;
+ }
+ EntityHuman human = (EntityHuman) this.passenger;
+ if (human.getBukkitEntity() != this.getPlayerOwner().getPlayer()) {
+ super.g(sideMot, forwMot);
+ this.S = 0.5F;
+ return;
+ }
+
+ this.S = 1.0F;
+
+ this.lastYaw = this.yaw = this.passenger.yaw;
+ this.pitch = this.passenger.pitch * 0.5F;
+ this.setYawPitch(this.yaw, this.pitch);
+ this.aI = this.aG = this.yaw;
+
+ sideMot = ((EntityLiving) this.passenger).aZ * 0.5F;
+ forwMot = ((EntityLiving) this.passenger).ba;
+
+ if (forwMot <= 0.0F) {
+ forwMot *= 0.25F;
+ }
+ sideMot *= 0.75F;
+
+ PetRideMoveEvent moveEvent = new PetRideMoveEvent(this.getPet(), forwMot, sideMot);
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(moveEvent);
+ if (moveEvent.isCancelled()) {
+ return;
+ }
+
+ this.k(this.rideSpeed);
+ super.g(moveEvent.getSidewardMotionSpeed(), moveEvent.getForwardMotionSpeed());
+
+ PetType pt = this.getPet().getPetType();
+ if (FIELD_JUMP != null && this.passenger != null) {
+ if (EchoPet.getOptions().canFly(pt)) {
+ try {
+ if (((Player) (human.getBukkitEntity())).isFlying()) {
+ ((Player) (human.getBukkitEntity())).setFlying(false);
+ }
+ if (FIELD_JUMP.getBoolean(this.passenger)) {
+ PetRideJumpEvent rideEvent = new PetRideJumpEvent(this.getPet(), this.jumpHeight);
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(rideEvent);
+ if (!rideEvent.isCancelled()) {
+ this.motY = 0.5F;
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate Pet Flying Motion for " + this.getPlayerOwner().getName() + "'s Pet.", e, true);
+ } catch (IllegalAccessException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate Pet Flying Motion for " + this.getPlayerOwner().getName() + "'s Pet.", e, true);
+ } catch (IllegalStateException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate Pet Flying Motion for " + this.getPlayerOwner().getName() + "'s Pet.", e, true);
+ }
+ } else if (this.onGround) {
+ try {
+ if (FIELD_JUMP.getBoolean(this.passenger)) {
+ PetRideJumpEvent rideEvent = new PetRideJumpEvent(this.getPet(), this.jumpHeight);
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(rideEvent);
+ if (!rideEvent.isCancelled()) {
+ this.motY = rideEvent.getJumpHeight();
+ doJumpAnimation();
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate Pet Jumping Motion for " + this.getPlayerOwner().getName() + "'s Pet.", e, true);
+ } catch (IllegalAccessException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate Pet Jumping Motion for " + this.getPlayerOwner().getName() + "'s Pet.", e, true);
+ } catch (IllegalStateException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate Pet Jumping Motion for " + this.getPlayerOwner().getName() + "'s Pet.", e, true);
+ }
+ }
+ }
+ }
+
+ // EntityInsentient
+ @Override
+ protected String z() {
+ return this.getIdleSound();
+ }
+
+ // EntityInsentient
+ @Override
+ protected String bo() {
+ return this.getDeathSound();
+ }
+
+ protected abstract String getIdleSound(); //idle sound
+
+ protected abstract String getDeathSound(); //death sound
+
+ @Override
+ public abstract SizeCategory getSizeCategory();
+
+ // Entity
+ @Override
+ public void t_() {
+ super.t_();
+ //this.C();
+ onLive();
+
+
+ if (this.petGoalSelector == null) {
+ this.remove(false);
+ return;
+ }
+ this.petGoalSelector.updateGoals();
+ }
+
+ // EntityLiving
+ @Override
+ protected void h() {
+ super.h();
+ initDatawatcher();
+ }
+
+ // Entity
+ @Override
+ protected void a(BlockPosition blockposition, Block block) {
+ super.a(blockposition, block);
+ this.a(blockposition.getX(), blockposition.getY(), blockposition.getZ(), block);
+ }
+
+ protected void a(int i, int j, int k, Block block) {
+ super.a(new BlockPosition(i, j, k), block);
+ makeStepSound(i, j, k, block);
+ }
+
+ protected void makeStepSound(int i, int j, int k, Block block) {
+ this.makeStepSound();
+ }
+
+ protected void initDatawatcher() {
+ }
+
+ protected void makeStepSound() {
+ }
+
+ protected void doJumpAnimation() {
+ }
+
+
+ @Override
+ public void b(NBTTagCompound nbttagcompound) {
+ // Do nothing with NBT
+ // Pets should not be stored to world save files
+ }
+
+ @Override
+ public boolean c(NBTTagCompound nbttagcompound) {
+ // Do nothing with NBT
+ // Pets should not be stored to world save files
+ return false;
+ }
+
+ @Override
+ public void a(NBTTagCompound nbttagcompound) {
+ // Do nothing with NBT
+ // Pets should not be stored to world save files
+
+ /*super.a(nbttagcompound);
+ String owner = nbttagcompound.getString("EchoPet_OwnerName");
+ PetType pt = this.getEntityPetType();
+ if (pt != null) {
+ this.pet = pt.getNewPetInstance(owner, this);
+ if (this.pet != null) {
+ EchoPet.getManager().loadRiderFromFile(this.getPet());
+ this.initiateEntityPet();
+ }
+ }*/
+ }
+
+ @Override
+ public boolean d(NBTTagCompound nbttagcompound) {
+ // Do nothing with NBT
+ // Pets should not be stored to world save files
+ return false;
+ }
+
+ @Override
+ public void e(NBTTagCompound nbttagcompound) {
+ // Do nothing with NBT
+ // Pets should not be stored to world save files
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalFloat.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalFloat.java
new file mode 100644
index 00000000..d06dc6c5
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalFloat.java
@@ -0,0 +1,55 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.ai;
+
+import com.dsh105.echopet.compat.api.ai.APetGoalFloat;
+import com.dsh105.echopet.compat.api.ai.PetGoalType;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.Navigation;
+
+public class PetGoalFloat extends APetGoalFloat {
+
+ private EntityPet pet;
+
+ public PetGoalFloat(EntityPet pet) {
+ this.pet = pet;
+ ((Navigation) pet.getNavigation()).d(true);
+ }
+
+ @Override
+ public PetGoalType getType() {
+ return PetGoalType.FOUR;
+ }
+
+ @Override
+ public String getDefaultKey() {
+ return "Float";
+ }
+
+ @Override
+ public boolean shouldStart() {
+ return this.pet.V() || this.pet.ab();
+ }
+
+ @Override
+ public void tick() {
+ if (this.pet.random().nextFloat() < 0.8F) {
+ this.pet.getControllerJump().a();
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalFollowOwner.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalFollowOwner.java
new file mode 100644
index 00000000..1bd78555
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalFollowOwner.java
@@ -0,0 +1,147 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.ai;
+
+import com.dsh105.echopet.compat.api.ai.APetGoalFollowOwner;
+import com.dsh105.echopet.compat.api.ai.PetGoalType;
+import com.dsh105.echopet.compat.api.event.PetMoveEvent;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.type.EntityEnderDragonPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.type.EntityGhastPet;
+import net.minecraft.server.v1_8_R2.EntityPlayer;
+import net.minecraft.server.v1_8_R2.GenericAttributes;
+import net.minecraft.server.v1_8_R2.Navigation;
+import net.minecraft.server.v1_8_R2.PathEntity;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer;
+
+
+public class PetGoalFollowOwner extends APetGoalFollowOwner {
+
+ private EntityPet pet;
+ private Navigation nav;
+ private int timer = 0;
+ private double startDistance;
+ private double stopDistance;
+ private double teleportDistance;
+ //private EntityPlayer owner;
+
+ public PetGoalFollowOwner(EntityPet pet, double startDistance, double stopDistance, double teleportDistance) {
+ this.pet = pet;
+ this.nav = (Navigation) pet.getNavigation();
+ this.startDistance = startDistance;
+ this.stopDistance = stopDistance;
+ this.teleportDistance = teleportDistance;
+ //this.owner = ((CraftPlayer) pet.getPlayerOwner()).getHandle();
+ }
+
+ @Override
+ public PetGoalType getType() {
+ return PetGoalType.THREE;
+ }
+
+ @Override
+ public String getDefaultKey() {
+ return "FollowOwner";
+ }
+
+ @Override
+ public boolean shouldStart() {
+ if (!this.pet.isAlive()) {
+ return false;
+ } else if (this.pet.getPlayerOwner() == null) {
+ return false;
+ } else if (this.pet.getPet().isOwnerRiding() || this.pet.getPet().isHat()) {
+ return false;
+ } else if (this.pet.h(((CraftPlayer) this.pet.getPlayerOwner()).getHandle()) < this.startDistance) {
+ return false;
+ } else if (this.pet instanceof EntityEnderDragonPet) {
+ return false;
+ } else {
+ return !(this.pet.getGoalTarget() != null && this.pet.getGoalTarget().isAlive());
+ }
+
+ }
+
+ @Override
+ public boolean shouldContinue() {
+ if (this.nav.g()) {
+ return false;
+ } else if (this.pet.getPlayerOwner() == null) {
+ return false;
+ } else if (this.pet.getPet().isOwnerRiding() || this.pet.getPet().isHat()) {
+ return false;
+ } else if (this.pet.h(((CraftPlayer) this.pet.getPlayerOwner()).getHandle()) <= this.stopDistance) {
+ return false;
+ }
+ //PetGoalMeleeAttack attackGoal = (PetGoalMeleeAttack) this.pet.petGoalSelector.getGoal("Attack");
+ //return !(attackGoal != null && attackGoal.isActive);
+ return true;
+ }
+
+ @Override
+ public void start() {
+ this.timer = 0;
+
+ //Set pathfinding radius
+ pet.getAttributeInstance(GenericAttributes.b).setValue(this.teleportDistance);
+ }
+
+ @Override
+ public void finish() {
+ this.nav.n();
+ }
+
+ @Override
+ public void tick() {
+ //https://github.com/Bukkit/mc-dev/blob/master/net/minecraft/server/PathfinderGoalFollowOwner.java#L57
+ EntityPlayer owner = ((CraftPlayer) this.pet.getPlayerOwner()).getHandle();
+ this.pet.getControllerLook().a(owner, 10.0F, (float) this.pet.bQ());
+ if (--this.timer <= 0) {
+ this.timer = 10;
+ if (this.pet.getPlayerOwner().isFlying()) {
+ //Don't move pet when owner flying
+ return;
+ }
+
+ double speed = 0.6F;
+ if (this.pet.h(owner) > (this.teleportDistance) && ((CraftPlayer) this.pet.getPlayerOwner()).getHandle().onGround) {
+ this.pet.getPet().teleportToOwner();
+ return;
+ }
+
+ PetMoveEvent moveEvent = new PetMoveEvent(this.pet.getPet(), this.pet.getLocation(), this.pet.getPlayerOwner().getLocation());
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(moveEvent);
+ if (moveEvent.isCancelled()) {
+ return;
+ }
+
+ if (pet.goalTarget == null) {
+ PathEntity path;
+ if (pet instanceof EntityGhastPet) {
+ path = pet.getNavigation().a(pet.getPlayerOwner().getLocation().getBlockX(), pet.getPlayerOwner().getLocation().getBlockY() + 5, pet.getPlayerOwner().getLocation().getBlockZ());
+ } else {
+ path = pet.getNavigation().a(owner);
+ }
+
+ //Smooth path finding to entity instead of location
+ pet.getNavigation().a(path, speed);
+ }
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalLookAtPlayer.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalLookAtPlayer.java
new file mode 100644
index 00000000..15b17798
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/ai/PetGoalLookAtPlayer.java
@@ -0,0 +1,95 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.ai;
+
+import com.dsh105.echopet.compat.api.ai.APetGoalLookAtPlayer;
+import com.dsh105.echopet.compat.api.ai.PetGoalType;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.Entity;
+import net.minecraft.server.v1_8_R2.EntityHuman;
+
+public class PetGoalLookAtPlayer extends APetGoalLookAtPlayer {
+
+ private EntityPet pet;
+ protected Entity player;
+ private float range;
+ private int ticksLeft;
+ private float chance;
+ private Class clazz;
+
+ public PetGoalLookAtPlayer(EntityPet pet, Class c) {
+ this.pet = pet;
+ this.range = 8.0F;
+ this.chance = 0.02F;
+ this.clazz = c;
+ }
+
+ public PetGoalLookAtPlayer(EntityPet pet, Class c, float f, float f1) {
+ this.pet = pet;
+ this.range = f;
+ this.chance = f1;
+ this.clazz = c;
+ }
+
+ @Override
+ public PetGoalType getType() {
+ return PetGoalType.TWO;
+ }
+
+ @Override
+ public String getDefaultKey() {
+ return "LookAtPlayer";
+ }
+
+ @Override
+ public boolean shouldStart() {
+ if (this.pet.random().nextFloat() >= this.chance) {
+ return false;
+ } else if (this.pet.passenger != null) {
+ return false;
+ } else {
+ if (this.clazz == EntityHuman.class) {
+ this.player = this.pet.world.findNearbyPlayer(this.pet, (double) this.range);
+ } else {
+ this.player = this.pet.world.a(this.clazz, this.pet.getBoundingBox().grow((double) this.range, 3.0D, (double) this.range), this.pet);
+ }
+ return this.player != null;
+ }
+ }
+
+ @Override
+ public boolean shouldContinue() {
+ return this.player.isAlive() && (this.pet.h(this.player) <= (double) (this.range * this.range) && this.ticksLeft > 0);
+ }
+
+ @Override
+ public void start() {
+ this.ticksLeft = 40 + this.pet.random().nextInt(40);
+ }
+
+ @Override
+ public void finish() {
+ this.player = null;
+ }
+
+ @Override
+ public void tick() {
+ this.pet.getControllerLook().a(this.player.locX, this.player.locY + (double) this.player.getHeadHeight(), this.player.locZ, 10.0F, (float) this.pet.bQ());
+ --this.ticksLeft;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityBatPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityBatPet.java
new file mode 100644
index 00000000..8abcf47f
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityBatPet.java
@@ -0,0 +1,83 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityBatPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.MathHelper;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.5F, height = 0.9F)
+@EntityPetType(petType = PetType.BAT)
+public class EntityBatPet extends EntityPet implements IEntityBatPet {
+
+ public EntityBatPet(World world) {
+ super(world);
+ }
+
+ public EntityBatPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public void setHanging(boolean flag) {
+ byte b0 = this.datawatcher.getByte(16);
+ if (flag) {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 1)));
+ } else {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -2)));
+ }
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return this.isStartled() && this.random.nextInt(4) != 0 ? null : "mob.bat.idle";
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+ if (this.isStartled()) {
+ this.motX = this.motY = this.motZ = 0.0D;
+ this.locY = (double) MathHelper.floor(this.locY) + 1.0D - (double) this.length;
+ } else {
+ this.motY *= 0.6000000238418579D;
+ }
+ }
+
+ public boolean isStartled() {
+ return (this.datawatcher.getByte(16) & 1) != 0;
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.bat.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.TINY;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityBlazePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityBlazePet.java
new file mode 100644
index 00000000..a5d4703e
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityBlazePet.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityBlazePet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 1.7F)
+@EntityPetType(petType = PetType.BLAZE)
+public class EntityBlazePet extends EntityPet implements IEntityBlazePet {
+
+ public EntityBlazePet(World world) {
+ super(world);
+ }
+
+ public EntityBlazePet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public void setOnFire(boolean flag) {
+ this.datawatcher.watch(16, (byte) (flag ? 1 : 0));
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.blaze.breathe";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.blaze.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCaveSpiderPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCaveSpiderPet.java
new file mode 100644
index 00000000..eda34d29
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCaveSpiderPet.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityCaveSpiderPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.7F, height = 0.5F)
+@EntityPetType(petType = PetType.CAVESPIDER)
+public class EntityCaveSpiderPet extends EntityPet implements IEntityCaveSpiderPet {
+
+ EntityCaveSpiderPet(World world) {
+ super(world);
+ }
+
+ public EntityCaveSpiderPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 0));
+ }
+
+ @Override
+ protected void makeStepSound() {
+ makeSound("mob.spider.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.spider.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.spider.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityChickenPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityChickenPet.java
new file mode 100644
index 00000000..9961c3c2
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityChickenPet.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityChickenPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.3F, height = 0.7F)
+@EntityPetType(petType = PetType.CHICKEN)
+public class EntityChickenPet extends EntityAgeablePet implements IEntityChickenPet {
+
+ public EntityChickenPet(World world) {
+ super(world);
+ }
+
+ public EntityChickenPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.chicken.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.chicken.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.chicken.hurt";
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCowPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCowPet.java
new file mode 100644
index 00000000..773b612b
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCowPet.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityCowPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.9F, height = 1.3F)
+@EntityPetType(petType = PetType.COW)
+public class EntityCowPet extends EntityAgeablePet implements IEntityCowPet {
+
+ public EntityCowPet(World world) {
+ super(world);
+ }
+
+ public EntityCowPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.cow.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.cow.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.cow.hurt";
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCreeperPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCreeperPet.java
new file mode 100644
index 00000000..50a496cf
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityCreeperPet.java
@@ -0,0 +1,69 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityCreeperPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 1.9F)
+@EntityPetType(petType = PetType.CREEPER)
+public class EntityCreeperPet extends EntityPet implements IEntityCreeperPet {
+
+ public EntityCreeperPet(World world) {
+ super(world);
+ }
+
+ public EntityCreeperPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public void setPowered(boolean flag) {
+ this.datawatcher.watch(17, Byte.valueOf((byte) (flag ? 1 : 0)));
+ }
+
+ @Override
+ public void setIgnited(boolean flag) {
+ this.datawatcher.watch(18, Byte.valueOf((byte) (flag ? 1 : 0)));
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, Byte.valueOf((byte) -1));
+ this.datawatcher.a(17, Byte.valueOf((byte) 0));
+ this.datawatcher.a(18, Byte.valueOf((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.creeper.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEnderDragonPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEnderDragonPet.java
new file mode 100644
index 00000000..386c940c
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEnderDragonPet.java
@@ -0,0 +1,449 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityEnderDragonPet;
+import com.dsh105.echopet.compat.api.event.PetRideJumpEvent;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.api.util.Logger;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityNoClipPet;
+import com.google.common.collect.Lists;
+import net.minecraft.server.v1_8_R2.*;
+import org.bukkit.Location;
+import org.bukkit.craftbukkit.v1_8_R2.entity.CraftPlayer;
+import org.bukkit.util.Vector;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+@EntitySize(width = 16.0F, height = 8.0F)
+@EntityPetType(petType = PetType.ENDERDRAGON)
+public class EntityEnderDragonPet extends EntityNoClipPet implements IComplex, IMonster, IEntityEnderDragonPet {
+
+ // TODO: ugly :(
+
+ private double a;
+ private double b;
+ private double c;
+ public int bl = -1;
+ public double[][] bk = new double[64][3];
+ private EntityComplexPart[] children;
+ private EntityComplexPart head;
+ private EntityComplexPart body;
+ private EntityComplexPart tail1;
+ private EntityComplexPart tail2;
+ private EntityComplexPart tail3;
+ private EntityComplexPart wing1;
+ private EntityComplexPart wing2;
+ private float bu;
+ private float bv;
+ private boolean bw;
+ private boolean bx;
+ private int by;
+ private Entity bA;
+
+ public EntityEnderDragonPet(World world) {
+ super(world);
+ }
+
+ public EntityEnderDragonPet(World world, IPet pet) {
+ super(world, pet);
+ this.children = new EntityComplexPart[]{this.head = new EntityComplexPart(this, "head", 6.0F, 6.0F), this.body = new EntityComplexPart(this, "body", 8.0F, 8.0F), this.tail1 = new EntityComplexPart(this, "tail", 4.0F, 4.0F), this.tail2 = new EntityComplexPart(this, "tail", 4.0F, 4.0F), this.tail3 = new EntityComplexPart(this, "tail", 4.0F, 4.0F), this.wing1 = new EntityComplexPart(this, "wing", 4.0F, 4.0F), this.wing2 = new EntityComplexPart(this, "wing", 4.0F, 4.0F)};
+ this.noClip(true);
+ this.b = 100.0D;
+ this.ah = true;
+ }
+
+ @Override
+ public void resizeBoundingBox(boolean flag) {
+ this.setSize(flag ? 8.0F : 16.0F, flag ? 4.0F : 8.0F);
+ }
+
+ public double[] b(int i, float f) {
+ if (this.getHealth() <= 0.0F) {
+ f = 0.0F;
+ }
+
+ f = 1.0F - f;
+ int j = this.bl - i * 1 & 63;
+ int k = this.bl - i * 1 - 1 & 63;
+ double[] adouble = new double[3];
+ double d0 = this.bk[j][0];
+ double d1 = MathHelper.g(this.bk[k][0] - d0);
+
+ adouble[0] = d0 + d1 * (double) f;
+ d0 = this.bk[j][1];
+ d1 = this.bk[k][1] - d0;
+ adouble[1] = d0 + d1 * (double) f;
+ adouble[2] = this.bk[j][2] + (this.bk[k][2] - this.bk[j][2]) * (double) f;
+ return adouble;
+ }
+
+ @Override
+ public void m() {
+ float f;
+ float f1;
+
+ if (this.passenger != null && (this.passenger instanceof EntityHuman)) {
+ EntityHuman human = (EntityHuman) this.passenger;
+ if (human.getBukkitEntity() == this.getPlayerOwner().getPlayer()) {
+ float forw = ((EntityLiving) this.passenger).ba;
+ float side = ((EntityLiving) this.passenger).aZ;
+
+ Vector v = new Vector();
+ Location l = new Location(this.world.getWorld(), this.locX, this.locY, this.locZ);
+
+ if (side < 0.0F) {
+ l.setYaw(this.passenger.yaw - 90);
+ v.add(l.getDirection().normalize().multiply(-0.5));
+ } else if (side > 0.0F) {
+ l.setYaw(this.passenger.yaw + 90);
+ v.add(l.getDirection().normalize().multiply(-0.5));
+ }
+
+ if (forw < 0.0F) {
+ l.setYaw(this.passenger.yaw);
+ v.add(l.getDirection().normalize().multiply(0.5));
+ } else if (forw > 0.0F) {
+ l.setYaw(this.passenger.yaw);
+ v.add(l.getDirection().normalize().multiply(0.5));
+ }
+
+ this.lastYaw = this.yaw = this.passenger.yaw - 180;
+ this.pitch = this.passenger.pitch * 0.5F;
+ this.setYawPitch(this.yaw, this.pitch);
+ this.aI = this.aG = this.yaw;
+
+ if (this.FIELD_JUMP != null) {
+ try {
+ if (this.FIELD_JUMP.getBoolean(this.passenger)) {
+ PetRideJumpEvent rideEvent = new PetRideJumpEvent(this.getPet(), this.jumpHeight);
+ EchoPet.getPlugin().getServer().getPluginManager().callEvent(rideEvent);
+ if (!rideEvent.isCancelled()) {
+ v.setY(0.5F);
+ }
+ } else {
+ if (((EntityLiving) this.passenger).pitch >= 50) {
+ v.setY(-0.4F);
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate LivingPet Flying Motion for " + this.getPlayerOwner().getName() + "'s LivingPet.", e, true);
+ } catch (IllegalAccessException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate LivingPet Flying Motion for " + this.getPlayerOwner().getName() + "'s LivingPet.", e, true);
+ } catch (IllegalStateException e) {
+ Logger.log(Logger.LogLevel.WARNING, "Failed to initiate LivingPet Flying Motion for " + this.getPlayerOwner().getName() + "'s LivingPet.", e, true);
+ }
+ }
+
+ l.add(v.multiply(Math.pow(this.rideSpeed, this.rideSpeed)));
+ this.setPos(l.getX(), l.getY(), l.getZ());
+ this.updateComplexParts();
+ return;
+ }
+ }
+
+ if (this.world.isClientSide) {
+ f = MathHelper.cos(this.bv * 3.1415927F * 2.0F);
+ f1 = MathHelper.cos(this.bu * 3.1415927F * 2.0F);
+ if (f1 <= -0.3F && f >= -0.3F && !this.R()) {
+ this.world.a(this.locX, this.locY, this.locZ, "mob.enderdragon.wings", 5.0F, 0.8F + this.random.nextFloat() * 0.3F, false);
+ }
+ }
+
+ this.bu = this.bv;
+ float f2;
+
+ if (this.getHealth() <= 0.0F) {
+ f = (this.random.nextFloat() - 0.5F) * 8.0F;
+ f1 = (this.random.nextFloat() - 0.5F) * 4.0F;
+ f2 = (this.random.nextFloat() - 0.5F) * 8.0F;
+ this.world.addParticle(EnumParticle.EXPLOSION_LARGE, this.locX + (double) f, this.locY + 2.0D + (double) f1, this.locZ + (double) f2, 0.0D, 0.0D, 0.0D, new int[0]);
+ } else {
+ // For EnderCrystals
+ //this.n();
+
+ f = 0.2F / (MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 10.0F + 1.0F);
+ f *= (float) Math.pow(2.0D, this.motY);
+ if (this.bx) {
+ this.bv += f * 0.5F;
+ } else {
+ this.bv += f;
+ }
+
+ this.yaw = MathHelper.g(this.yaw);
+ if (ce()) {
+ this.bv = 0.5F;
+ } else {
+ if (this.bl < 0) {
+ for (int i = 0; i < this.bk.length; ++i) {
+ this.bk[i][0] = (double) this.yaw;
+ this.bk[i][1] = this.locY;
+ }
+ }
+
+ if (++this.bl == this.bk.length) {
+ this.bl = 0;
+ }
+ }
+
+
+ this.bk[this.bl][0] = (double) this.yaw;
+ this.bk[this.bl][1] = this.locY;
+
+ if (this.world.isClientSide) {
+ if (this.bc > 0) {
+ double d3 = this.locX + (this.bd - this.locX) / this.bc;
+ double d0 = this.locY + (this.be - this.locY) / this.bc;
+ double d1 = this.locZ + (this.bf - this.locZ) / this.bc;
+ double d2 = MathHelper.g(this.bg - this.yaw);
+ this.yaw = ((float) (this.yaw + d2 / this.bc));
+ this.pitch = ((float) (this.pitch + (this.bh - this.pitch) / this.bc));
+ this.bc -= 1;
+ setPosition(d3, d0, d1);
+ setYawPitch(this.yaw, this.pitch);
+ }
+ } else {
+ double d3 = this.a - this.locX;
+ double d0 = this.b - this.locY;
+ double d1 = this.c - this.locZ;
+ double d2 = d3 * d3 + d0 * d0 + d1 * d1;
+ if (this.bA != null) {
+ this.a = this.bA.locX;
+ this.c = this.bA.locZ;
+ double d5 = this.a - this.locX;
+ double d6 = this.c - this.locZ;
+ double d7 = Math.sqrt(d5 * d5 + d6 * d6);
+
+ double d4 = 0.4000000059604645D + d7 / 80.0D - 1.0D;
+ if (d4 > 10.0D) {
+ d4 = 10.0D;
+ }
+ this.b = (this.bA.getBoundingBox().b + d4);
+ } else {
+ this.a += this.random.nextGaussian() * 2.0D;
+ this.c += this.random.nextGaussian() * 2.0D;
+ }
+ if ((this.bw) || (d2 < 100.0D) || (d2 > 22500.0D) || (this.positionChanged) || (this.E)) {
+ target();
+ }
+ d0 /= MathHelper.sqrt(d3 * d3 + d1 * d1);
+ float f3 = 0.6F;
+ d0 = MathHelper.a(d0, -f3, f3);
+ this.motY += d0 * 0.10000000149011612D;
+ this.yaw = MathHelper.g(this.yaw);
+ double d8 = 180.0D - MathHelper.b(d3, d1) * 180.0D / 3.1415927410125732D;
+ double d9 = MathHelper.g(d8 - this.yaw);
+ if (d9 > 50.0D) {
+ d9 = 50.0D;
+ }
+ if (d9 < -50.0D) {
+ d9 = -50.0D;
+ }
+ Vec3D vec3d = new Vec3D(this.a - this.locX, this.b - this.locY, this.c - this.locZ).a();
+
+ double d4 = -MathHelper.cos(this.yaw * 3.1415927F / 180.0F);
+ Vec3D vec3d1 = new Vec3D(MathHelper.sin(this.yaw * 3.1415927F / 180.0F), this.motY, d4).a();
+ float f4 = ((float) vec3d1.b(vec3d) + 0.5F) / 1.5F;
+ if (f4 < 0.0F) {
+ f4 = 0.0F;
+ }
+ this.bb *= 0.8F;
+ float f5 = MathHelper.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 1.0F + 1.0F;
+ double d10 = Math.sqrt(this.motX * this.motX + this.motZ * this.motZ) * 1.0D + 1.0D;
+ if (d10 > 40.0D) {
+ d10 = 40.0D;
+ }
+ this.bb = ((float) (this.bb + d9 * (0.699999988079071D / d10 / f5)));
+ this.yaw += this.bb * 0.1F;
+ float f6 = (float) (2.0D / (d10 + 1.0D));
+ float f7 = 0.06F;
+
+ a(0.0F, -1.0F, f7 * (f4 * f6 + (1.0F - f6)));
+ if (this.bx) {
+ move(this.motX * 0.800000011920929D, this.motY * 0.800000011920929D, this.motZ * 0.800000011920929D);
+ } else {
+ move(this.motX, this.motY, this.motZ);
+ }
+ Vec3D vec3d2 = new Vec3D(this.motX, this.motY, this.motZ).a();
+ float f8 = ((float) vec3d2.b(vec3d1) + 1.0F) / 2.0F;
+
+ f8 = 0.8F + 0.15F * f8;
+ this.motX *= f8;
+ this.motZ *= f8;
+ this.motY *= 0.9100000262260437D;
+ }
+
+ this.updateComplexParts();
+
+ //Nope, absolutely no destruction
+ /*if (!this.world.isStatic) {
+ this.bx = this.a(this.head.getBoundingBox()) | this.a(this.body.getBoundingBox());
+ }*/
+ }
+ }
+
+ private void setPos(double x, double y, double z) {
+ double[] d0 = new double[]{x, y, z};
+ double[] d1 = new double[]{this.locX, this.locY, this.locZ};
+ for (int i = 0; i < 3; i++) {
+ if (this.world.getWorld().getBlockAt((int) x, (int) y, (int) z).getType().isSolid()) {
+ d0[i] = d1[i];
+ }
+ }
+ this.setPosition(d0[0], d0[1], d0[2]);
+ }
+
+ private void updateComplexParts() {
+ if (this.children != null) {
+ this.aI = this.yaw;
+ this.head.width = this.head.length = 3.0F;
+ this.tail1.width = this.tail1.length = 2.0F;
+ this.tail2.width = this.tail2.length = 2.0F;
+ this.tail3.width = this.tail3.length = 2.0F;
+ this.body.length = 3.0F;
+ this.body.width = 5.0F;
+ this.wing1.length = 2.0F;
+ this.wing1.width = 4.0F;
+ this.wing2.length = 3.0F;
+ this.wing2.width = 4.0F;
+ float f1 = (float)(b(5, 1.0F)[1] - b(10, 1.0F)[1]) * 10.0F / 180.0F * 3.1415927F;
+ float f2 = MathHelper.cos(f1);
+ float f9 = -MathHelper.sin(f1);
+ float f10 = this.yaw * 3.1415927F / 180.0F;
+ float f11 = MathHelper.sin(f10);
+ float f12 = MathHelper.cos(f10);
+
+ this.body.t_();
+ this.body.setPositionRotation(this.locX + f11 * 0.5F, this.locY, this.locZ - f12 * 0.5F, 0.0F, 0.0F);
+ this.wing1.t_();
+ this.wing1.setPositionRotation(this.locX + f12 * 4.5F, this.locY + 2.0D, this.locZ + f11 * 4.5F, 0.0F, 0.0F);
+ this.wing2.t_();
+ this.wing2.setPositionRotation(this.locX - f12 * 4.5F, this.locY + 2.0D, this.locZ - f11 * 4.5F, 0.0F, 0.0F);
+ /*if ((!this.world.isClientSide) && (this.hurtTicks == 0)) {
+ launchEntities(this.world.getEntities(this, this.wing1.getBoundingBox().grow(4.0D, 2.0D, 4.0D).c(0.0D, -2.0D, 0.0D)));
+ launchEntities(this.world.getEntities(this, this.wing2.getBoundingBox().grow(4.0D, 2.0D, 4.0D).c(0.0D, -2.0D, 0.0D)));
+ damageEntities(this.world.getEntities(this, this.head.getBoundingBox().grow(1.0D, 1.0D, 1.0D)));
+ }*/
+ double[] adouble = b(5, 1.0F);
+ double[] adouble1 = b(0, 1.0F);
+
+ float f3 = MathHelper.sin(this.yaw * 3.1415927F / 180.0F - this.bb * 0.01F);
+ float f13 = MathHelper.cos(this.yaw * 3.1415927F / 180.0F - this.bb * 0.01F);
+
+ this.head.t_();
+ this.head.setPositionRotation(this.locX + f3 * 5.5F * f2, this.locY + (adouble1[1] - adouble[1]) * 1.0D + f9 * 5.5F, this.locZ - f13 * 5.5F * f2, 0.0F, 0.0F);
+ for (int j = 0; j < 3; j++) {
+ EntityComplexPart entitycomplexpart = null;
+ if (j == 0) {
+ entitycomplexpart = this.tail1;
+ }
+ if (j == 1) {
+ entitycomplexpart = this.tail2;
+ }
+ if (j == 2) {
+ entitycomplexpart = this.tail3;
+ }
+ double[] adouble2 = b(12 + j * 2, 1.0F);
+ float f14 = this.yaw * 3.1415927F / 180.0F + ((float) MathHelper.g(adouble2[0] - adouble[0])) * 3.1415927F / 180.0F * 1.0F;
+ float f15 = MathHelper.sin(f14);
+ float f16 = MathHelper.cos(f14);
+ float f17 = 1.5F;
+ float f18 = (j + 1) * 2.0F;
+
+ entitycomplexpart.t_();
+ entitycomplexpart.setPositionRotation(this.locX - (f11 * f17 + f15 * f18) * f2, this.locY + (adouble2[1] - adouble[1]) * 1.0D - (f18 + f17) * f9 + 1.5D, this.locZ + (f12 * f17 + f16 * f18) * f2, 0.0F, 0.0F);
+ }
+ }
+ }
+
+ private void target() {
+ this.bw = false;
+ ArrayList arraylist = Lists.newArrayList(this.world.players);
+ Iterator iterator = arraylist.iterator();
+ while (iterator.hasNext()) {
+ if (((EntityHuman) iterator.next()).v()) {
+ iterator.remove();
+ }
+ }
+ if (this.random.nextInt(2) == 0 && !this.world.players.isEmpty()) {
+ if (this.random.nextInt(10) <= 9 && this.getPlayerOwner() != null) {
+ this.bA = ((CraftPlayer) this.getPlayerOwner()).getHandle();
+ } else {
+ this.bA = (Entity) this.world.players.get(this.random.nextInt(this.world.players.size()));
+ }
+ } else {
+ boolean flag;
+ do {
+ this.a = 0.0D;
+ this.b = (70.0F + this.random.nextFloat() * 50.0F);
+ this.c = 0.0D;
+ this.a += this.random.nextFloat() * 120.0F - 60.0F;
+ this.c += this.random.nextFloat() * 120.0F - 60.0F;
+ double d0 = this.locX - this.a;
+ double d1 = this.locY - this.b;
+ double d2 = this.locZ - this.c;
+
+ flag = d0 * d0 + d1 * d1 + d2 * d2 > 100.0D;
+ } while (!flag);
+ this.bA = null;
+ }
+ }
+
+ @Override
+ public World a() {
+ return this.world;
+ }
+
+ @Override
+ public boolean a(EntityComplexPart entityComplexPart, DamageSource damageSource, float f) {
+ if (entityComplexPart != this.head) {
+ f = f / 4.0F + 1.0F;
+ }
+
+ float f1 = this.yaw * 3.1415927F / 180.0F;
+ float f2 = MathHelper.sin(f1);
+ float f3 = MathHelper.cos(f1);
+
+ this.a = this.locX + (double) (f2 * 5.0F) + (double) ((this.random.nextFloat() - 0.5F) * 2.0F);
+ this.b = this.locY + (double) (this.random.nextFloat() * 3.0F) + 1.0D;
+ this.c = this.locZ - (double) (f3 * 5.0F) + (double) ((this.random.nextFloat() - 0.5F) * 2.0F);
+ this.bA = null;
+ if (damageSource.getEntity() instanceof EntityHuman || damageSource.isExplosion()) {
+ //this.attack(damageSource.getEntity(), f);
+ }
+
+ return true;
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "";
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.enderdragon.growl";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.GIANT;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEndermanPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEndermanPet.java
new file mode 100644
index 00000000..60520c0c
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEndermanPet.java
@@ -0,0 +1,85 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityEndermanPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.Block;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 2.9F)
+@EntityPetType(petType = PetType.ENDERMAN)
+public class EntityEndermanPet extends EntityPet implements IEntityEndermanPet {
+
+ public EntityEndermanPet(World world) {
+ super(world);
+ }
+
+ public EntityEndermanPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public void setScreaming(boolean flag) {
+ this.datawatcher.watch(18, Byte.valueOf((byte) (flag ? 1 : 0)));
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Short((short) 0));
+ this.datawatcher.a(17, new Byte((byte) 0));
+ this.datawatcher.a(18, new Byte((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return this.isScreaming() ? "mob.endermen.scream" : "mob.endermen.idle";
+ }
+
+ public boolean isScreaming() {
+ return this.datawatcher.getByte(18) > 0;
+ }
+
+ public void setCarried(Block block) {
+ this.datawatcher.watch(16, Short.valueOf((short) (Block.getId(block) & 255)));
+ }
+
+ public Block getCarried() {
+ return Block.getById(this.datawatcher.getShort(16));
+ }
+
+ public void setCarriedData(int i) {
+ this.datawatcher.watch(17, Byte.valueOf((byte) (i & 255)));
+ }
+
+ public int getCarriedData() {
+ return this.datawatcher.getByte(17);
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.enderman.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEndermitePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEndermitePet.java
new file mode 100644
index 00000000..851f7da2
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityEndermitePet.java
@@ -0,0 +1,48 @@
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityEndermitePet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.EnumParticle;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.4F, height = 0.3F)
+@EntityPetType(petType = PetType.ENDERMITE)
+public class EntityEndermitePet extends EntityPet implements IEntityEndermitePet {
+
+ public EntityEndermitePet(World world) {
+ super(world);
+ }
+
+ public EntityEndermitePet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.TINY;
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.silverfish.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.silverfish.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.silverfish.hit";
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+ for (int i = 0; i < 2; i++) {
+ this.world.addParticle(EnumParticle.PORTAL, this.locX + (this.random.nextDouble() - 0.5D) * this.width, this.locY + this.random.nextDouble() * this.length, this.locZ + (this.random.nextDouble() - 0.5D) * this.width, (this.random.nextDouble() - 0.5D) * 2.0D, -this.random.nextDouble(), (this.random.nextDouble() - 0.5D) * 2.0D, new int[0]);
+ }
+ }
+}
\ No newline at end of file
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGhastPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGhastPet.java
new file mode 100644
index 00000000..73747fa0
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGhastPet.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityGhastPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 4.0F, height = 4.0F)
+@EntityPetType(petType = PetType.GHAST)
+public class EntityGhastPet extends EntityPet implements IEntityGhastPet {
+
+ public EntityGhastPet(World world) {
+ super(world);
+ }
+
+ public EntityGhastPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.ghast.moan";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.ghast.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.OVERSIZE;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGiantPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGiantPet.java
new file mode 100644
index 00000000..c0b2d890
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGiantPet.java
@@ -0,0 +1,56 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityGiantPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 5.5F, height = 5.5F)
+@EntityPetType(petType = PetType.GIANT)
+public class EntityGiantPet extends EntityPet implements IEntityGiantPet {
+
+ public EntityGiantPet(World world) {
+ super(world);
+ }
+
+ public EntityGiantPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.zombie.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.zombie.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.zombie.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.OVERSIZE;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGuardianPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGuardianPet.java
new file mode 100644
index 00000000..024f39ae
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityGuardianPet.java
@@ -0,0 +1,64 @@
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityGuardianPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.85F, height = 0.85F)
+@EntityPetType(petType = PetType.GUARDIAN)
+public class EntityGuardianPet extends EntityPet implements IEntityGuardianPet {
+
+ public EntityGuardianPet(World world) {
+ super(world);
+ }
+
+ public EntityGuardianPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return isElder() ? "mob.guardian.elder.idle" : !V() ? "mob.guardian.land.idle" : "mob.guardian.idle";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return isElder() ? "mob.guardian.elder.hit" : !V() ? "mob.guardian.land.hit" : "mob.guardian.hit";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return isElder() ? SizeCategory.GIANT : SizeCategory.LARGE;
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Integer(0));
+ this.datawatcher.a(17, new Integer(0));
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+ }
+
+ @Override
+ public boolean isElder() {
+ int i = 4;
+ return (this.datawatcher.getInt(16) & i) != 0;
+ }
+
+ @Override
+ public void setElder(boolean flag) {
+ int i = 4;
+ int existing = this.datawatcher.getInt(16);
+
+ if (flag) {
+ this.datawatcher.watch(16, Integer.valueOf(existing | i));
+ } else {
+ this.datawatcher.watch(16, Integer.valueOf(existing & (i ^ 0xFFFFFFFF)));
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityHorsePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityHorsePet.java
new file mode 100644
index 00000000..6ed11907
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityHorsePet.java
@@ -0,0 +1,188 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityHorsePet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.*;
+
+@EntitySize(width = 1.4F, height = 1.6F)
+@EntityPetType(petType = PetType.HORSE)
+public class EntityHorsePet extends EntityAgeablePet implements IEntityHorsePet {
+
+ private int rearingCounter = 0;
+ int stepSoundCount = 0;
+
+ public EntityHorsePet(World world) {
+ super(world);
+ }
+
+ public EntityHorsePet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public void setSaddled(boolean flag) {
+ this.horseVisual(4, flag);
+ }
+
+ @Override
+ public void setType(HorseType t) {
+ if (t != HorseType.NORMAL) {
+ this.setArmour(HorseArmour.NONE);
+ }
+ this.datawatcher.watch(19, Byte.valueOf((byte) t.getId()));
+ }
+
+ @Override
+ public void setVariant(HorseVariant v, HorseMarking m) {
+ this.datawatcher.watch(20, Integer.valueOf(m.getId(v)));
+ }
+
+ @Override
+ public void setArmour(HorseArmour a) {
+ if (this.datawatcher.getByte(19) == Byte.valueOf((byte) HorseType.NORMAL.getId())) {
+ this.datawatcher.watch(22, Integer.valueOf(a.getId()));
+ }
+ }
+
+ @Override
+ public void setChested(boolean flag) {
+ this.horseVisual(8, flag);
+ }
+
+ @Override
+ public boolean attack(Entity entity) {
+ boolean flag = super.attack(entity);
+ if (flag) {
+ horseVisual(64, true);
+ if (getType() == 0) {
+ this.makeSound("mob.horse.angry", 1.0F, 1.0F);
+ } else if (getType() == 2 || getType() == 3) {
+ this.makeSound("mob.horse.donkey.angry", 1.0F, 1.0F);
+ }
+ }
+ return flag;
+ }
+
+ /*
+ * 4 = saddle
+ * 8 = chest
+ * 32 = head down
+ * 64 = rear
+ * 128 = mouth open
+ */
+ private void horseVisual(int i, boolean flag) {
+ int j = this.datawatcher.getInt(16);
+
+ if (flag) {
+ this.datawatcher.watch(16, Integer.valueOf(j | i));
+ } else {
+ this.datawatcher.watch(16, Integer.valueOf(j & ~i));
+ }
+ }
+
+ public int getType() {
+ return this.datawatcher.getByte(19);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, Integer.valueOf(0));
+ this.datawatcher.a(19, Byte.valueOf((byte) 0));
+ this.datawatcher.a(20, Integer.valueOf(0));
+ this.datawatcher.a(21, String.valueOf(""));
+ this.datawatcher.a(22, Integer.valueOf(0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ int i = this.getType();
+
+ return i == 3 ? "mob.horse.zombie.idle" : (i == 4 ? "mob.horse.skeleton.idle" : (i != 1 && i != 2 ? "mob.horse.idle" : "mob.horse.donkey.idle"));
+ }
+
+ @Override
+ protected void makeStepSound(int i, int j, int k, Block block) {
+ Block.StepSound stepsound = block.stepSound;
+
+ if (this.world.getType(new BlockPosition(i, j + 1, k)) == Blocks.SNOW) {
+ stepsound = Blocks.SNOW.stepSound;
+ }
+
+ if (!block.getMaterial().isLiquid()) {
+ int l = this.getType();
+
+ if (this.passenger != null && l != 1 && l != 2) {
+ ++this.stepSoundCount;
+ if (this.stepSoundCount > 5 && this.stepSoundCount % 3 == 0) {
+ this.makeSound("mob.horse.gallop", stepsound.getVolume1() * 0.15F, stepsound.getVolume2());
+ if (l == 0 && this.random.nextInt(10) == 0) {
+ this.makeSound("mob.horse.breathe", stepsound.getVolume1() * 0.6F, stepsound.getVolume2());
+ }
+ } else if (this.stepSoundCount <= 5) {
+ this.makeSound("mob.horse.wood", stepsound.getVolume1() * 0.15F, stepsound.getVolume2());
+ }
+ } else if (stepsound == Block.f) {
+ this.makeSound("mob.horse.wood", stepsound.getVolume1() * 0.15F, stepsound.getVolume2());
+ } else {
+ this.makeSound("mob.horse.soft", stepsound.getVolume1() * 0.15F, stepsound.getVolume2());
+ }
+ }
+ }
+
+ @Override
+ public void g(float sideMot, float forwMot) {
+ super.g(sideMot, forwMot);
+ if (forwMot <= 0.0F) {
+ this.stepSoundCount = 0;
+ }
+ }
+
+ @Override
+ protected String getDeathSound() {
+ int i = this.getType();
+ return i == 3 ? "mob.horse.zombie.death" : (i == 4 ? "mob.horse.skeleton.death" : (i != 1 && i != 2 ? "mob.horse.death" : "mob.horse.donkey.death"));
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ if (this.isBaby()) {
+ return SizeCategory.TINY;
+ } else {
+ return SizeCategory.LARGE;
+ }
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+ if (rearingCounter > 0 && ++rearingCounter > 20) {
+ horseVisual(64, false);
+ }
+ }
+
+ @Override
+ protected void doJumpAnimation() {
+ this.makeSound("mob.horse.jump", 0.4F, 1.0F);
+ this.rearingCounter = 1;
+ horseVisual(64, true);
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityIronGolemPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityIronGolemPet.java
new file mode 100644
index 00000000..0c9fcf39
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityIronGolemPet.java
@@ -0,0 +1,74 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityIronGolemPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.Entity;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 1.4F, height = 2.9F)
+@EntityPetType(petType = PetType.IRONGOLEM)
+public class EntityIronGolemPet extends EntityPet implements IEntityIronGolemPet {
+
+ public EntityIronGolemPet(World world) {
+ super(world);
+ }
+
+ public EntityIronGolemPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, Byte.valueOf((byte) 0));
+ }
+
+ @Override
+ public boolean attack(Entity entity) {
+ boolean flag = super.attack(entity);
+ if (flag) {
+ this.world.broadcastEntityEffect(this, (byte) 4);
+ entity.motY = 0.4000000059604645D;
+ this.makeSound("mob.irongolem.throw", 1.0F, 1.0F);
+ }
+ return flag;
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.irongolem.walk", 1.0F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "none";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.irongolem.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.LARGE;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityMagmaCubePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityMagmaCubePet.java
new file mode 100644
index 00000000..8990ac6a
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityMagmaCubePet.java
@@ -0,0 +1,38 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityMagmaCubePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 0.6F)
+@EntityPetType(petType = PetType.MAGMACUBE)
+public class EntityMagmaCubePet extends EntitySlimePet implements IEntityMagmaCubePet {
+
+ public EntityMagmaCubePet(World world) {
+ super(world);
+ }
+
+ public EntityMagmaCubePet(World world, IPet pet) {
+ super(world, pet);
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityMushroomCowPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityMushroomCowPet.java
new file mode 100644
index 00000000..e850f974
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityMushroomCowPet.java
@@ -0,0 +1,54 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityMushroomCowPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.9F, height = 1.3F)
+@EntityPetType(petType = PetType.MUSHROOMCOW)
+public class EntityMushroomCowPet extends EntityAgeablePet implements IEntityMushroomCowPet {
+
+ public EntityMushroomCowPet(World world) {
+ super(world);
+ }
+
+ public EntityMushroomCowPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.cow.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.cow.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.cow.death";
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityOcelotPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityOcelotPet.java
new file mode 100644
index 00000000..cbf4e185
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityOcelotPet.java
@@ -0,0 +1,70 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityOcelotPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 0.8F)
+@EntityPetType(petType = PetType.OCELOT)
+public class EntityOcelotPet extends EntityAgeablePet implements IEntityOcelotPet {
+
+ public EntityOcelotPet(World world) {
+ super(world);
+ }
+
+ public EntityOcelotPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ public int getCatType() {
+ return this.datawatcher.getByte(18);
+ }
+
+ @Override
+ public void setCatType(int i) {
+ this.datawatcher.watch(18, (byte) i);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 0));
+ this.datawatcher.a(18, new Byte((byte) 0));
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.ozelot.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return (this.random.nextInt(4) == 0 ? "mob.cat.purreow" : "mob.cat.meow");
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.cat.hitt";
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityPigPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityPigPet.java
new file mode 100644
index 00000000..e7ded78b
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityPigPet.java
@@ -0,0 +1,73 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityPigPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.9F, height = 0.9F)
+@EntityPetType(petType = PetType.PIG)
+public class EntityPigPet extends EntityAgeablePet implements IEntityPigPet {
+
+ public EntityPigPet(World world) {
+ super(world);
+ }
+
+ public EntityPigPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ public boolean hasSaddle() {
+ return (this.datawatcher.getByte(16) & 1) != 0;
+ }
+
+ @Override
+ public void setSaddled(boolean flag) {
+ if (flag) {
+ this.datawatcher.watch(16, Byte.valueOf((byte) 1));
+ } else {
+ this.datawatcher.watch(16, Byte.valueOf((byte) 0));
+ }
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, Byte.valueOf((byte) 0));
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.pig.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.pig.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.pig.death";
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityPigZombiePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityPigZombiePet.java
new file mode 100644
index 00000000..207bc1b7
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityPigZombiePet.java
@@ -0,0 +1,87 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityPigZombiePet;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.ItemStack;
+import net.minecraft.server.v1_8_R2.Items;
+import net.minecraft.server.v1_8_R2.World;
+import org.bukkit.scheduler.BukkitRunnable;
+
+@EntitySize(width = 0.6F, height = 1.8F)
+@EntityPetType(petType = PetType.PIGZOMBIE)
+public class EntityPigZombiePet extends EntityPet implements IEntityPigZombiePet {
+
+ public EntityPigZombiePet(World world) {
+ super(world);
+ }
+
+ public EntityPigZombiePet(World world, IPet pet) {
+ super(world, pet);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ setEquipment(0, new ItemStack(Items.GOLDEN_SWORD));
+ }
+ }.runTaskLater(EchoPet.getPlugin(), 5L);
+ }
+
+ @Override
+ public void setBaby(boolean flag) {
+ this.datawatcher.watch(12, (byte) (flag ? 1 : 0));
+ }
+
+ @Override
+ public void setVillager(boolean flag) {
+ this.datawatcher.watch(13, (byte) (flag ? 1 : 0));
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(12, new Byte((byte) 0));
+ this.datawatcher.a(13, new Byte((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.zombiepig.zpig";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.zombiepig.zpigdeath";
+ }
+
+ @Override
+ public boolean isBaby() {
+ return this.datawatcher.getByte(12) < 0;
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ if (this.isBaby()) {
+ return SizeCategory.TINY;
+ } else {
+ return SizeCategory.REGULAR;
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityRabbitPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityRabbitPet.java
new file mode 100644
index 00000000..11f1812e
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityRabbitPet.java
@@ -0,0 +1,99 @@
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityRabbitPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+import org.bukkit.entity.Rabbit;
+
+@EntitySize(width = 0.6F, height = 0.7F)
+@EntityPetType(petType = PetType.RABBIT)
+public class EntityRabbitPet extends EntityAgeablePet implements IEntityRabbitPet {
+
+ private int jumpDelay;
+
+ public EntityRabbitPet(World world) {
+ super(world);
+ }
+
+ public EntityRabbitPet(World world, IPet pet) {
+ super(world, pet);
+ this.jumpDelay = this.random.nextInt(15) + 10;
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.rabbit.idle";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.rabbit.hurt";
+ }
+
+ @Override
+ public Rabbit.Type getRabbitType() {
+ return TypeMapping.fromMagic(this.datawatcher.getByte(18));
+ }
+
+ @Override
+ public void setRabbitType(Rabbit.Type type) {
+ this.datawatcher.watch(18, Byte.valueOf((byte) TypeMapping.toMagic(type)));
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(18, Byte.valueOf((byte)0));
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+ // same as the slime
+ if (this.onGround && this.jumpDelay-- <= 0) {
+ getControllerJump().a();
+ this.jumpDelay = this.random.nextInt(15) + 10;
+ this.world.broadcastEntityEffect(this, (byte) 1);
+ }
+ }
+
+ static class TypeMapping {
+
+ private static final int[] NMS_TYPES = new int[Rabbit.Type.values().length];
+ private static final Rabbit.Type[] INVERSE = new Rabbit.Type[Rabbit.Type.values().length];
+
+ static {
+ set(Rabbit.Type.BROWN, 0);
+ set(Rabbit.Type.WHITE, 1);
+ set(Rabbit.Type.BLACK, 2);
+ set(Rabbit.Type.BLACK_AND_WHITE, 3);
+ set(Rabbit.Type.GOLD, 4);
+ set(Rabbit.Type.SALT_AND_PEPPER, 5);
+ set(Rabbit.Type.THE_KILLER_BUNNY, 99);
+ }
+
+ private static void set(Rabbit.Type type, int magicValue) {
+ NMS_TYPES[type.ordinal()] = magicValue;
+ if (magicValue < INVERSE.length) {
+ INVERSE[magicValue] = type;
+ }
+ }
+
+ protected static Rabbit.Type fromMagic(int magicValue) {
+ if (magicValue < INVERSE.length) {
+ return INVERSE[magicValue];
+ } else if (magicValue == 99) {
+ return Rabbit.Type.THE_KILLER_BUNNY;
+ }
+ // a default
+ return Rabbit.Type.BROWN;
+ }
+
+ protected static int toMagic(Rabbit.Type type) {
+ return NMS_TYPES[type.ordinal()];
+ }
+
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySheepPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySheepPet.java
new file mode 100644
index 00000000..3e9e8b5b
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySheepPet.java
@@ -0,0 +1,87 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySheepPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.9F, height = 1.3F)
+@EntityPetType(petType = PetType.SHEEP)
+public class EntitySheepPet extends EntityAgeablePet implements IEntitySheepPet {
+
+ public EntitySheepPet(World world) {
+ super(world);
+ }
+
+ public EntitySheepPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ public int getColor() {
+ return this.datawatcher.getByte(16) & 15;
+ }
+
+ @Override
+ public void setColor(int i) {
+ byte b0 = this.datawatcher.getByte(16);
+
+ byte b = Byte.valueOf((byte) (b0 & 240 | i & 15));
+ this.datawatcher.watch(16, b);
+ }
+
+ public boolean isSheared() {
+ return (this.datawatcher.getByte(16) & 16) != 0;
+ }
+
+ @Override
+ public void setSheared(boolean flag) {
+ byte b0 = this.datawatcher.getByte(16);
+
+ if (flag) {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 16)));
+ } else {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -17)));
+ }
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 0));
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.sheep.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.sheep.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.sheep.say";
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySilverfishPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySilverfishPet.java
new file mode 100644
index 00000000..7af06929
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySilverfishPet.java
@@ -0,0 +1,56 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySilverfishPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.3F, height = 0.7F)
+@EntityPetType(petType = PetType.SILVERFISH)
+public class EntitySilverfishPet extends EntityPet implements IEntitySilverfishPet {
+
+ public EntitySilverfishPet(World world) {
+ super(world);
+ }
+
+ public EntitySilverfishPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.silverfish.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.silverfish.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.silverfish.kill";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.TINY;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySkeletonPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySkeletonPet.java
new file mode 100644
index 00000000..822bb064
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySkeletonPet.java
@@ -0,0 +1,95 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySkeletonPet;
+import com.dsh105.echopet.compat.api.entity.type.pet.ISkeletonPet;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.ItemStack;
+import net.minecraft.server.v1_8_R2.Items;
+import net.minecraft.server.v1_8_R2.World;
+import org.bukkit.scheduler.BukkitRunnable;
+
+@EntitySize(width = 0.6F, height = 1.9F)
+@EntityPetType(petType = PetType.SKELETON)
+public class EntitySkeletonPet extends EntityPet implements IEntitySkeletonPet {
+
+ public EntitySkeletonPet(World world) {
+ super(world);
+ }
+
+ public EntitySkeletonPet(World world, final IPet pet) {
+ super(world, pet);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ if (((ISkeletonPet) pet).isWither()) {
+ setEquipment(0, new ItemStack(Items.STONE_SWORD));
+ } else {
+ setEquipment(0, new ItemStack(Items.BOW));
+ }
+ }
+ }.runTaskLater(EchoPet.getPlugin(), 5L);
+ }
+
+ @Override
+ public void setWither(boolean flag) {
+ this.datawatcher.watch(13, (byte) (flag ? 1 : 0));
+ if (flag) {
+ setEquipment(0, new ItemStack(Items.STONE_SWORD));
+ } else {
+ setEquipment(0, new ItemStack(Items.BOW));
+ }
+ }
+
+ public int getSkeletonType() {
+ return this.datawatcher.getByte(13);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(13, new Byte((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.skeleton.say";
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.skeleton.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.skeleton.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ if (this.getSkeletonType() == 1) {
+ return SizeCategory.LARGE;
+ } else {
+ return SizeCategory.REGULAR;
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySlimePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySlimePet.java
new file mode 100644
index 00000000..665447dd
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySlimePet.java
@@ -0,0 +1,100 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySlimePet;
+import com.dsh105.echopet.compat.api.util.Perm;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 0.6F)
+@EntityPetType(petType = PetType.SLIME)
+public class EntitySlimePet extends EntityPet implements IEntitySlimePet {
+
+ int jumpDelay;
+
+ public EntitySlimePet(World world) {
+ super(world);
+ }
+
+ public EntitySlimePet(World world, IPet pet) {
+ super(world, pet);
+ if (!Perm.hasDataPerm(pet.getOwner(), false, pet.getPetType(), PetData.MEDIUM, false)) {
+ if (!Perm.hasDataPerm(pet.getOwner(), false, pet.getPetType(), PetData.SMALL, false)) {
+ this.setSize(4);
+ } else {
+ this.setSize(1);
+ }
+ } else {
+ this.setSize(2);
+ }
+ this.jumpDelay = this.random.nextInt(15) + 10;
+ }
+
+ @Override
+ public void setSize(int i) {
+ this.datawatcher.watch(16, new Byte((byte) i));
+ EntitySize es = this.getClass().getAnnotation(EntitySize.class);
+ this.a(es.width() * (float) i, es.height() * (float) i);
+ this.setPosition(this.locX, this.locY, this.locZ);
+ this.setHealth(this.getMaxHealth());
+ }
+
+ public int getSize() {
+ return this.datawatcher.getByte(16);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 1));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.slime." + (this.getSize() > 1 ? "big" : "small");
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+
+ if (this.onGround && this.jumpDelay-- <= 0) {
+ this.jumpDelay = this.random.nextInt(15) + 10;
+ this.makeSound(this.getDeathSound(), this.bB(), ((this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F) / 0.8F);
+ getControllerJump().a();
+ }
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ if (this.getSize() == 1) {
+ return SizeCategory.TINY;
+ } else if (this.getSize() == 4) {
+ return SizeCategory.LARGE;
+ } else {
+ return SizeCategory.REGULAR;
+ }
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySnowmanPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySnowmanPet.java
new file mode 100644
index 00000000..130c2b75
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySnowmanPet.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySnowmanPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.4F, height = 1.8F)
+@EntityPetType(petType = PetType.SNOWMAN)
+public class EntitySnowmanPet extends EntityPet implements IEntitySnowmanPet {
+
+ public EntitySnowmanPet(World world) {
+ super(world);
+ }
+
+ public EntitySnowmanPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "none";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "none";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySpiderPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySpiderPet.java
new file mode 100644
index 00000000..bfec1f56
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySpiderPet.java
@@ -0,0 +1,62 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySpiderPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 1.4F, height = 0.9F)
+@EntityPetType(petType = PetType.SPIDER)
+public class EntitySpiderPet extends EntityPet implements IEntitySpiderPet {
+
+ public EntitySpiderPet(World world) {
+ super(world);
+ }
+
+ public EntitySpiderPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Byte((byte) 0));
+ }
+
+ @Override
+ protected void makeStepSound() {
+ makeSound("mob.spider.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.spider.say";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.spider.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySquidPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySquidPet.java
new file mode 100644
index 00000000..eeccd8f0
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntitySquidPet.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntitySquidPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.95F, height = 0.95F)
+@EntityPetType(petType = PetType.SQUID)
+public class EntitySquidPet extends EntityPet implements IEntitySquidPet {
+
+ public EntitySquidPet(World world) {
+ super(world);
+ }
+
+ public EntitySquidPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return null;
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityVillagerPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityVillagerPet.java
new file mode 100644
index 00000000..6228c11a
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityVillagerPet.java
@@ -0,0 +1,60 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.EntityPetType;
+import com.dsh105.echopet.compat.api.entity.EntitySize;
+import com.dsh105.echopet.compat.api.entity.IPet;
+import com.dsh105.echopet.compat.api.entity.PetType;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityVillagerPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 1.8F)
+@EntityPetType(petType = PetType.VILLAGER)
+public class EntityVillagerPet extends EntityAgeablePet implements IEntityVillagerPet {
+
+ public EntityVillagerPet(World world) {
+ super(world);
+ }
+
+ public EntityVillagerPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ public void setProfession(int i) {
+ this.datawatcher.watch(16, i);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return this.random.nextBoolean() ? "mob.villager.haggle" : "mob.villager.idle";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.villager.death";
+ }
+
+ @Override
+ public void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(16, new Integer(0));
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWitchPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWitchPet.java
new file mode 100644
index 00000000..6ec08eb7
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWitchPet.java
@@ -0,0 +1,51 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityWitchPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.6F, height = 1.9F)
+@EntityPetType(petType = PetType.WITCH)
+public class EntityWitchPet extends EntityPet implements IEntityWitchPet {
+
+ public EntityWitchPet(World world) {
+ super(world);
+ }
+
+ public EntityWitchPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.witch.idle";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.witch.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.REGULAR;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWitherPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWitherPet.java
new file mode 100644
index 00000000..5fe969f4
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWitherPet.java
@@ -0,0 +1,65 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityWitherPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.World;
+
+@EntitySize(width = 0.9F, height = 4.0F)
+@EntityPetType(petType = PetType.WITHER)
+public class EntityWitherPet extends EntityPet implements IEntityWitherPet {
+
+ public EntityWitherPet(World world) {
+ super(world);
+ }
+
+ public EntityWitherPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(17, new Integer(0));
+ this.datawatcher.a(18, new Integer(0));
+ this.datawatcher.a(19, new Integer(0));
+ this.datawatcher.a(20, new Integer(0));
+ }
+
+ public void setShielded(boolean flag) {
+ this.datawatcher.watch(20, new Integer((flag ? 1 : 0)));
+ this.setHealth((float) (flag ? 150 : 300));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.wither.idle";
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.wither.death";
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ return SizeCategory.LARGE;
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWolfPet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWolfPet.java
new file mode 100644
index 00000000..97354b20
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityWolfPet.java
@@ -0,0 +1,146 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityWolfPet;
+import com.dsh105.echopet.compat.api.entity.type.pet.IWolfPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityAgeablePet;
+import net.minecraft.server.v1_8_R2.EnumColor;
+import net.minecraft.server.v1_8_R2.EnumParticle;
+import net.minecraft.server.v1_8_R2.MathHelper;
+import net.minecraft.server.v1_8_R2.World;
+import org.bukkit.DyeColor;
+
+@EntitySize(width = 0.6F, height = 0.8F)
+@EntityPetType(petType = PetType.WOLF)
+public class EntityWolfPet extends EntityAgeablePet implements IEntityWolfPet {
+
+ private boolean wet;
+ private boolean shaking;
+ private float shakeCount;
+
+ public EntityWolfPet(World world) {
+ super(world);
+ }
+
+ public EntityWolfPet(World world, IPet pet) {
+ super(world, pet);
+ }
+
+ public boolean isTamed() {
+ return (this.datawatcher.getByte(16) & 4) != 0;
+ }
+
+ @Override
+ public void setTamed(boolean flag) {
+ if (isAngry() && flag) {
+ this.getPet().getPetData().remove(PetData.ANGRY);
+ setAngry(false);
+ }
+
+ byte b0 = this.datawatcher.getByte(16);
+
+ if (flag) {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 4)));
+ } else {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -5)));
+ }
+ }
+
+ @Override
+ public void setAngry(boolean flag) {
+ if (isTamed() && flag) {
+ this.getPet().getPetData().remove(PetData.TAMED);
+ setTamed(false);
+ }
+
+ byte b0 = this.datawatcher.getByte(16);
+
+ if (flag) {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 | 2)));
+ } else {
+ this.datawatcher.watch(16, Byte.valueOf((byte) (b0 & -3)));
+ }
+ }
+
+ public boolean isAngry() {
+ return (this.datawatcher.getByte(16) & 2) != 0;
+ }
+
+ @Override
+ public void setCollarColor(DyeColor dc) {
+ if (((IWolfPet) pet).isTamed()) {
+ byte colour = dc.getWoolData();
+ this.datawatcher.watch(20, colour);
+ }
+ }
+
+ @Override
+ public void onLive() {
+ super.onLive();
+ if (this.inWater) {
+ this.wet = true;
+ this.shaking = false;
+ this.shakeCount = 0.0F;
+ } else if ((this.wet || this.shaking) && this.shaking) {
+ if (this.shakeCount == 0.0F) {
+ this.makeSound("mob.wolf.shake", this.bB(), (this.random.nextFloat() - this.random.nextFloat()) * 0.2F + 1.0F);
+ }
+
+ this.shakeCount += 0.05F;
+ if (this.shakeCount - 0.05F >= 2.0F) {
+ this.wet = false;
+ this.shaking = false;
+ this.shakeCount = 0.0F;
+ }
+
+ if (this.shakeCount > 0.4F) {
+ float f = (float) this.getBoundingBox().b;
+ int i = (int) (MathHelper.sin((this.shakeCount - 0.4F) * 3.1415927F) * 7.0F);
+
+ for (int j = 0; j < i; ++j) {
+ float f1 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
+ float f2 = (this.random.nextFloat() * 2.0F - 1.0F) * this.width * 0.5F;
+
+ this.world.addParticle(EnumParticle.WATER_SPLASH, this.locX + (double) f1, (double) (f + 0.8F), this.locZ + (double) f2, this.motX, this.motY, this.motZ);
+ }
+ }
+ }
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return this.isAngry() ? "mob.wolf.growl" : (this.random.nextInt(3) == 0 ? (this.isTamed() && this.datawatcher.getFloat(18) < 10 ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark");
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.wolf.death";
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(17, "");
+ this.datawatcher.a(16, new Byte((byte) 0));
+ this.datawatcher.a(18, new Float(this.getHealth()));
+ this.datawatcher.a(19, new Byte((byte) 0));
+ this.datawatcher.a(20, new Byte((byte) EnumColor.RED.getColorIndex()));
+ }
+}
diff --git a/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityZombiePet.java b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityZombiePet.java
new file mode 100644
index 00000000..d04dc73e
--- /dev/null
+++ b/modules/v1_8_R2/src/main/java/com/dsh105/echopet/compat/nms/v1_8_R2/entity/type/EntityZombiePet.java
@@ -0,0 +1,92 @@
+/*
+ * This file is part of EchoPet.
+ *
+ * EchoPet is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * EchoPet is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with EchoPet. If not, see .
+ */
+
+package com.dsh105.echopet.compat.nms.v1_8_R2.entity.type;
+
+import com.dsh105.echopet.compat.api.entity.*;
+import com.dsh105.echopet.compat.api.entity.type.nms.IEntityZombiePet;
+import com.dsh105.echopet.compat.api.plugin.EchoPet;
+import com.dsh105.echopet.compat.nms.v1_8_R2.entity.EntityPet;
+import net.minecraft.server.v1_8_R2.ItemStack;
+import net.minecraft.server.v1_8_R2.Items;
+import net.minecraft.server.v1_8_R2.World;
+import org.bukkit.scheduler.BukkitRunnable;
+
+@EntitySize(width = 0.6F, height = 1.8F)
+@EntityPetType(petType = PetType.ZOMBIE)
+public class EntityZombiePet extends EntityPet implements IEntityZombiePet {
+
+ public EntityZombiePet(World world) {
+ super(world);
+ }
+
+ public EntityZombiePet(World world, IPet pet) {
+ super(world, pet);
+ new BukkitRunnable() {
+ @Override
+ public void run() {
+ setEquipment(0, new ItemStack(Items.IRON_SHOVEL));
+ }
+ }.runTaskLater(EchoPet.getPlugin(), 5L);
+ }
+
+ @Override
+ public void setBaby(boolean flag) {
+ this.datawatcher.watch(12, (byte) (flag ? 1 : 0));
+ }
+
+ @Override
+ public void setVillager(boolean flag) {
+ this.datawatcher.watch(13, (byte) (flag ? 1 : 0));
+ }
+
+ @Override
+ protected void initDatawatcher() {
+ super.initDatawatcher();
+ this.datawatcher.a(12, new Byte((byte) 0));
+ this.datawatcher.a(13, new Byte((byte) 0));
+ }
+
+ @Override
+ protected String getIdleSound() {
+ return "mob.zombie.say";
+ }
+
+ @Override
+ protected void makeStepSound() {
+ this.makeSound("mob.zombie.step", 0.15F, 1.0F);
+ }
+
+ @Override
+ protected String getDeathSound() {
+ return "mob.zombie.death";
+ }
+
+ @Override
+ public boolean isBaby() {
+ return this.datawatcher.getByte(12) == 1;
+ }
+
+ @Override
+ public SizeCategory getSizeCategory() {
+ if (this.isBaby()) {
+ return SizeCategory.TINY;
+ } else {
+ return SizeCategory.REGULAR;
+ }
+ }
+}
diff --git a/pom.xml b/pom.xml
index 5029f9ab..dfb8e4d6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -37,6 +37,7 @@
modules/v1_7_R3
modules/v1_7_R4
modules/v1_8_R1
+ modules/v1_8_R2
modules/EchoPet
@@ -44,7 +45,7 @@
org.bukkit
bukkit
- 1.8-R0.1-SNAPSHOT
+ 1.8.3-R0.1-SNAPSHOT
com.dsh105
@@ -122,14 +123,14 @@
-
- bukkit-repo
- http://repo.bukkit.org/content/groups/public/
-
spigot-hub
http://hub.spigotmc.org/nexus/content/groups/public/
+
+ bukkit-repo
+ http://repo.bukkit.org/content/groups/public/
+
spigot-repo
http://repo.md-5.net/content/groups/public/
@@ -150,10 +151,6 @@
kitteh-repo
http://repo.kitteh.org/content/groups/public
-
- repo-daboross-net
- http://repo.daboross.net/
-
vault-repo
http://nexus.theyeticave.net/content/repositories/pub_releases
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index f3a02a2d..97113daa 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -118,8 +118,12 @@ permissions:
default: op
echopet.pet.type.enderman:
default: op
+ echopet.pet.type.endermite:
+ default: op
echopet.pet.type.ghast:
default: op
+ echopet.pet.type.guardian:
+ default: op
echopet.pet.type.horse:
default: op
echopet.pet.type.human:
@@ -136,6 +140,8 @@ permissions:
default: op
echopet.pet.type.pigzombie:
default: op
+ echopet.pet.type.rabbit:
+ default: op
echopet.pet.type.sheep:
default: op
echopet.pet.type.silverfish:
@@ -176,8 +182,12 @@ permissions:
default: op
echopet.pet.hat.enderman:
default: op
+ echopet.pet.hat.endermite:
+ default: op
echopet.pet.hat.ghast:
default: op
+ echopet.pet.hat.guardian:
+ default: op
echopet.pet.hat.horse:
default: op
echopet.pet.hat.human:
@@ -194,6 +204,8 @@ permissions:
default: op
echopet.pet.hat.pigzombie:
default: op
+ echopet.pet.hat.rabbit:
+ default: op
echopet.pet.hat.sheep:
default: op
echopet.pet.hat.silverfish:
@@ -234,8 +246,12 @@ permissions:
default: op
echopet.pet.ride.enderman:
default: op
+ echopet.pet.ride.endermite:
+ default: op
echopet.pet.ride.ghast:
default: op
+ echopet.pet.ride.guardian:
+ default: op
echopet.pet.ride.horse:
default: op
echopet.pet.ride.human:
@@ -252,6 +268,8 @@ permissions:
default: op
echopet.pet.ride.pigzombie:
default: op
+ echopet.pet.ride.rabbit:
+ default: op
echopet.pet.ride.sheep:
default: op
echopet.pet.ride.silverfish:
@@ -292,8 +310,12 @@ permissions:
default: op
echopet.pet.default.set.type.enderman:
default: op
+ echopet.pet.default.set.type.endermite:
+ default: op
echopet.pet.default.set.type.ghast:
default: op
+ echopet.pet.default.set.type.guardian:
+ default: op
echopet.pet.default.set.type.horse:
default: op
echopet.pet.default.set.type.human:
@@ -310,6 +332,8 @@ permissions:
default: op
echopet.pet.default.set.type.pigzombie:
default: op
+ echopet.pet.default.set.type.rabbit:
+ default: op
echopet.pet.default.set.type.sheep:
default: op
echopet.pet.default.set.type.silverfish:
@@ -344,6 +368,8 @@ permissions:
default: op
echopet.pet.type.enderman.screaming:
default: op
+ echopet.pet.type.guardian.elder:
+ default: op
echopet.pet.type.horse.baby:
default: op
echopet.pet.type.horse.chested:
@@ -418,6 +444,20 @@ permissions:
default: op
echopet.pet.type.pigzombie.villager:
default: op
+ echopet.pet.type.rabbit.baby:
+ default: op
+ echopet.pet.type.rabbit.brown:
+ default: op
+ echopet.pet.type.rabbit.white:
+ default: op
+ echopet.pet.type.rabbit.black:
+ default: op
+ echopet.pet.type.rabbit.blackandwhite:
+ default: op
+ echopet.pet.type.rabbit.saltandpepper:
+ default: op
+ echopet.pet.type.rabbit.killerbunny:
+ default: op
echopet.pet.type.sheep.baby:
default: op
echopet.pet.type.sheep.sheared:
@@ -534,8 +574,12 @@ permissions:
default: op
echopet.petadmin.type.enderman:
default: op
+ echopet.petadmin.type.endermite:
+ default: op
echopet.petadmin.type.ghast:
default: op
+ echopet.petadmin.type.guardian:
+ default: op
echopet.petadmin.type.horse:
default: op
echopet.petadmin.type.human:
@@ -552,6 +596,8 @@ permissions:
default: op
echopet.petadmin.type.pigzombie:
default: op
+ echopet.petadmin.type.rabbit:
+ default: op
echopet.petadmin.type.sheep:
default: op
echopet.petadmin.type.silverfish:
@@ -592,8 +638,12 @@ permissions:
default: op
echopet.petadmin.ride.enderman:
default: op
+ echopet.petadmin.ride.endermite:
+ default: op
echopet.petadmin.ride.ghast:
default: op
+ echopet.petadmin.ride.guardian:
+ default: op
echopet.petadmin.ride.horse:
default: op
echopet.petadmin.ride.human:
@@ -610,6 +660,8 @@ permissions:
default: op
echopet.petadmin.ride.pigzombie:
default: op
+ echopet.petadmin.ride.rabbit:
+ default: op
echopet.petadmin.ride.sheep:
default: op
echopet.petadmin.ride.silverfish:
@@ -650,8 +702,12 @@ permissions:
default: op
echopet.petadmin.hat.enderman:
default: op
+ echopet.petadmin.hat.endermite:
+ default: op
echopet.petadmin.hat.ghast:
default: op
+ echopet.petadmin.hat.guardian:
+ default: op
echopet.petadmin.hat.horse:
default: op
echopet.petadmin.hat.human:
@@ -668,6 +724,8 @@ permissions:
default: op
echopet.petadmin.hat.pigzombie:
default: op
+ echopet.petadmin.hat.rabbit:
+ default: op
echopet.petadmin.hat.sheep:
default: op
echopet.petadmin.hat.silverfish:
@@ -708,8 +766,12 @@ permissions:
default: op
echopet.petadmin.default.set.type.enderman:
default: op
+ echopet.petadmin.default.set.type.endermite:
+ default: op
echopet.petadmin.default.set.type.ghast:
default: op
+ echopet.petadmin.default.set.type.guardian:
+ default: op
echopet.petadmin.default.set.type.horse:
default: op
echopet.petadmin.default.set.type.human:
@@ -726,6 +788,8 @@ permissions:
default: op
echopet.petadmin.default.set.type.pigzombie:
default: op
+ echopet.petadmin.default.set.type.rabbit:
+ default: op
echopet.petadmin.default.set.type.sheep:
default: op
echopet.petadmin.default.set.type.silverfish:
@@ -790,7 +854,9 @@ permissions:
echopet.pet.type.creeper: true
echopet.pet.type.enderdragon: true
echopet.pet.type.enderman: true
+ echopet.pet.type.endermite: true
echopet.pet.type.ghast: true
+ echopet.pet.type.guardian: true
echopet.pet.type.horse: true
echopet.pet.type.human: true
echopet.pet.type.irongolem: true
@@ -799,6 +865,7 @@ permissions:
echopet.pet.type.ocelot: true
echopet.pet.type.pig: true
echopet.pet.type.pigzombie: true
+ echopet.pet.type.rabbit: true
echopet.pet.type.sheep: true
echopet.pet.type.silverfish: true
echopet.pet.type.skeleton: true
@@ -823,7 +890,9 @@ permissions:
echopet.pet.ride.creeper: true
echopet.pet.ride.enderdragon: true
echopet.pet.ride.enderman: true
+ echopet.pet.ride.endermite: true
echopet.pet.ride.ghast: true
+ echopet.pet.ride.guardian: true
echopet.pet.ride.horse: true
echopet.pet.ride.human: true
echopet.pet.ride.irongolem: true
@@ -832,6 +901,7 @@ permissions:
echopet.pet.ride.ocelot: true
echopet.pet.ride.pig: true
echopet.pet.ride.pigzombie: true
+ echopet.pet.ride.rabbit: true
echopet.pet.ride.sheep: true
echopet.pet.ride.silverfish: true
echopet.pet.ride.skeleton: true
@@ -856,7 +926,9 @@ permissions:
echopet.pet.hat.creeper: true
echopet.pet.hat.enderdragon: true
echopet.pet.hat.enderman: true
+ echopet.pet.hat.endermite: true
echopet.pet.hat.ghast: true
+ echopet.pet.hat.guardian: true
echopet.pet.hat.horse: true
echopet.pet.hat.human: true
echopet.pet.hat.irongolem: true
@@ -865,6 +937,7 @@ permissions:
echopet.pet.hat.ocelot: true
echopet.pet.hat.pig: true
echopet.pet.hat.pigzombie: true
+ echopet.pet.hat.rabbit: true
echopet.pet.hat.sheep: true
echopet.pet.hat.silverfish: true
echopet.pet.hat.skeleton: true
@@ -896,7 +969,9 @@ permissions:
echopet.pet.default.set.type.creeper: true
echopet.pet.default.set.type.enderdragon: true
echopet.pet.default.set.type.enderman: true
+ echopet.pet.default.set.type.endermite: true
echopet.pet.default.set.type.ghast: true
+ echopet.pet.default.set.type.guardian: true
echopet.pet.default.set.type.horse: true
echopet.pet.default.set.type.human: true
echopet.pet.default.set.type.irongolem: true
@@ -905,6 +980,7 @@ permissions:
echopet.pet.default.set.type.ocelot: true
echopet.pet.default.set.type.pig: true
echopet.pet.default.set.type.pigzombie: true
+ echopet.pet.default.set.type.rabbit: true
echopet.pet.default.set.type.sheep: true
echopet.pet.default.set.type.silverfish: true
echopet.pet.default.set.type.skeleton: true
@@ -950,7 +1026,9 @@ permissions:
echopet.petadmin.type.creeper: true
echopet.petadmin.type.enderdragon: true
echopet.petadmin.type.enderman: true
+ echopet.petadmin.type.endermite: true
echopet.petadmin.type.ghast: true
+ echopet.petadmin.type.guardian: true
echopet.petadmin.type.horse: true
echopet.petadmin.type.human: true
echopet.petadmin.type.irongolem: true
@@ -959,6 +1037,7 @@ permissions:
echopet.petadmin.type.ocelot: true
echopet.petadmin.type.pig: true
echopet.petadmin.type.pigzombie: true
+ echopet.petadmin.type.rabbit: true
echopet.petadmin.type.sheep: true
echopet.petadmin.type.silverfish: true
echopet.petadmin.type.skeleton: true
@@ -983,7 +1062,9 @@ permissions:
echopet.petadmin.ride.creeper: true
echopet.petadmin.ride.enderdragon: true
echopet.petadmin.ride.enderman: true
+ echopet.petadmin.ride.endermite: true
echopet.petadmin.ride.ghast: true
+ echopet.petadmin.ride.guardian: true
echopet.petadmin.ride.horse: true
echopet.petadmin.ride.human: true
echopet.petadmin.ride.irongolem: true
@@ -992,6 +1073,7 @@ permissions:
echopet.petadmin.ride.ocelot: true
echopet.petadmin.ride.pig: true
echopet.petadmin.ride.pigzombie: true
+ echopet.petadmin.ride.rabbit: true
echopet.petadmin.ride.sheep: true
echopet.petadmin.ride.silverfish: true
echopet.petadmin.ride.skeleton: true
@@ -1016,7 +1098,9 @@ permissions:
echopet.petadmin.hat.creeper: true
echopet.petadmin.hat.enderdragon: true
echopet.petadmin.hat.enderman: true
+ echopet.petadmin.hat.endermite: true
echopet.petadmin.hat.ghast: true
+ echopet.petadmin.hat.guardian: true
echopet.petadmin.hat.horse: true
echopet.petadmin.hat.human: true
echopet.petadmin.hat.irongolem: true
@@ -1025,6 +1109,7 @@ permissions:
echopet.petadmin.hat.ocelot: true
echopet.petadmin.hat.pig: true
echopet.petadmin.hat.pigzombie: true
+ echopet.petadmin.hat.rabbit: true
echopet.petadmin.hat.sheep: true
echopet.petadmin.hat.silverfish: true
echopet.petadmin.hat.skeleton: true
@@ -1056,7 +1141,9 @@ permissions:
echopet.petadmin.default.set.type.creeper: true
echopet.petadmin.default.set.type.enderdragon: true
echopet.petadmin.default.set.type.enderman: true
+ echopet.petadmin.default.set.type.endermite: true
echopet.petadmin.default.set.type.ghast: true
+ echopet.petadmin.default.set.type.guardian: true
echopet.petadmin.default.set.type.horse: true
echopet.petadmin.default.set.type.human: true
echopet.petadmin.default.set.type.irongolem: true
@@ -1065,6 +1152,7 @@ permissions:
echopet.petadmin.default.set.type.ocelot: true
echopet.petadmin.default.set.type.pig: true
echopet.petadmin.default.set.type.pigzombie: true
+ echopet.petadmin.default.set.type.rabbit: true
echopet.petadmin.default.set.type.sheep: true
echopet.petadmin.default.set.type.silverfish: true
echopet.petadmin.default.set.type.skeleton: true
@@ -1102,6 +1190,11 @@ permissions:
description: 'All enderman pet data permissions'
children:
echopet.pet.type.enderman.screaming: true
+ echopet.pet.type.guardian.*:
+ default: op
+ description: 'All guardian pet data permissions'
+ children:
+ echopet.pet.type.guardian.elder: true
echopet.pet.type.horse.*:
default: op
description: 'All horse pet data permissions'
@@ -1163,6 +1256,17 @@ permissions:
children:
echopet.pet.type.pigzombie.baby: true
echopet.pet.type.pigzombie.villager: true
+ echopet.pet.type.rabbit.*:
+ default: op
+ description: 'All rabbit pet data permissions'
+ children:
+ echopet.pet.type.rabbit.baby: true
+ echopet.pet.type.rabbit.brown: true
+ echopet.pet.type.rabbit.white: true
+ echopet.pet.type.rabbit.black: true
+ echopet.pet.type.rabbit.blackandwhite: true
+ echopet.pet.type.rabbit.saltandpepper: true
+ echopet.pet.type.rabbit.killerbunny: true
echopet.pet.type.sheep.*:
default: op
description: 'All sheep pet data permissions'