├── .script └── upload-javadoc.sh ├── .travis.yml ├── API ├── pom.xml └── src │ ├── main │ ├── java │ │ └── org │ │ │ └── inventivetalent │ │ │ └── npclib │ │ │ ├── ArrayMaker.java │ │ │ ├── ClassBuilder.java │ │ │ ├── ClassGenerator.java │ │ │ ├── INPCChannel.java │ │ │ ├── INPCPlayerConnection.java │ │ │ ├── NPCLib.java │ │ │ ├── NPCType.java │ │ │ ├── ObjectContainer.java │ │ │ ├── ObjectConverter.java │ │ │ ├── Reflection.java │ │ │ ├── SuperSwitch.java │ │ │ ├── ai │ │ │ └── AIAbstract.java │ │ │ ├── animation │ │ │ └── Animation.java │ │ │ ├── annotation │ │ │ ├── ExtraMethod.java │ │ │ ├── ExtraMethods.java │ │ │ ├── NPC.java │ │ │ └── NPCInfo.java │ │ │ ├── entity │ │ │ ├── EntityExperienceOrb.java │ │ │ ├── EntityItem.java │ │ │ ├── NPCEntity.java │ │ │ └── living │ │ │ │ ├── EntityArmorStand.java │ │ │ │ ├── NPCEntityLiving.java │ │ │ │ ├── human │ │ │ │ ├── EntityPlayer.java │ │ │ │ └── NPCEntityHuman.java │ │ │ │ └── insentient │ │ │ │ ├── EntityEnderDragon.java │ │ │ │ ├── EntityPigZombie.java │ │ │ │ ├── EntitySlime.java │ │ │ │ ├── EntityZombie.java │ │ │ │ ├── NPCEntityInsentient.java │ │ │ │ ├── creature │ │ │ │ ├── NPCEntityCreature.java │ │ │ │ ├── ageable │ │ │ │ │ ├── EntityVillager.java │ │ │ │ │ ├── NPCEntityAgeable.java │ │ │ │ │ └── animal │ │ │ │ │ │ ├── EntityChicken.java │ │ │ │ │ │ ├── EntityCow.java │ │ │ │ │ │ ├── EntityHorse.java │ │ │ │ │ │ ├── EntityLlama.java │ │ │ │ │ │ ├── EntityMushroomCow.java │ │ │ │ │ │ ├── EntityPig.java │ │ │ │ │ │ ├── EntityPolarBear.java │ │ │ │ │ │ ├── EntityRabbit.java │ │ │ │ │ │ ├── EntitySheep.java │ │ │ │ │ │ ├── NPCEntityAnimal.java │ │ │ │ │ │ └── tameable │ │ │ │ │ │ ├── EntityOcelot.java │ │ │ │ │ │ ├── EntityWolf.java │ │ │ │ │ │ └── NPCEntityTameable.java │ │ │ │ ├── golem │ │ │ │ │ ├── EntityIronGolem.java │ │ │ │ │ ├── EntityShulker.java │ │ │ │ │ ├── EntitySnowman.java │ │ │ │ │ └── NPCEntityGolem.java │ │ │ │ └── monster │ │ │ │ │ ├── EntityCaveSpider.java │ │ │ │ │ ├── EntityCreeper.java │ │ │ │ │ ├── EntityEnderman.java │ │ │ │ │ ├── EntityEndermite.java │ │ │ │ │ ├── EntityGiant.java │ │ │ │ │ ├── EntityGuardian.java │ │ │ │ │ ├── EntityHusk.java │ │ │ │ │ ├── EntitySkeleton.java │ │ │ │ │ ├── EntitySpider.java │ │ │ │ │ ├── EntityWitch.java │ │ │ │ │ ├── EntityWither.java │ │ │ │ │ └── NPCEntityMonster.java │ │ │ │ ├── flying │ │ │ │ ├── EntityGhast.java │ │ │ │ └── NPCEntityFlying.java │ │ │ │ └── water │ │ │ │ ├── EntitySquid.java │ │ │ │ └── NPCEntityWaterAnimal.java │ │ │ ├── equipment │ │ │ └── EquipmentSlot.java │ │ │ ├── event │ │ │ ├── NPCCollisionEvent.java │ │ │ ├── NPCDamageEvent.java │ │ │ ├── NPCDeathEvent.java │ │ │ ├── NPCEvent.java │ │ │ ├── NPCInteractEvent.java │ │ │ ├── NPCSpawnEvent.java │ │ │ ├── NPCVelocityEvent.java │ │ │ ├── nbt │ │ │ │ ├── NBTReadEvent.java │ │ │ │ ├── NBTWriteEvent.java │ │ │ │ └── NPCNBTEvent.java │ │ │ └── path │ │ │ │ └── NPCPathFinishEvent.java │ │ │ ├── npc │ │ │ ├── NPCAbstract.java │ │ │ ├── NPCExperienceOrb.java │ │ │ ├── NPCItem.java │ │ │ └── living │ │ │ │ ├── NPCArmorStand.java │ │ │ │ ├── NPCLivingAbstract.java │ │ │ │ ├── human │ │ │ │ ├── NPCHumanAbstract.java │ │ │ │ └── NPCPlayer.java │ │ │ │ └── insentient │ │ │ │ ├── NPCEnderDragon.java │ │ │ │ ├── NPCInsentientAbstract.java │ │ │ │ ├── NPCPigZombie.java │ │ │ │ ├── NPCSlime.java │ │ │ │ ├── NPCZombie.java │ │ │ │ ├── creature │ │ │ │ ├── NPCCreatureAbstract.java │ │ │ │ ├── ageable │ │ │ │ │ ├── NPCAgeableAbstract.java │ │ │ │ │ ├── NPCVillager.java │ │ │ │ │ └── animal │ │ │ │ │ │ ├── NPCAnimalAbstract.java │ │ │ │ │ │ ├── NPCChicken.java │ │ │ │ │ │ ├── NPCCow.java │ │ │ │ │ │ ├── NPCHorse.java │ │ │ │ │ │ ├── NPCLlama.java │ │ │ │ │ │ ├── NPCMushroomCow.java │ │ │ │ │ │ ├── NPCPig.java │ │ │ │ │ │ ├── NPCPolarBear.java │ │ │ │ │ │ ├── NPCRabbit.java │ │ │ │ │ │ ├── NPCSheep.java │ │ │ │ │ │ └── tameable │ │ │ │ │ │ ├── NPCOcelot.java │ │ │ │ │ │ ├── NPCTameableAbstract.java │ │ │ │ │ │ └── NPCWolf.java │ │ │ │ ├── golem │ │ │ │ │ ├── NPCGolemAbstract.java │ │ │ │ │ ├── NPCIronGolem.java │ │ │ │ │ ├── NPCShulker.java │ │ │ │ │ └── NPCSnowman.java │ │ │ │ └── monster │ │ │ │ │ ├── NPCCaveSpider.java │ │ │ │ │ ├── NPCCreeper.java │ │ │ │ │ ├── NPCEnderman.java │ │ │ │ │ ├── NPCEndermite.java │ │ │ │ │ ├── NPCGiant.java │ │ │ │ │ ├── NPCGuardian.java │ │ │ │ │ ├── NPCHusk.java │ │ │ │ │ ├── NPCMonsterAbstract.java │ │ │ │ │ ├── NPCSkeleton.java │ │ │ │ │ ├── NPCSpider.java │ │ │ │ │ ├── NPCWitch.java │ │ │ │ │ └── NPCWither.java │ │ │ │ ├── flying │ │ │ │ ├── NPCFlyingAbstract.java │ │ │ │ └── NPCGhast.java │ │ │ │ └── water │ │ │ │ ├── NPCSquid.java │ │ │ │ └── NPCWaterAnimalAbstract.java │ │ │ ├── path │ │ │ ├── AStarPathfinder.java │ │ │ ├── NMSPathEntity.java │ │ │ ├── NMSPathPoint.java │ │ │ ├── PathPoint.java │ │ │ └── PathfinderAbstract.java │ │ │ ├── registry │ │ │ └── NPCRegistry.java │ │ │ ├── skin │ │ │ ├── ISkinnableEntity.java │ │ │ └── SkinLayer.java │ │ │ └── watcher │ │ │ ├── AnnotatedMethodWatcher.java │ │ │ ├── MethodWatcher.java │ │ │ └── Watch.java │ └── resources │ │ └── npclib.properties │ └── test │ └── java │ └── org │ └── inventivetalent │ └── npclib │ └── test │ ├── SkinLayerTest.java │ └── TypeTest.java ├── ISSUE_TEMPLATE.md ├── LICENSE ├── Plugin ├── pom.xml └── src │ └── main │ ├── java │ └── org │ │ └── inventivetalent │ │ └── npclib │ │ ├── NPCLibPlugin.java │ │ ├── command │ │ └── SpawnCommands.java │ │ └── metrics │ │ └── Metrics.java │ └── resources │ ├── config.yml │ └── plugin.yml ├── README.md ├── pom.xml ├── renovate.json └── settings.xml /.script/upload-javadoc.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | echo -e "Uploading Javadoc...\n" 3 | 4 | cd $HOME 5 | git config --global user.email "git-bot@inventivetalent.org" 6 | git config --global user.name "InventiveBot" 7 | git clone --quiet --branch=gh-pages https://${GITHUB_TOKEN}@github.com/InventivetalentDev/CompactNPCLib gh-pages > /dev/null 8 | 9 | cd gh-pages 10 | git rm -rf . 11 | cp -Rf $TRAVIS_BUILD_DIR/target/site/apidocs . 12 | git add -f . 13 | git commit -m "Javadoc for #$TRAVIS_BUILD_NUMBER" 14 | git push -fq origin gh-pages > /dev/null 15 | 16 | echo -e "Uploaded Javadoc\n" 17 | 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: java 2 | jdk: 3 | - oraclejdk8 4 | 5 | script: "mvn javadoc:aggregate deploy --settings settings.xml" 6 | before_script: 7 | - "chmod +x .script/upload-javadoc.sh" 8 | after_success: ".script/upload-javadoc.sh" 9 | env: 10 | global: 11 | - secure: "qxDGdJ+QcUTNU3ACL0wLT06CmQhuN/gyi1op/sBWLP1MKR1WBbgsdCeoLNu5JWt008v3rU+cBrk8ZL0zGcnc12BGWqiHmbWX6Y0nHeI7crBxtXV2Nbjb5XXP3PvO5m+2s29Lb4CCUVmgBxPiaKVNbIm6Ax6UMYTvQW+MIh556XCtemhDGqswqgQDptSzk+WPUd86cFhGLTMd1vP8qs0h/Kos34bpF8D+Zi37zbxF4piuS4Z39xKJtkwD96HFbAfY9Cz59WCycj3x5v7Gcyj4k3c5ji6MRq6BEzX1gDJVuwpT+TgJMByAhomNvwmyZdEA48YC5+5CbQ76w1RbzPok79FcsRlvMDccxETMpnuF51BF4vtyMQSSadnJjAh2B0vAbZroroXbI26ndroB5xhloNl3ogHvkGeIpufJTwiWvEUsTP5JkvM+b15+lHbiudh/uLblc0rWX+ld3npwOeZ0sV5gznt+mwKDW+Gz+FIiurJAURIIszHxh3YC2O20ylSAjcKjvF359kQpv0YyOIpOpjXe9XgZFeCzadzXh+RKj1tuQbDbk8/2w+n6/JipwPtdJOfxQKbXg2CQQQaIIgBMV7KvlzxfLqjio4L8G87XAbQKxbsLVFwr1wQN8DQ7LCli13TBjCFkTwKCyatol+cDYsgO0zYjIQo6/n8zkbx8Pn4=" 12 | - secure: "hcMNxLwta0O2r/F0+XheR5s/5C6sKHLsptJkw2AG2SUwkSDfXGt/Ob38KyeUegkVQ/kQkOTVZkF4CvDvZLipiPC1BfM+6HuWsIHAkJlgnNBZ/ntj0vCussmkqNJ6hUelK0/XBauGcO5YmqB4Re/TlSlFyHQeLeAG4h38hgQCELsZ3xTl6887+nEy5nLn5xNlzb661BMd6IaRLsm5BMV+8me9ySXMU/+SU9sMZWa7rREOHw6ruFJrW2r5o9FFEJRsuGwmU0MOdYhxM+uD//A+luI0ZO+gneswe/7IAPgwfgCB4qDKBmL4jxokCkcUWfaL3AnfnusP8DXES1b/uQfGtxJNO/uijRHpSD6VnWoz6f3PoTqsez34hzwfawlqZvGxnIQA/wNs76kVfyrjvVib4khkOb/M8ubDVX3lAoX08qojWhYL7lNDY86CqIQ0iWVYKg2j5xVDsiGZ380HYYHjAaEbqDpHqfkwbUtlpn46m2XpoLYGdJhQ/6g4s7hIuHD8n39fvhu0LDd58cRglLqOM5kbWU0Q07GjnL3Aph4XRyMwiFOW+B4UIcl9RfsU3XNy3nispwolwY9wVguUy7Frv3fOHvXf249eD65ayribmFlKLThiuBUzV+hPZ7e4Gz7XyAfpjyJQjiRQ1s2b/OksU0UyQz+Jl77TzUI3Mq4525I=" 13 | - secure: "gVPrGhZia3dh30sP0krrRRfa9AJmLIqMvoTWskeyudXe9gSk6ELSSlQwpkhqx4IB+SoFGClm7687t5CbVvN+NLiDymD9uUiY4LmaSbwCHwYgoBL0qJAxeZ8ZjhRoVk1AnVPervjdEHgeXCSePMluGBlYtNfi40vOaa5tv0TT8Fm6B9QwOqU+nZVVaEl7uZjMNd0ZeGbQz/qiErSTBCHC49vevu1u1YqJBIxblHJYSeTp3uvI/SySVcFSY9lFMsWBq0Q3CcKgn7TeAsYsjOjlqEPT7WrA2i7LT7hUWZIA7yGXkknF9TKCjLrXLLgQSVzwImTPXULd+pATMp336DqHVcTzXlfKSJP+YKHuJYYNf17EHHbWW3BviyPcP87weAAJE/LzNQCB96RI9tpcMYcKMWgMollPX15f5wfE7euuLq5jcF2nKvqWtuQOH2XD14bD+9+SN7b2A6ohaud92XXYV5HLFnB0SZZPDURyiLIfzPl14F94nhAkJnCzdQ7JguDXH6eJPhRaIFq1szpBq3rKtmHeHD/37xbFxI3jF/VG1R/PYkyH9BVwaTgiu5z3G0PxoU3tsrYJt7Z92qkkIM40AdhYRReF4aDxcq4Ayd3ewpVNUGpDmCHJumiyH3QqXBhHuU6diWKha8vmsiCCT2deGMqYZSR1Azu4k39W40rP/Xo=" 14 | deploy: 15 | provider: releases 16 | api_key: 17 | secure: "onM7hHSoZEr7BrggRPAQz643zghYXI9mXt6rXJeyaqq3EXKn911pOGNsaALcB1iDdrkoumVb9mkX2R0Pn7S5b7JQ00Rb/VvbRjgo9vXUAO3C+KHT8hK1KWH7VPpldMpbJDhGsdbu4j27iOQ9b2PqFnYF9vuqCoIy1q9WQ0BIuYrdA+/ZQ+kShKfqwwrD96D0DZ/68g18vGc6IndKL/2T35MuRMVQVmF137T/BuXKHDVXPKWgeTRY9VMbgh/sI0WhDm2XbyksFeWh6NtUPYxFv10PSJelCJ3c1iqR9wDz0tAuORWGpPMPPIhPCJX07JXotEmz88yFmJXSR5vBddkzaqk5oZpTUlxb4XgtY0ZwJtfzW1x34IKF4db20Tzg3+dRvKlWtfPy5UtbuypiHseltlheEZIciVDW2PdOoKHY3nqP7eeOZCj9DeNpTaa2GWkfc6c8L+IV2K+joJbDp2IEohBKoBKGNDEI+7WQwJWNgJd7qS12Unja1wvDW/Kwryvlwdj5Q9c5qOBgTARQ6Ki5BnZzqYObAkbWaUrEc4xqGIzA7sw51ibFm+oFQabZNAiQUquj0ueeenwgzdRONumw2QAqf8ObQY0xEquaYNS3Bp1IKM+7gvCNqhLuoIfnqRFCJRr+Am2b/YAOTnda+AKThMyNwnjF2XqAhqdGTR8irlE=" 18 | file_glob: true 19 | file: 20 | - "API/target/api-*.jar" 21 | - "Plugin/target/NPCLib_v*.jar" 22 | skip_cleanup: true 23 | on: 24 | tags: true 25 | -------------------------------------------------------------------------------- /API/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 33 | 34 | parent 35 | org.inventivetalent.npc-lib 36 | parent 37 | 38 | 4.0.0 39 | 40 | api 41 | ${npclib.version} 42 | 43 | 44 | 45 | inventive-repo 46 | https://repo.inventivetalent.org/content/groups/public/ 47 | 48 | 49 | spigot-repo 50 | https://hub.spigotmc.org/nexus/content/repositories/snapshots/ 51 | 52 | 53 | 54 | 55 | 56 | org.spigotmc 57 | spigot-api 58 | 1.12-R0.1-SNAPSHOT 59 | provided 60 | 61 | 62 | org.inventivetalent 63 | reflectionhelper 64 | ${reflection.version} 65 | 66 | 67 | org.inventivetalent 68 | pluginannotations 69 | ${annotations.version} 70 | 71 | 72 | org.inventivetalent 73 | mc-wrappers 74 | ${wrappers.version} 75 | 76 | 77 | org.inventivetalent 78 | vectors 79 | ${vectors.version} 80 | 81 | 82 | org.inventivetalent 83 | boundingboxapi 84 | ${boundingbox.version} 85 | 86 | 87 | org.inventivetalent 88 | apimanager 89 | ${apimanager.version} 90 | 91 | 92 | org.inventivetalent 93 | nbt-lib 94 | ${nbt.version} 95 | 96 | 97 | org.inventivetalent.nicknamer 98 | api 99 | ${nicknamer.version} 100 | 101 | 102 | 103 | org.projectlombok 104 | lombok 105 | 1.16.8 106 | 107 | 108 | com.google.code.gson 109 | gson 110 | 2.6.2 111 | 112 | 113 | com.google.guava 114 | guava 115 | 19.0 116 | 117 | 118 | 119 | org.javassist 120 | javassist 121 | 3.20.0-GA 122 | 123 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/ArrayMaker.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | public class ArrayMaker { 4 | 5 | public static Object[] fromParameters() { 6 | return new Object[0]; 7 | } 8 | 9 | public static Object[] fromParameters(Object... args) { 10 | return args; 11 | } 12 | 13 | public static Object[] fromParameters(Object o) { 14 | return new Object[] { o }; 15 | } 16 | 17 | public static Object[] fromParameters(Object o1, Object o2) { 18 | return new Object[] { 19 | o1, 20 | o2 }; 21 | } 22 | 23 | public static Object[] fromParameters(Object o1, Object o2, Object o3) { 24 | return new Object[] { 25 | o1, 26 | o2, 27 | o3 }; 28 | } 29 | 30 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4) { 31 | return new Object[] { 32 | o1, 33 | o2, 34 | o3, 35 | o4 }; 36 | } 37 | 38 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4, Object o5) { 39 | return new Object[] { 40 | o1, 41 | o2, 42 | o3, 43 | o4, 44 | o5 }; 45 | } 46 | 47 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6) { 48 | return new Object[] { 49 | o1, 50 | o2, 51 | o3, 52 | o4, 53 | o5, 54 | o6 }; 55 | } 56 | 57 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7) { 58 | return new Object[] { 59 | o1, 60 | o2, 61 | o3, 62 | o4, 63 | o5, 64 | o6, 65 | o7 }; 66 | } 67 | 68 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8) { 69 | return new Object[] { 70 | o1, 71 | o2, 72 | o3, 73 | o4, 74 | o5, 75 | o6, 76 | o7, 77 | o8 }; 78 | } 79 | 80 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9) { 81 | return new Object[] { 82 | o1, 83 | o2, 84 | o3, 85 | o4, 86 | o5, 87 | o6, 88 | o7, 89 | o8, 90 | o9 }; 91 | } 92 | 93 | public static Object[] fromParameters(Object o1, Object o2, Object o3, Object o4, Object o5, Object o6, Object o7, Object o8, Object o9, Object o10) { 94 | return new Object[] { 95 | o1, 96 | o2, 97 | o3, 98 | o4, 99 | o5, 100 | o6, 101 | o7, 102 | o8, 103 | o9, 104 | o10 }; 105 | } 106 | 107 | // Why am I even doing this... 108 | } 109 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/ClassBuilder.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import javassist.ClassPool; 4 | import org.bukkit.Bukkit; 5 | import org.inventivetalent.reflection.minecraft.Minecraft; 6 | import org.inventivetalent.reflection.resolver.FieldResolver; 7 | import org.inventivetalent.reflection.resolver.MethodResolver; 8 | import org.inventivetalent.reflection.resolver.ResolverQuery; 9 | import org.inventivetalent.reflection.util.AccessUtil; 10 | 11 | import java.lang.reflect.Field; 12 | import java.net.SocketAddress; 13 | import java.util.List; 14 | 15 | public class ClassBuilder { 16 | 17 | protected static Class nmsPacketPlayOutPlayerInfo; 18 | protected static Class nmsPlayerInfoData; 19 | protected static Class nmsEnumPlayerInfoAction; 20 | protected static Class nmsEnumGamemode; 21 | static Class generatedChannel; 22 | static Class generatedPlayerConnection; 23 | static Class NetworkManager = Reflection.nmsClassResolver.resolveSilent("NetworkManager"); 24 | 25 | public static Object buildPacketPlayOutBed(int id, int x, int y, int z) { 26 | try { 27 | Class packetClass = Reflection.nmsClassResolver.resolve("PacketPlayOutBed"); 28 | Object bedPacket = packetClass.newInstance(); 29 | AccessUtil.setAccessible(packetClass.getDeclaredField("a")).set(bedPacket, id); 30 | if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_8_R1)) { 31 | AccessUtil.setAccessible(packetClass.getDeclaredField("b")).set(bedPacket, x); 32 | AccessUtil.setAccessible(packetClass.getDeclaredField("c")).set(bedPacket, y); 33 | AccessUtil.setAccessible(packetClass.getDeclaredField("d")).set(bedPacket, z); 34 | } else { 35 | AccessUtil.setAccessible(packetClass.getDeclaredField("b")).set(bedPacket, Reflection.nmsClassResolver.resolve("BlockPosition").getConstructor(int.class, int.class, int.class).newInstance(x, y, z)); 36 | } 37 | return bedPacket; 38 | } catch (Exception e) { 39 | throw new RuntimeException(e); 40 | } 41 | } 42 | 43 | public static Object buildPacketPlayOutAnimation(int entID, int animID) { 44 | try { 45 | Class packetClass = Reflection.nmsClassResolver.resolve("PacketPlayOutAnimation"); 46 | Object animationPacket = packetClass.newInstance(); 47 | AccessUtil.setAccessible(packetClass.getDeclaredField("a")).set(animationPacket, entID); 48 | AccessUtil.setAccessible(packetClass.getDeclaredField("b")).set(animationPacket, animID); 49 | 50 | return animationPacket; 51 | } catch (Exception e) { 52 | throw new RuntimeException(e); 53 | } 54 | } 55 | 56 | public static Object buildPacketPlayOutEntityStatus(int entityId, byte animationId) { 57 | try { 58 | Class packetClass = Reflection.nmsClassResolver.resolve("PacketPlayOutEntityStatus"); 59 | Object animationPacket = packetClass.newInstance(); 60 | AccessUtil.setAccessible(packetClass.getDeclaredField("a")).set(animationPacket, entityId); 61 | AccessUtil.setAccessible(packetClass.getDeclaredField("b")).set(animationPacket, animationId); 62 | 63 | return animationPacket; 64 | } catch (Exception e) { 65 | throw new RuntimeException(e); 66 | } 67 | } 68 | 69 | public static Object buildPacketPlayOutEntityTeleport(int id, double x, double y, double z, float yaw, float pitch, boolean onGround, boolean heightCorrection) { 70 | try { 71 | Class packetClass = Reflection.nmsClassResolver.resolve("PacketPlayOutEntityTeleport"); 72 | Object teleportPacket; 73 | if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_8_R1)) { 74 | teleportPacket = packetClass.getConstructor(int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class, boolean.class) 75 | .newInstance(id, floor(x * 32.0D), floor(y * 32.0D), floor(z * 32.0D), (byte) (int) (yaw * 256F / 360F), (byte) (int) (pitch * 256F / 360F), onGround, heightCorrection); 76 | } else if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_9_R1)) { 77 | teleportPacket = packetClass.getConstructor(int.class, int.class, int.class, int.class, byte.class, byte.class, boolean.class) 78 | .newInstance(id, floor(x * 32.0D), floor(y * 32.0D), floor(z * 32.0D), (byte) (int) (yaw * 256F / 360F), (byte) (int) (pitch * 256F / 360F), onGround); 79 | } else { 80 | teleportPacket = packetClass.newInstance(); 81 | AccessUtil.setAccessible(packetClass.getDeclaredField("a")).set(teleportPacket, id); 82 | AccessUtil.setAccessible(packetClass.getDeclaredField("b")).set(teleportPacket, x); 83 | AccessUtil.setAccessible(packetClass.getDeclaredField("c")).set(teleportPacket, y); 84 | AccessUtil.setAccessible(packetClass.getDeclaredField("d")).set(teleportPacket, z); 85 | AccessUtil.setAccessible(packetClass.getDeclaredField("e")).set(teleportPacket, (byte) (int) (yaw * 256F / 360F)); 86 | AccessUtil.setAccessible(packetClass.getDeclaredField("f")).set(teleportPacket, (byte) (int) (pitch * 256F / 360F)); 87 | AccessUtil.setAccessible(packetClass.getDeclaredField("g")).set(teleportPacket, onGround); 88 | } 89 | 90 | return teleportPacket; 91 | } catch (Exception e) { 92 | throw new RuntimeException(e); 93 | } 94 | } 95 | 96 | public static int floor(double d1) { 97 | int i = (int) d1; 98 | return d1 >= i ? i : i - 1; 99 | } 100 | 101 | static Class PacketListener = Reflection.nmsClassResolver.resolveSilent("PacketListener"); 102 | // 103 | // public static Object buildWatchableObject(int type, int index, Object value) throws Exception { 104 | // return NMSClass.nmsWatchableObject.getConstructor(int.class, int.class, Object.class).newInstance(type, index, value); 105 | // } 106 | // 107 | // public static Object setDataWatcherValue(Object dataWatcher, int index, Object value) throws Exception { 108 | // int type = getDataWatcherValueType(value); 109 | // 110 | // Object map = AccessUtil.setAccessible(NMSClass.nmsDataWatcher.getDeclaredField("dataValues")).get(dataWatcher); 111 | // NMUClass.gnu_trove_map_hash_TIntObjectHashMap.getDeclaredMethod("put", int.class, Object.class).invoke(map, index, buildWatchableObject(type, index, value)); 112 | // 113 | // return dataWatcher; 114 | // } 115 | // 116 | // public static int getDataWatcherValueType(Object value) { 117 | // int type = 0; 118 | // if (value instanceof Number) { 119 | // if (value instanceof Byte) { 120 | // type = 0; 121 | // } else if (value instanceof Short) { 122 | // type = 1; 123 | // } else if (value instanceof Integer) { 124 | // type = 2; 125 | // } else if (value instanceof Float) { 126 | // type = 3; 127 | // } 128 | // } else if (value instanceof String) { 129 | // type = 4; 130 | // } 131 | // // Should not be needed 132 | // // else if (value != null && value.getClass().equals(NMSClass.ItemStack)) { 133 | // // type = 5; 134 | // // } else if (value != null && (value.getClass().equals(NMSClass.ChunkCoordinates) || value.getClass().equals(NMSClass.BlockPosition))) { 135 | // // type = 6; 136 | // // } else if (value != null && value.getClass().equals(NMSClass.Vector3f)) { 137 | // // type = 7; 138 | // // } 139 | // 140 | // return type; 141 | // } 142 | 143 | // public static Object getDataWatcher(org.bukkit.entity.Entity ent) { 144 | // try { 145 | // return NMSClass.nmsEntity.getDeclaredMethod("getDataWatcher").invoke(Reflection.getHandle(ent)); 146 | // } catch (Exception e) { 147 | // e.printStackTrace(); 148 | // } 149 | // return null; 150 | // } 151 | static FieldResolver NetworkManagerFieldResolver = new FieldResolver(NetworkManager); 152 | static MethodResolver NetworkManagerMethodResolver = new MethodResolver(NetworkManager); 153 | private static boolean initialized = false; 154 | 155 | static { 156 | try { 157 | ClassPool classPool = ClassPool.getDefault(); 158 | generatedChannel = ClassGenerator.generateChannel(classPool); 159 | generatedPlayerConnection = ClassGenerator.generatePlayerConnection(classPool); 160 | } catch (Exception e) { 161 | throw new RuntimeException(e); 162 | } 163 | } 164 | 165 | static { 166 | if (!initialized) { 167 | try { 168 | nmsPacketPlayOutPlayerInfo = Reflection.nmsClassResolver.resolve("PacketPlayOutPlayerInfo"); 169 | if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_8_R1)) { 170 | // if (NPCLib.getServerVersion() <= 181) { 171 | // nmsPlayerInfoData = Reflection.getNMSClassWithException("PlayerInfoData"); 172 | // } else { 173 | // nmsPlayerInfoData = Reflection.getNMSClassWithException("PacketPlayOutPlayerInfo$PlayerInfoData"); 174 | // } 175 | nmsPlayerInfoData = Reflection.nmsClassResolver.resolve("PlayerInfoData", "PacketPlayOutPlayerInfo$PlayerInfoData"); 176 | // if (NPCLib.getServerVersion() <= 181) { 177 | // nmsEnumPlayerInfoAction = Reflection.getNMSClassWithException("EnumPlayerInfoAction"); 178 | // } else { 179 | // nmsEnumPlayerInfoAction = Reflection.getNMSClassWithException("PacketPlayOutPlayerInfo$EnumPlayerInfoAction"); 180 | // } 181 | nmsEnumPlayerInfoAction = Reflection.nmsClassResolver.resolve("EnumPlayerInfoAction", "PacketPlayOutPlayerInfo$EnumPlayerInfoAction"); 182 | } 183 | // if (NPCLib.getServerVersion() <= 181) { 184 | // nmsEnumGamemode = Reflection.getNMSClassWithException("EnumGamemode"); 185 | // } else { 186 | // nmsEnumGamemode = Reflection.getNMSClassWithException("WorldSettings$EnumGamemode"); 187 | // } 188 | nmsEnumGamemode = Reflection.nmsClassResolver.resolve("EnumGamemode", "WorldSettings$EnumGamemode"); 189 | initialized = true; 190 | } catch (Exception e) { 191 | e.printStackTrace(); 192 | } 193 | } 194 | } 195 | 196 | public static Object buildPlayerConnection(Object networkManager, Object entity) throws Exception { 197 | final Object playerConnection = generatedPlayerConnection.getDeclaredConstructor(Reflection.nmsClassResolver.resolve("MinecraftServer"), networkManager.getClass(), Reflection.nmsClassResolver.resolve("EntityPlayer")).newInstance(new MethodResolver(Bukkit.getServer().getClass()).resolve("getServer").invoke(Bukkit.getServer()), networkManager, entity); 198 | NetworkManagerMethodResolver.resolve(new ResolverQuery("setPacketListener", PacketListener), new ResolverQuery("a", PacketListener)).invoke(networkManager, playerConnection); 199 | return playerConnection; 200 | } 201 | 202 | public static Object buildNetworkManager(boolean clientBound) throws Exception { 203 | Object networkManager = Reflection.nmsClassResolver.resolve("NetworkManager").getConstructor(Reflection.nmsClassResolver.resolve("EnumProtocolDirection")).newInstance(Reflection.nmsClassResolver.resolve("EnumProtocolDirection").getEnumConstants()[clientBound ? 0 : 1]); 204 | 205 | Field channelField = NetworkManagerFieldResolver.resolveByFirstType(Reflection.classResolver.resolve("io.netty.channel.Channel")); 206 | Field addressField = NetworkManagerFieldResolver.resolveByFirstType(SocketAddress.class); 207 | 208 | Object parentChannel = generatedChannel.newInstance(); 209 | 210 | try { 211 | Field protocolVersionField = Reflection.nmsClassResolver.resolve("NetworkManager").getDeclaredField("c"); 212 | Object attribute = getNMUtilClass("io.netty.util.AttributeMap").getDeclaredMethod("attr", getNMUtilClass("io.netty.util.AttributeKey")).invoke(parentChannel, protocolVersionField.get(null)); 213 | getNMUtilClass("io.netty.util.Attribute").getDeclaredMethod("set", Object.class).invoke(attribute, 5);// TODO version based protocol 214 | } catch (NoSuchFieldException e) { 215 | e.printStackTrace(); 216 | } 217 | 218 | channelField.set(networkManager, parentChannel); 219 | addressField.set(networkManager, new SocketAddress() { 220 | private static final long serialVersionUID = 1108301788933825435L; 221 | }); 222 | 223 | return networkManager; 224 | } 225 | 226 | @SuppressWarnings({ 227 | "rawtypes", 228 | "unchecked" }) 229 | public static Object buildPlayerInfoPacket(int action, Object profile, int ping, int gamemodeOrdinal, String name) { 230 | try { 231 | Object packet = nmsPacketPlayOutPlayerInfo.newInstance(); 232 | 233 | if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_8_R1)) { 234 | AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("action")).set(packet, action); 235 | AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("player")).set(packet, profile); 236 | AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("gamemode")).set(packet, gamemodeOrdinal); 237 | AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("ping")).set(packet, ping); 238 | AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("username")).set(packet, name); 239 | } else { 240 | AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("a")).set(packet, nmsEnumPlayerInfoAction.getEnumConstants()[action]); 241 | List list = (List) AccessUtil.setAccessible(nmsPacketPlayOutPlayerInfo.getDeclaredField("b")).get(packet); 242 | 243 | Object data; 244 | // if (NPCLib.getServerVersion() <= 181) { 245 | data = nmsPlayerInfoData.getConstructor(nmsPacketPlayOutPlayerInfo, getNMUtilClass("com.mojang.authlib.GameProfile"), int.class, nmsEnumGamemode, Reflection.nmsClassResolver.resolve("IChatBaseComponent")).newInstance(packet, profile, ping, nmsEnumGamemode.getEnumConstants()[gamemodeOrdinal], buildChatComponent(name)); 246 | // } else { 247 | // data = nmsPlayerInfoData.getConstructor(getNMUtilClass("com.mojang.authlib.GameProfile"), int.class, nmsEnumGamemode, 248 | // Reflection.getNMSClass("IChatBaseComponent")).newInstance(profile, ping, nmsEnumGamemode.getEnumConstants()[gamemodeOrdinal], buildChatComponent(name)); 249 | // } 250 | list.add(data); 251 | } 252 | return packet; 253 | } catch (Exception e) { 254 | e.printStackTrace(); 255 | } 256 | return null; 257 | } 258 | 259 | public static Object buildChatComponent(String string) { 260 | Object comp = null; 261 | try { 262 | Object[] components = (Object[]) Reflection.obcClassResolver.resolve("util.CraftChatMessage").getMethod("fromString", String.class).invoke(null, string); 263 | if (components.length > 0) { 264 | comp = components[0]; 265 | } 266 | } catch (Exception e) { 267 | e.printStackTrace(); 268 | } 269 | return comp; 270 | } 271 | 272 | public static Class getNMUtilClass(String name) throws ClassNotFoundException { 273 | if (Minecraft.VERSION.olderThan(Minecraft.Version.v1_8_R1)) { return Class.forName("net.minecraft.util." + name); } else { return Class.forName(name); } 274 | } 275 | } 276 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/INPCChannel.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | public interface INPCChannel { 4 | 5 | void setOpen(boolean open); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/INPCPlayerConnection.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | public interface INPCPlayerConnection { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/NPCLib.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import com.google.common.base.Joiner; 4 | import com.mojang.authlib.GameProfile; 5 | import lombok.NonNull; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.entity.Entity; 8 | import org.bukkit.entity.Player; 9 | import org.bukkit.plugin.Plugin; 10 | import org.inventivetalent.apihelper.API; 11 | import org.inventivetalent.npclib.entity.NPCEntity; 12 | import org.inventivetalent.npclib.event.NPCInteractEvent; 13 | import org.inventivetalent.npclib.npc.NPCAbstract; 14 | import org.inventivetalent.npclib.npc.living.human.NPCPlayer; 15 | import org.inventivetalent.npclib.registry.NPCRegistry; 16 | import org.inventivetalent.packetlistener.handler.PacketHandler; 17 | import org.inventivetalent.packetlistener.handler.PacketOptions; 18 | import org.inventivetalent.packetlistener.handler.ReceivedPacket; 19 | import org.inventivetalent.packetlistener.handler.SentPacket; 20 | import org.inventivetalent.reflection.minecraft.Minecraft; 21 | 22 | import java.io.IOException; 23 | import java.io.InputStream; 24 | import java.util.Properties; 25 | import java.util.UUID; 26 | import java.util.logging.Level; 27 | import java.util.logging.Logger; 28 | 29 | public class NPCLib implements API { 30 | 31 | public static Logger logger = Logger.getLogger("NPCLib"); 32 | public static boolean debug; 33 | 34 | public static NPCRegistry createRegistry(@NonNull Plugin plugin) { 35 | // return Reflection.newInstance("org.inventivetalent.npc.registry", "NPCRegistry", NPCRegistry.class, plugin); 36 | return new NPCRegistry(plugin); 37 | } 38 | 39 | public static boolean isNPC(Entity entity) { 40 | if (entity == null) { return false; } 41 | try { 42 | return Minecraft.getHandle(entity) instanceof NPCEntity; 43 | } catch (Exception e) { 44 | throw new RuntimeException(e); 45 | } 46 | } 47 | 48 | public static NPCAbstract getNPC(Entity entity) { 49 | if (entity == null) { return null; } 50 | try { 51 | Object handle = Minecraft.getHandle(entity); 52 | if (handle instanceof NPCEntity) { 53 | return ((NPCEntity) handle).getNPC(); 54 | } 55 | } catch (Exception e) { 56 | throw new RuntimeException(e); 57 | } 58 | return null; 59 | } 60 | 61 | public static void debug(Object... message) { 62 | if (debug) { logger.info("[DEBUG] " + Joiner.on(" ").join(message)); } 63 | } 64 | 65 | public static final String getVersion() { 66 | try (InputStream in = NPCLib.class.getResourceAsStream("/npclib.properties")) { 67 | Properties properties = new Properties(); 68 | properties.load(in); 69 | return properties.getProperty("npclib.version"); 70 | } catch (IOException e) { 71 | logger.log(Level.WARNING, "Failed to get API version from npclib.properties", e); 72 | return "0.0.0"; 73 | } 74 | } 75 | 76 | @Override 77 | public void load() { 78 | long start = System.currentTimeMillis(); 79 | Class[] classes = new Class[NPCType.values().length]; 80 | for (int i = 0; i < classes.length; ) { 81 | if (NPCType.values()[i].isAvailable()) { 82 | classes[i] = NPCType.values()[i].getNpcClass(); 83 | } 84 | i++; 85 | } 86 | NPCRegistry.injectClasses(classes); 87 | long end = System.currentTimeMillis(); 88 | long diff = end - start; 89 | logger.info("Generated & Injected available entity classes in " + (diff / 1000D) + "s"); 90 | } 91 | 92 | @Override 93 | public void init(final Plugin plugin) { 94 | PacketHandler.addHandler(new PacketHandler(plugin) { 95 | @PacketOptions(forcePlayer = true) 96 | @Override 97 | public void onSend(final SentPacket sentPacket) { 98 | if (sentPacket.hasPlayer()) { 99 | if ("PacketPlayOutNamedEntitySpawn".equals(sentPacket.getPacketName())) { 100 | final Player player = sentPacket.getPlayer(); 101 | final UUID uuid = Minecraft.VERSION.newerThan(Minecraft.Version.v1_8_R1) ? 102 | ((UUID) sentPacket.getPacketValue("b")) : 103 | (((GameProfile) sentPacket.getPacketValue("b")).getId()); 104 | Player npcPlayer = null; 105 | //TODO: check if this doesn't cause any ConcurrentModExceptions / make this synchronous somehow 106 | for (Player worldPlayer : player.getWorld().getPlayers()) {// We can't use Bukkit#getOnlinePlayers, since the server doesn't know about the player NPCs 107 | if (worldPlayer.getUniqueId().equals(uuid)) { 108 | npcPlayer = worldPlayer; 109 | break; 110 | } 111 | } 112 | if (npcPlayer != null) { 113 | NPCAbstract npcAbstract = NPCLib.getNPC(npcPlayer); 114 | if (npcAbstract != null && npcAbstract instanceof NPCPlayer) { 115 | ((NPCPlayer) npcAbstract).updateToPlayer(player); 116 | } 117 | } 118 | } 119 | } 120 | } 121 | 122 | @PacketOptions(forcePlayer = true) 123 | @Override 124 | public void onReceive(ReceivedPacket receivedPacket) { 125 | if (receivedPacket.hasPlayer()) { 126 | if ("PacketPlayInUseEntity".equals(receivedPacket.getPacketName())) { 127 | int a = (int) receivedPacket.getPacketValue(0); 128 | Entity entity = Reflection.getEntityById(receivedPacket.getPlayer().getWorld(), a); 129 | if (entity == null || !NPCLib.isNPC(entity)) { 130 | return; 131 | } 132 | Enum action = (Enum) receivedPacket.getPacketValue(1); 133 | 134 | NPCInteractEvent event = new NPCInteractEvent(NPCLib.getNPC(entity), a, action == null ? -1 : action.ordinal(), receivedPacket.getPlayer()); 135 | Bukkit.getPluginManager().callEvent(event); 136 | if (event.isCancelled()) { 137 | receivedPacket.setCancelled(true); 138 | } 139 | } 140 | } 141 | } 142 | }); 143 | 144 | String version = getVersion(); 145 | logger.info("Version is " + version); 146 | } 147 | 148 | @Override 149 | public void disable(Plugin plugin) { 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/NPCType.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import com.google.common.base.Strings; 4 | import com.google.common.collect.Maps; 5 | import lombok.Getter; 6 | import org.bukkit.entity.EntityType; 7 | import org.inventivetalent.npclib.npc.NPCAbstract; 8 | import org.inventivetalent.npclib.npc.NPCExperienceOrb; 9 | import org.inventivetalent.npclib.npc.NPCItem; 10 | import org.inventivetalent.npclib.npc.living.NPCArmorStand; 11 | import org.inventivetalent.npclib.npc.living.human.NPCPlayer; 12 | import org.inventivetalent.npclib.npc.living.insentient.NPCEnderDragon; 13 | import org.inventivetalent.npclib.npc.living.insentient.NPCPigZombie; 14 | import org.inventivetalent.npclib.npc.living.insentient.NPCSlime; 15 | import org.inventivetalent.npclib.npc.living.insentient.NPCZombie; 16 | import org.inventivetalent.npclib.npc.living.insentient.creature.ageable.NPCVillager; 17 | import org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.*; 18 | import org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.tameable.NPCOcelot; 19 | import org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.tameable.NPCWolf; 20 | import org.inventivetalent.npclib.npc.living.insentient.creature.golem.NPCIronGolem; 21 | import org.inventivetalent.npclib.npc.living.insentient.creature.golem.NPCShulker; 22 | import org.inventivetalent.npclib.npc.living.insentient.creature.golem.NPCSnowman; 23 | import org.inventivetalent.npclib.npc.living.insentient.creature.monster.*; 24 | import org.inventivetalent.npclib.npc.living.insentient.flying.NPCGhast; 25 | import org.inventivetalent.npclib.npc.living.insentient.water.NPCSquid; 26 | 27 | import java.util.Map; 28 | 29 | import static com.google.common.base.Preconditions.checkNotNull; 30 | 31 | public enum NPCType { 32 | DROPPED_ITEM("DROPPED_ITEM", NPCItem.class), 33 | EXPERIENCE_ORB("EXPERIENCE_ORB", NPCExperienceOrb.class), 34 | 35 | HUSK("HUSK", NPCHusk.class), 36 | 37 | ARMOR_STAND("ARMOR_STAND", NPCArmorStand.class), 38 | 39 | CREEPER("CREEPER", NPCCreeper.class), 40 | SKELETON("SKELETON", NPCSkeleton.class), 41 | SPIDER("SPIDER", NPCSpider.class), 42 | GIANT("GIANT", NPCGiant.class), 43 | ZOMBIE("ZOMBIE", NPCZombie.class), 44 | SLIME("SLIME", NPCSlime.class), 45 | GHAST("GHAST", NPCGhast.class), 46 | PIG_ZOMBIE("PIG_ZOMBIE", NPCPigZombie.class), 47 | ENDERMAN("ENDERMAN", NPCEnderman.class), 48 | CAVE_SPIDER("CAVE_SPIDER", NPCCaveSpider.class), 49 | ENDER_DRAGON("ENDER_DRAGON", NPCEnderDragon.class), 50 | WITHER("WITHER", NPCWither.class), 51 | WITCH("WITCH", NPCWitch.class), 52 | ENDERMITE("ENDERMITE", NPCEndermite.class), 53 | GUARDIAN("GUARDIAN", NPCGuardian.class), 54 | SHULKER("SHULKER", NPCShulker.class), 55 | 56 | PIG("PIG", NPCPig.class), 57 | SHEEP("SHEEP", NPCSheep.class), 58 | COW("COW", NPCCow.class), 59 | CHICKEN("CHICKEN", NPCChicken.class), 60 | SQUID("SQUID", NPCSquid.class), 61 | WOLF("WOLF", NPCWolf.class), 62 | MUSHROOM_COW("MUSHROOM_COW", NPCMushroomCow.class), 63 | SNOWMAN("SNOWMAN", NPCSnowman.class), 64 | OCELOT("OCELOT", NPCOcelot.class), 65 | IRON_GOLEM("IRON_GOLEM", NPCIronGolem.class), 66 | HORSE("HORSE", NPCHorse.class), 67 | RABBIT("RABBIT", NPCRabbit.class), 68 | POLAR_BEAR("POLAR_BEAR", NPCPolarBear.class), 69 | LLAMA("LLAMA", NPCLlama.class), 70 | 71 | VILLAGER("VILLAGER", NPCVillager.class), 72 | 73 | PLAYER("PLAYER", NPCPlayer.class); 74 | 75 | private static final Map entityTypeMap = Maps.newHashMap(); 76 | private static final Map>, NPCType> classMap = Maps.newHashMap(); 77 | 78 | static { 79 | for (NPCType npcType : values()) { 80 | if (npcType.entityType != null) { 81 | entityTypeMap.put(npcType.entityType, npcType); 82 | } 83 | if (npcType.npcClass != null) { 84 | classMap.put(npcType.npcClass, npcType); 85 | } 86 | } 87 | } 88 | 89 | @Getter private EntityType entityType; 90 | @Getter private Class> npcClass; 91 | 92 | NPCType(EntityType entityType, Class> npcClass) { 93 | this.entityType = entityType; 94 | this.npcClass = npcClass; 95 | } 96 | 97 | NPCType(String entityTypeName, Class> npcClass) { 98 | try { 99 | this.entityType = EntityType.valueOf(entityTypeName); 100 | this.npcClass = npcClass; 101 | } catch (NoSuchFieldError | IllegalArgumentException ignored) { 102 | NPCLib.logger.warning("NPCType " + name() + " is not supported on this server version"); 103 | } 104 | } 105 | 106 | public static NPCType forEntityType(EntityType entityType) { 107 | return entityTypeMap.get(checkNotNull(entityType)); 108 | } 109 | 110 | public static NPCType forNpcClass(Class> clazz) { 111 | return classMap.get(clazz); 112 | } 113 | 114 | public static NPCType fromString(String string) { 115 | if (Strings.isNullOrEmpty(string)) { return null; } 116 | NPCType type; 117 | if ((type = valueOfOrNull(string.toUpperCase())) != null) { 118 | return type; 119 | } 120 | if ((type = valueOfOrNull(string.toUpperCase().replace(" ", "_"))) != null) { 121 | return type; 122 | } 123 | if ((type = valueOfOrNull(string.toUpperCase().replaceAll("\\s", ""))) != null) { 124 | return type; 125 | } 126 | for (NPCType npcType : values()) { 127 | String combined = npcType.name().replace("_", ""); 128 | if (combined.equals(string.toUpperCase())) { 129 | return npcType; 130 | } 131 | } 132 | return null; 133 | } 134 | 135 | private static NPCType valueOfOrNull(String string) { 136 | try { 137 | return valueOf(string); 138 | } catch (IllegalArgumentException e) { 139 | return null; 140 | } 141 | } 142 | 143 | /** 144 | * Check if this NPC type is available for the current server version 145 | * 146 | * @return whether this type is available 147 | */ 148 | public boolean isAvailable() { 149 | return this.entityType != null && this.npcClass != null; 150 | } 151 | 152 | } 153 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/ObjectContainer.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Data; 5 | import lombok.EqualsAndHashCode; 6 | 7 | @Data 8 | @AllArgsConstructor 9 | @EqualsAndHashCode 10 | public class ObjectContainer { 11 | 12 | public T value; 13 | 14 | public static ObjectContainer[] fromObjects(Object[] objects) { 15 | ObjectContainer[] containers = new ObjectContainer[objects.length]; 16 | for (int i = 0; i < objects.length; i++) 17 | containers[i] = new ObjectContainer<>(objects[i]); 18 | return containers; 19 | } 20 | 21 | public static Object[] toObjects(ObjectContainer[] containers) { 22 | Object[] objects = new Object[containers.length]; 23 | for (int i = 0; i < containers.length; i++) 24 | objects[i] = containers[i].value; 25 | return objects; 26 | } 27 | 28 | @Override 29 | public String toString() { 30 | if (value == null) { return "ObjectContainer[null]"; } 31 | return value.toString(); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/ObjectConverter.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | public class ObjectConverter { 4 | 5 | public static Object toObject(Object o) { 6 | return o; 7 | } 8 | 9 | public static Object toObject(byte b) { 10 | return Byte.valueOf(b); 11 | } 12 | 13 | public static Object toObject(short s) { 14 | return Short.valueOf(s); 15 | } 16 | 17 | public static Object toObject(int i) { 18 | return Integer.valueOf(i); 19 | } 20 | 21 | public static Object toObject(long l) { 22 | return Long.valueOf(l); 23 | } 24 | 25 | public static Object toObject(float f) { 26 | return Float.valueOf(f); 27 | } 28 | 29 | public static Object toObject(double d) { 30 | return Double.valueOf(d); 31 | } 32 | 33 | public static Object toObject(boolean b) { 34 | return Boolean.valueOf(b); 35 | } 36 | 37 | public static Object toObject(char c) { 38 | return Character.valueOf(c); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/Reflection.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import org.bukkit.World; 4 | import org.bukkit.entity.Entity; 5 | import org.bukkit.event.entity.EntityDamageEvent; 6 | import org.inventivetalent.reflection.minecraft.Minecraft; 7 | import org.inventivetalent.reflection.resolver.ClassResolver; 8 | import org.inventivetalent.reflection.resolver.MethodResolver; 9 | import org.inventivetalent.reflection.resolver.ResolverQuery; 10 | import org.inventivetalent.reflection.resolver.minecraft.NMSClassResolver; 11 | import org.inventivetalent.reflection.resolver.minecraft.OBCClassResolver; 12 | import org.inventivetalent.reflection.resolver.wrapper.MethodWrapper; 13 | import org.inventivetalent.reflection.util.AccessUtil; 14 | 15 | import java.lang.reflect.Field; 16 | import java.lang.reflect.Method; 17 | 18 | public class Reflection { 19 | 20 | public static final boolean is1_9 = Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1); 21 | public static final boolean is1_8 = !is1_9 && Minecraft.VERSION.newerThan(Minecraft.Version.v1_8_R1); 22 | public static final boolean is1_7 = !is1_8 && Minecraft.VERSION.newerThan(Minecraft.Version.v1_7_R1); 23 | 24 | public static final ClassResolver classResolver = new ClassResolver(); 25 | public static final NMSClassResolver nmsClassResolver = new NMSClassResolver(); 26 | public static final OBCClassResolver obcClassResolver = new OBCClassResolver(); 27 | 28 | public static boolean doesClassExist(String name) { 29 | try { 30 | return Class.forName(name) != null; 31 | } catch (ClassNotFoundException e) { 32 | } 33 | return false; 34 | } 35 | 36 | public static String getMethodSignature(Method method) { 37 | // StringBuilder stringBuilder = new StringBuilder(method.getName()); 38 | // stringBuilder.append("("); 39 | // 40 | // boolean first = true; 41 | // for (Class clazz : method.getParameterTypes()) { 42 | // if (!first) { stringBuilder.append(","); } 43 | // stringBuilder.append(clazz.getSimpleName()); 44 | // first = false; 45 | // } 46 | // return stringBuilder.append(")").toString(); 47 | return MethodWrapper.getMethodSignature(method, false); 48 | } 49 | 50 | public static String getDamageSourceName(Object damageSource) { 51 | if (damageSource != null) { 52 | try { 53 | return (String) Reflection.nmsClassResolver.resolve("DamageSource").getField("translationIndex").get(damageSource); 54 | } catch (ReflectiveOperationException e) { 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | return null; 59 | } 60 | 61 | public static EntityDamageEvent.DamageCause damageSourceToCause(String damageName) { 62 | if (damageName == null) { 63 | return EntityDamageEvent.DamageCause.VOID; 64 | } 65 | EntityDamageEvent.DamageCause cause = EntityDamageEvent.DamageCause.CUSTOM; 66 | switch (damageName) { 67 | case "inFire": 68 | cause = EntityDamageEvent.DamageCause.FIRE; 69 | break; 70 | case "onFire": 71 | cause = EntityDamageEvent.DamageCause.FIRE_TICK; 72 | break; 73 | case "lava": 74 | cause = EntityDamageEvent.DamageCause.LAVA; 75 | break; 76 | case "inWall": 77 | cause = EntityDamageEvent.DamageCause.SUFFOCATION; 78 | break; 79 | case "drown": 80 | cause = EntityDamageEvent.DamageCause.DROWNING; 81 | break; 82 | case "starve": 83 | cause = EntityDamageEvent.DamageCause.STARVATION; 84 | break; 85 | case "cactus": 86 | cause = EntityDamageEvent.DamageCause.CONTACT; 87 | break; 88 | case "fall": 89 | cause = EntityDamageEvent.DamageCause.FALL; 90 | break; 91 | case "outOfWorld": 92 | cause = EntityDamageEvent.DamageCause.VOID; 93 | break; 94 | case "generic": 95 | cause = EntityDamageEvent.DamageCause.CUSTOM; 96 | break; 97 | case "indirectMagic": 98 | cause = EntityDamageEvent.DamageCause.MAGIC; 99 | break; 100 | case "magic": 101 | cause = EntityDamageEvent.DamageCause.POISON; 102 | break; 103 | case "wither": 104 | cause = EntityDamageEvent.DamageCause.WITHER; 105 | break; 106 | case "anvil": 107 | case "fallingBlock": 108 | cause = EntityDamageEvent.DamageCause.FALLING_BLOCK; 109 | break; 110 | case "thorns": 111 | cause = EntityDamageEvent.DamageCause.THORNS; 112 | break; 113 | case "fireball": 114 | case "arrow": 115 | cause = EntityDamageEvent.DamageCause.PROJECTILE; 116 | break; 117 | case "thrown":// No idea what causes this 118 | case "mob": 119 | case "player": 120 | cause = EntityDamageEvent.DamageCause.ENTITY_ATTACK; 121 | break; 122 | case "explosion.player": 123 | case "explosion": 124 | cause = EntityDamageEvent.DamageCause.ENTITY_EXPLOSION; 125 | break; 126 | case "dragonBreath": 127 | cause = EntityDamageEvent.DamageCause.DRAGON_BREATH; 128 | break; 129 | case "flyIntoWall": 130 | cause = EntityDamageEvent.DamageCause.FLY_INTO_WALL; 131 | break; 132 | case "hotFloor": 133 | cause = EntityDamageEvent.DamageCause.HOT_FLOOR; 134 | break; 135 | default: 136 | break; 137 | } 138 | return cause; 139 | } 140 | 141 | public static Entity getEntityFromDamageSource(Object damageSource) { 142 | if (damageSource == null) { return null; } 143 | try { 144 | Class classDamageSource = nmsClassResolver.resolve("DamageSource"); 145 | Object nmsEntity = classDamageSource.getDeclaredMethod("getEntity").invoke(damageSource); 146 | if (nmsEntity == null) { return null; } 147 | return Minecraft.getBukkitEntity(nmsEntity); 148 | } catch (ReflectiveOperationException e) { 149 | throw new RuntimeException(); 150 | } 151 | } 152 | 153 | public static Entity getEntityById(World world, int id) { 154 | try { 155 | Field mapField = AccessUtil.setAccessible(nmsClassResolver.resolve("World").getDeclaredField("entitiesById")); 156 | Object nmsEntity = nmsClassResolver.resolve("IntHashMap").getDeclaredMethod("get", int.class).invoke(mapField.get(Minecraft.getHandle(world)), id); 157 | return nmsEntity == null ? null : Minecraft.getBukkitEntity(nmsEntity); 158 | } catch (ReflectiveOperationException e) { 159 | throw new RuntimeException(e); 160 | } 161 | } 162 | 163 | public static void mergeNBTCompound(Object originalTag, Object toMerge) { 164 | try { 165 | Class clazz = nmsClassResolver.resolve("NBTTagCompound"); 166 | Method method = new MethodResolver(clazz).resolve(new ResolverQuery("merge", clazz)/*(SRG mapping)*/, new ResolverQuery("a", clazz)); 167 | method.invoke(originalTag, toMerge); 168 | } catch (ReflectiveOperationException e) { 169 | throw new RuntimeException(e); 170 | } 171 | } 172 | 173 | public static Object getDataWatcher(org.bukkit.entity.Entity ent) { 174 | try { 175 | return nmsClassResolver.resolve("Entity").getDeclaredMethod("getDataWatcher").invoke(Minecraft.getHandle(ent)); 176 | } catch (Exception e) { 177 | e.printStackTrace(); 178 | } 179 | return null; 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/SuperSwitch.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import lombok.*; 4 | import org.bukkit.event.Cancellable; 5 | 6 | @Data 7 | @NoArgsConstructor 8 | @AllArgsConstructor 9 | @EqualsAndHashCode 10 | @ToString 11 | public class SuperSwitch implements Cancellable { 12 | 13 | private State state = State.PASS; 14 | 15 | public static SuperSwitch newInstance() { 16 | return new SuperSwitch(); 17 | } 18 | 19 | @Override 20 | public boolean isCancelled() { 21 | return this.state == State.CANCEL; 22 | } 23 | 24 | @Override 25 | public void setCancelled(boolean b) { 26 | this.state = State.CANCEL; 27 | } 28 | 29 | public boolean callSuper() { 30 | return this.state == State.PASS || this.state == State.REPLACE; 31 | } 32 | 33 | public boolean isReplace() { 34 | return this.state == State.REPLACE; 35 | } 36 | 37 | public enum State { 38 | /** 39 | * Let the call pass and return the default value by calling the super method 40 | */ 41 | PASS, 42 | /** 43 | * Cancel the call entirely and don't call super 44 | */ 45 | CANCEL, 46 | /** 47 | * Call super, but replace the returned value of the method 48 | */ 49 | REPLACE; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/ai/AIAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.ai; 2 | 3 | import org.inventivetalent.npclib.npc.NPCAbstract; 4 | 5 | public class AIAbstract> { 6 | 7 | private N npc; 8 | 9 | /** 10 | * Called when the containing NPC is ticked 11 | */ 12 | public void tick() { 13 | } 14 | 15 | /** 16 | * If this returns true, this AI will be removed from the NPC 17 | * 18 | * @return if true, the AI will be removed 19 | */ 20 | public boolean isFinished() { 21 | return false; 22 | } 23 | 24 | public final N getNpc() { 25 | if (this.npc == null) { throw new IllegalStateException("npc not set"); } 26 | return this.npc; 27 | } 28 | 29 | public final void setNpc(N npc) { 30 | if (this.npc != null) { throw new IllegalStateException("npc already set"); } 31 | this.npc = npc; 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/animation/Animation.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.animation; 2 | 3 | public enum Animation { 4 | 5 | SWING_MAIN_ARM(Type.ANIMATION, 0), 6 | TAKE_DAMAGE(Type.ANIMATION, 1), 7 | LEAVE_BED(Type.ANIMATION, 2), 8 | SWING_OFF_HAND(Type.ANIMATION, 3), 9 | CRITICAL_EFFECT(Type.ANIMATION, 4), 10 | CRITICAL_EFFECT_MAGIC(Type.ANIMATION, 5), 11 | 12 | ENTITY_HURT(Type.STATUS, 2), 13 | ENTITY_DEATH(Type.STATUS, 3), 14 | IRON_GOLEM_ARMS(Type.STATUS, 4), 15 | WOLF_SHAKE(Type.STATUS, 8), 16 | SHEEP_EAT(Type.STATUS, 10), 17 | IRON_GOLEM_ROSE(Type.STATUS, 11), 18 | RESET_SQUID_ROTATION(Type.STATUS, 19); 19 | 20 | private final Type type; 21 | private final int id; 22 | 23 | Animation(Type type, int id) { 24 | this.type = type; 25 | this.id = id; 26 | } 27 | 28 | public Type getType() { 29 | return type; 30 | } 31 | 32 | public int getId() { 33 | return id; 34 | } 35 | 36 | public enum Type { 37 | STATUS, 38 | ANIMATION; 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/annotation/ExtraMethod.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.annotation; 2 | 3 | import org.inventivetalent.reflection.minecraft.Minecraft; 4 | 5 | import java.lang.annotation.ElementType; 6 | import java.lang.annotation.Retention; 7 | import java.lang.annotation.RetentionPolicy; 8 | import java.lang.annotation.Target; 9 | 10 | @Target(ElementType.METHOD) 11 | @Retention(RetentionPolicy.RUNTIME) 12 | public @interface ExtraMethod { 13 | 14 | String value(); 15 | 16 | /** 17 | * If specified, the annotated method will be generate for this version upwards 18 | * @return the Version 19 | */ 20 | Minecraft.Version fromVersion() default Minecraft.Version.UNKNOWN; 21 | 22 | /** 23 | * If specified, the annotated method will be generate for this version downwards 24 | * @return the Version 25 | */ 26 | Minecraft.Version untilVersion() default Minecraft.Version.UNKNOWN; 27 | 28 | /** 29 | * If specified, the annotated method will be generate for only these versions 30 | * @return the Version 31 | */ 32 | Minecraft.Version[] forVersion() default {}; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/annotation/ExtraMethods.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.annotation; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface ExtraMethods { 11 | ExtraMethod[] value(); 12 | } 13 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/annotation/NPC.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.annotation; 2 | 3 | import org.bukkit.entity.Entity; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.entity.NPCEntity; 6 | 7 | import java.lang.annotation.ElementType; 8 | import java.lang.annotation.Retention; 9 | import java.lang.annotation.RetentionPolicy; 10 | import java.lang.annotation.Target; 11 | 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target(ElementType.TYPE) 14 | public @interface NPC { 15 | 16 | int id(); 17 | 18 | EntityType type(); 19 | 20 | Class bukkit(); 21 | 22 | String nms(); 23 | 24 | Class entity(); 25 | 26 | String[] constructors() default { 27 | "public %1$s(World world){\n" 28 | + " super(world);\n" 29 | + " this.$npc = new %2$s(this);\n" 30 | + "}" }; 31 | 32 | String[] extraPackages() default {}; 33 | 34 | String[] extraFields() default {}; 35 | 36 | String[] extraMethods() default {}; 37 | 38 | } 39 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/annotation/NPCInfo.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.annotation; 2 | 3 | import lombok.*; 4 | import org.bukkit.entity.Entity; 5 | import org.bukkit.entity.EntityType; 6 | import org.inventivetalent.npclib.Reflection; 7 | import org.inventivetalent.npclib.entity.NPCEntity; 8 | 9 | import java.lang.reflect.Modifier; 10 | 11 | import static com.google.common.base.Preconditions.checkArgument; 12 | import static com.google.common.base.Preconditions.checkNotNull; 13 | import static com.google.common.base.Strings.emptyToNull; 14 | 15 | @RequiredArgsConstructor(access = AccessLevel.PRIVATE) 16 | @Data 17 | @EqualsAndHashCode 18 | @ToString 19 | public class NPCInfo { 20 | 21 | private final int id; 22 | private final EntityType type; 23 | private final Class bukkit; 24 | private final String nms; 25 | private final Class entity; 26 | private final String[] constructors; 27 | private final String[] extraPackages; 28 | private final String[] extraFields; 29 | private final String[] extraMethods; 30 | private Class npcClass; 31 | 32 | public static NPCInfo of(NPC annotation) { 33 | checkNotNull(annotation); 34 | return new NPCInfo(annotation.id(), checkNotNull(annotation.type()), checkNotNull(annotation.bukkit()), checkNotNull(emptyToNull(annotation.nms())), checkNotNull(annotation.entity()), annotation.constructors(), annotation.extraPackages(), annotation.extraFields(), annotation.extraMethods()); 35 | } 36 | 37 | public static NPCInfo of(Class clazz) { 38 | checkNotNull(clazz); 39 | checkArgument(!Modifier.isAbstract(clazz.getModifiers()), "Cannot use @NPC on abstract class"); 40 | checkArgument(!clazz.isInterface(), "Cannot use @NPC on interface"); 41 | NPC annotation = (NPC) clazz.getAnnotation(NPC.class); 42 | NPCInfo info = of(checkNotNull(annotation, "Class has no @NPC annotation")); 43 | info.npcClass = clazz; 44 | return info; 45 | } 46 | 47 | public Class getNMSClass() { 48 | try { 49 | return Reflection.nmsClassResolver.resolve(nms); 50 | } catch (ClassNotFoundException e) { 51 | throw new RuntimeException(e); 52 | } 53 | } 54 | 55 | public String getNPCClassName() { 56 | String className = npcClass.getName(); 57 | if (className.startsWith("org.inventivetalent.npclib.npc")) {// Internal NPCs 58 | return "NPC" + nms; 59 | } else { 60 | return className.replace(".", "_") + "_NPC"; 61 | } 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/EntityExperienceOrb.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity; 2 | 3 | public interface EntityExperienceOrb extends NPCEntity { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/EntityItem.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity; 2 | 3 | public interface EntityItem extends NPCEntity { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/NPCEntity.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity; 2 | 3 | import org.bukkit.event.entity.CreatureSpawnEvent; 4 | import org.inventivetalent.npclib.annotation.ExtraMethod; 5 | import org.inventivetalent.npclib.annotation.NPCInfo; 6 | import org.inventivetalent.npclib.npc.NPCAbstract; 7 | import org.inventivetalent.npclib.watcher.MethodWatcher; 8 | import org.inventivetalent.reflection.minecraft.Minecraft; 9 | import org.inventivetalent.vectors.d3.Vector3DDouble; 10 | 11 | public interface NPCEntity { 12 | 13 | void setMethodWatcher(MethodWatcher methodWatcher); 14 | 15 | @ExtraMethod("public NPCAbstract getNPC() {\n" 16 | + " return this.$npc;\n" 17 | + "}") 18 | NPCAbstract getNPC(); 19 | 20 | // T getBukkitEntity(); 21 | 22 | boolean methodCalled(String name, Object[] args); 23 | 24 | Object methodCalled(String name, Object superValue, Object[] args); 25 | 26 | NPCInfo getNpcInfo(); 27 | 28 | void setNpcInfo(NPCInfo npcInfo); 29 | 30 | // Overwritten methods 31 | 32 | void setLocation(double x, double y, double z, float yaw, float pitch); 33 | 34 | // The EnumMoveType was added in 1.11 as an anticheat feature. 35 | @ExtraMethod(value = "public void move(double x, double y, double z) {\n" 36 | + " move(EnumMoveType.SELF, x, y, z);\n" 37 | + "}", 38 | fromVersion = Minecraft.Version.v1_11_R1) 39 | void move(double x, double y, double z); 40 | 41 | // Helpers 42 | 43 | @ExtraMethod("public void spawn() {\n" 44 | + " this.world.addEntity(this);\n" 45 | + "}") 46 | void spawn(); 47 | 48 | @ExtraMethod("public void spawn(org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {\n" 49 | + " this.world.addEntity(this, spawnReason);\n" 50 | + "}") 51 | void spawn(CreatureSpawnEvent.SpawnReason spawnReason); 52 | 53 | @ExtraMethod("public org.inventivetalent.vectors.d3.Vector3DDouble getLocationVector() {\n" 54 | + " return new org.inventivetalent.vectors.d3.Vector3DDouble(this.locX, this.locY, this.locZ);\n" 55 | + "}") 56 | Vector3DDouble getLocationVector(); 57 | 58 | @ExtraMethod("public void setYaw(float yaw) {\n" 59 | + " this.yaw = yaw;\n" 60 | + "}") 61 | void setYaw(float yaw); 62 | 63 | @ExtraMethod("public void setPitch(float pitch) {\n" 64 | + " this.pitch = pitch;\n" 65 | + "}") 66 | void setPitch(float pitch); 67 | 68 | // mot? accessors 69 | 70 | @ExtraMethod("public double getMotX() {" 71 | + " return this.motX;\n" 72 | + "}") 73 | double getMotX(); 74 | 75 | @ExtraMethod("public void setMotX(double motX) {\n" 76 | + " this.motX = motX;\n" 77 | + "}") 78 | void setMotX(double motX); 79 | 80 | @ExtraMethod("public double getMotY() {" 81 | + " return this.motY;\n" 82 | + "}") 83 | double getMotY(); 84 | 85 | @ExtraMethod("public void setMotY(double motY) {\n" 86 | + " this.motY = motY;\n" 87 | + "}") 88 | void setMotY(double motY); 89 | 90 | @ExtraMethod("public double getMotZ() {" 91 | + " return this.motZ;\n" 92 | + "}") 93 | double getMotZ(); 94 | 95 | @ExtraMethod("public void setMotZ(double motZ) {\n" 96 | + " this.motZ = motZ;\n" 97 | + "}") 98 | void setMotZ(double motZ); 99 | 100 | } 101 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/EntityArmorStand.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living; 2 | 3 | public interface EntityArmorStand extends NPCEntityLiving { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/NPCEntityLiving.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living; 2 | 3 | import org.inventivetalent.npclib.entity.NPCEntity; 4 | 5 | public interface NPCEntityLiving extends NPCEntity { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/human/EntityPlayer.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.human; 2 | 3 | import org.bukkit.event.entity.CreatureSpawnEvent; 4 | import org.inventivetalent.npclib.annotation.ExtraMethod; 5 | 6 | public interface EntityPlayer extends NPCEntityHuman { 7 | 8 | @ExtraMethod("public void spawnPlayer(org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason spawnReason) {\n" 9 | + " this.world.players.add(this);\n" 10 | + " this.world.entityList.add(this);\n" 11 | + "}") 12 | void spawnPlayer(CreatureSpawnEvent.SpawnReason spawnReason); 13 | } 14 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/human/NPCEntityHuman.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.human; 2 | 3 | import com.mojang.authlib.GameProfile; 4 | import org.inventivetalent.npclib.entity.living.NPCEntityLiving; 5 | 6 | public interface NPCEntityHuman extends NPCEntityLiving { 7 | 8 | GameProfile getProfile(); 9 | 10 | void checkMovement(double x, double y, double z); 11 | 12 | } 13 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/EntityEnderDragon.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient; 2 | 3 | public interface EntityEnderDragon extends NPCEntityInsentient { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/EntityPigZombie.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient; 2 | 3 | public interface EntityPigZombie extends EntityZombie { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/EntitySlime.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient; 2 | 3 | public interface EntitySlime extends NPCEntityInsentient { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/EntityZombie.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient; 2 | 3 | public interface EntityZombie extends NPCEntityInsentient { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/NPCEntityInsentient.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient; 2 | 3 | import org.inventivetalent.npclib.entity.living.NPCEntityLiving; 4 | 5 | public interface NPCEntityInsentient extends NPCEntityLiving { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/NPCEntityCreature.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.NPCEntityInsentient; 4 | 5 | public interface NPCEntityCreature extends NPCEntityInsentient { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/EntityVillager.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable; 2 | 3 | public interface EntityVillager extends NPCEntityAgeable { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/NPCEntityAgeable.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.creature.NPCEntityCreature; 4 | 5 | public interface NPCEntityAgeable extends NPCEntityCreature { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityChicken.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityChicken extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityCow.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityCow extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityHorse.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityHorse extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityLlama.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityLlama extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityMushroomCow.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityMushroomCow extends EntityCow { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityPig.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityPig extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityPolarBear.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityPolarBear extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntityRabbit.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntityRabbit extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/EntitySheep.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | public interface EntitySheep extends NPCEntityAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/NPCEntityAnimal.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.NPCEntityAgeable; 4 | 5 | public interface NPCEntityAnimal extends NPCEntityAgeable { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/tameable/EntityOcelot.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.tameable; 2 | 3 | public interface EntityOcelot extends NPCEntityTameable { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/tameable/EntityWolf.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.tameable; 2 | 3 | public interface EntityWolf extends NPCEntityTameable { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/ageable/animal/tameable/NPCEntityTameable.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.tameable; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.NPCEntityAnimal; 4 | 5 | public interface NPCEntityTameable extends NPCEntityAnimal { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/golem/EntityIronGolem.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.golem; 2 | 3 | public interface EntityIronGolem extends NPCEntityGolem { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/golem/EntityShulker.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.golem; 2 | 3 | public interface EntityShulker extends NPCEntityGolem { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/golem/EntitySnowman.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.golem; 2 | 3 | public interface EntitySnowman extends NPCEntityGolem { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/golem/NPCEntityGolem.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.golem; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.creature.NPCEntityCreature; 4 | 5 | public interface NPCEntityGolem extends NPCEntityCreature { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityCaveSpider.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityCaveSpider extends EntitySpider { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityCreeper.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityCreeper extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityEnderman.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityEnderman extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityEndermite.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityEndermite extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityGiant.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityGiant extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityGuardian.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityGuardian extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityHusk.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.EntityZombie; 4 | 5 | public interface EntityHusk extends EntityZombie { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntitySkeleton.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntitySkeleton extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntitySpider.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntitySpider extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityWitch.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityWitch extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/EntityWither.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | public interface EntityWither extends NPCEntityMonster { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/creature/monster/NPCEntityMonster.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.creature.monster; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.creature.NPCEntityCreature; 4 | 5 | public interface NPCEntityMonster extends NPCEntityCreature { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/flying/EntityGhast.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.flying; 2 | 3 | public interface EntityGhast extends NPCEntityFlying { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/flying/NPCEntityFlying.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.flying; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.NPCEntityInsentient; 4 | 5 | public interface NPCEntityFlying extends NPCEntityInsentient { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/water/EntitySquid.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.water; 2 | 3 | public interface EntitySquid extends NPCEntityWaterAnimal { 4 | } 5 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/entity/living/insentient/water/NPCEntityWaterAnimal.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.entity.living.insentient.water; 2 | 3 | import org.inventivetalent.npclib.entity.living.insentient.NPCEntityInsentient; 4 | 5 | public interface NPCEntityWaterAnimal extends NPCEntityInsentient { 6 | } 7 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/equipment/EquipmentSlot.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.equipment; 30 | 31 | import org.inventivetalent.npclib.Reflection; 32 | import org.inventivetalent.reflection.minecraft.Minecraft; 33 | 34 | public enum EquipmentSlot { 35 | 36 | @Deprecated HAND(0), 37 | MAIN_HAND(0), 38 | OFF_HAND(1), 39 | FEET(2), 40 | LEGS(3), 41 | CHEST(4), 42 | HEAD(5); 43 | 44 | private int id; 45 | 46 | EquipmentSlot(int id) { 47 | this.id = id; 48 | } 49 | 50 | public int getID() { 51 | if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) { 52 | return this.id; 53 | } else { 54 | switch (this) { 55 | case OFF_HAND: 56 | return 0; 57 | case FEET: 58 | return 1; 59 | case LEGS: 60 | return 2; 61 | case CHEST: 62 | return 3; 63 | case HEAD: 64 | return 4; 65 | default: 66 | return this.id; 67 | } 68 | } 69 | } 70 | 71 | public Object toNMS() { 72 | if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) { 73 | try { 74 | return Reflection.nmsClassResolver.resolve("EnumItemSlot").getEnumConstants()[this.id]; 75 | } catch (ClassNotFoundException e) { 76 | throw new RuntimeException(e); 77 | } 78 | } else if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_8_R1)) { 79 | return getID(); 80 | } else { 81 | return null; 82 | } 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCCollisionEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event; 30 | 31 | import org.bukkit.entity.Entity; 32 | import org.bukkit.event.HandlerList; 33 | import org.inventivetalent.npclib.npc.NPCAbstract; 34 | 35 | public class NPCCollisionEvent extends NPCEvent { 36 | 37 | private Entity entity; 38 | 39 | public NPCCollisionEvent(NPCAbstract npc, Entity with) { 40 | super(npc); 41 | this.entity = with; 42 | } 43 | 44 | public Entity getEntity() { 45 | return entity; 46 | } 47 | 48 | private static HandlerList handlerList = new HandlerList(); 49 | 50 | @Override 51 | public HandlerList getHandlers() { 52 | return handlerList; 53 | } 54 | 55 | public static HandlerList getHandlerList() { 56 | return handlerList; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCDamageEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event; 30 | 31 | import org.bukkit.entity.Entity; 32 | import org.bukkit.event.Cancellable; 33 | import org.bukkit.event.HandlerList; 34 | import org.bukkit.event.entity.EntityDamageEvent; 35 | import org.inventivetalent.npclib.npc.NPCAbstract; 36 | 37 | import javax.annotation.Nullable; 38 | 39 | /** 40 | * Called if an NPC is damaged 41 | */ 42 | public class NPCDamageEvent extends NPCEvent implements Cancellable { 43 | 44 | private static HandlerList handlerList = new HandlerList(); 45 | private boolean cancelled; 46 | private String damageSourceName; 47 | private EntityDamageEvent.DamageCause damageCause; 48 | private float amount; 49 | private Entity damager; 50 | 51 | public NPCDamageEvent(NPCAbstract npc, String damageSourceName, EntityDamageEvent.DamageCause damageCause, 52 | float amount, Entity damager) { 53 | super(npc); 54 | 55 | this.damageSourceName = damageSourceName; 56 | this.damageCause = damageCause; 57 | this.amount = amount; 58 | this.damager = damager; 59 | } 60 | 61 | public static HandlerList getHandlerList() { 62 | return handlerList; 63 | } 64 | 65 | /** 66 | * Get the NMS damage source name 67 | * 68 | * @return the source name 69 | */ 70 | public String getDamageSourceName() { 71 | return damageSourceName; 72 | } 73 | 74 | /** 75 | * Get the damage cause 76 | * 77 | * @return the event's {@link org.bukkit.event.entity.EntityDamageEvent.DamageCause} 78 | */ 79 | public EntityDamageEvent.DamageCause getDamageCause() { 80 | return damageCause; 81 | } 82 | 83 | /** 84 | * Get the amount 85 | * 86 | * @return the damage amount 87 | */ 88 | public float getAmount() { 89 | return amount; 90 | } 91 | 92 | /** 93 | * Set the amount 94 | * 95 | * @param amount the new damage amount 96 | */ 97 | public void setAmount(float amount) { 98 | this.amount = amount; 99 | } 100 | 101 | /** 102 | * Get the damager 103 | * 104 | * @return the entity that damaged the NPC, or null 105 | */ 106 | @Nullable 107 | public Entity getDamager() { 108 | return damager; 109 | } 110 | 111 | @Override 112 | public boolean isCancelled() { 113 | return cancelled; 114 | } 115 | 116 | @Override 117 | public void setCancelled(boolean b) { 118 | cancelled = b; 119 | } 120 | 121 | @Override 122 | public HandlerList getHandlers() { 123 | return handlerList; 124 | } 125 | } 126 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCDeathEvent.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.event; 2 | 3 | import org.bukkit.event.Cancellable; 4 | import org.bukkit.event.HandlerList; 5 | import org.bukkit.event.entity.EntityDamageEvent; 6 | import org.inventivetalent.npclib.npc.NPCAbstract; 7 | 8 | /** 9 | * Event called when a NPC dies. 10 | * 11 | * Note: This event is called twice for living entities. Once for the LivingEntity with a damage source, once for the base entity without a source. 12 | */ 13 | public class NPCDeathEvent extends NPCEvent implements Cancellable { 14 | 15 | private static HandlerList handlerList = new HandlerList(); 16 | private boolean cancelled; 17 | private String damageSourceName; 18 | private EntityDamageEvent.DamageCause damageCause; 19 | 20 | public NPCDeathEvent(NPCAbstract npc, String damageSourceName, EntityDamageEvent.DamageCause damageCause) { 21 | super(npc); 22 | this.damageSourceName = damageSourceName; 23 | this.damageCause = damageCause; 24 | } 25 | 26 | public static HandlerList getHandlerList() { 27 | return handlerList; 28 | } 29 | 30 | /** 31 | * Whether this death event has a source. Always false for non-living entities 32 | * 33 | * @return true if the death has a source 34 | */ 35 | public boolean hasSource() { 36 | return damageSourceName != null; 37 | } 38 | 39 | /** 40 | * Get the damage source name 41 | * 42 | * @return the source name 43 | */ 44 | public String getDamageSourceName() { 45 | return damageSourceName; 46 | } 47 | 48 | /** 49 | * Get the damage cause 50 | * 51 | * @return the {@link org.bukkit.event.entity.EntityDamageEvent.DamageCause} 52 | */ 53 | public EntityDamageEvent.DamageCause getDamageCause() { 54 | return damageCause; 55 | } 56 | 57 | @Override 58 | public boolean isCancelled() { 59 | return cancelled; 60 | } 61 | 62 | @Override 63 | public void setCancelled(boolean b) { 64 | cancelled = b; 65 | } 66 | 67 | @Override 68 | public HandlerList getHandlers() { 69 | return handlerList; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCEvent.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.event; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.event.Event; 5 | import org.inventivetalent.npclib.NPCType; 6 | import org.inventivetalent.npclib.npc.NPCAbstract; 7 | 8 | /** 9 | * Abstract base class for NPC events 10 | */ 11 | public abstract class NPCEvent extends Event { 12 | 13 | private final NPCAbstract npc; 14 | 15 | public NPCEvent(NPCAbstract npc) { 16 | this.npc = npc; 17 | } 18 | 19 | /** 20 | * Get the involved NPC 21 | * 22 | * @return the NPC 23 | */ 24 | public NPCAbstract getNpc() { 25 | return npc; 26 | } 27 | 28 | /** 29 | * Get the NPC's type 30 | * 31 | * @return the {@link NPCType} 32 | */ 33 | public NPCType getNpcType() { 34 | return npc.getNpcType(); 35 | } 36 | 37 | /** 38 | * Get the NPC's entity type 39 | * 40 | * @return the {@link EntityType} 41 | */ 42 | public EntityType getEntityType() { 43 | return npc.getEntityType(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCInteractEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event; 30 | 31 | import org.bukkit.entity.Player; 32 | import org.bukkit.event.Cancellable; 33 | import org.bukkit.event.HandlerList; 34 | import org.inventivetalent.npclib.npc.NPCAbstract; 35 | 36 | public class NPCInteractEvent extends NPCEvent implements Cancellable { 37 | 38 | private static HandlerList handlerList = new HandlerList(); 39 | private int entityId; 40 | private int actionId; 41 | private Player player; 42 | private boolean cancelled; 43 | 44 | public NPCInteractEvent(NPCAbstract npc, int entityId, int actionId, Player player) { 45 | super(npc); 46 | this.entityId = entityId; 47 | this.actionId = actionId; 48 | this.player = player; 49 | } 50 | 51 | public static HandlerList getHandlerList() { 52 | return handlerList; 53 | } 54 | 55 | public int getEntityId() { 56 | return entityId; 57 | } 58 | 59 | public int getActionId() { 60 | return actionId; 61 | } 62 | 63 | public Player getPlayer() { 64 | return player; 65 | } 66 | 67 | @Override 68 | public boolean isCancelled() { 69 | return cancelled; 70 | } 71 | 72 | @Override 73 | public void setCancelled(boolean b) { 74 | cancelled = b; 75 | } 76 | 77 | @Override 78 | public HandlerList getHandlers() { 79 | return handlerList; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCSpawnEvent.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.event; 2 | 3 | import com.google.common.base.Preconditions; 4 | import org.bukkit.Location; 5 | import org.bukkit.event.HandlerList; 6 | import org.bukkit.event.entity.CreatureSpawnEvent; 7 | import org.inventivetalent.npclib.npc.NPCAbstract; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | /** 12 | * Event called when a new NPC is spawned 13 | */ 14 | public class NPCSpawnEvent extends NPCEvent { 15 | 16 | private static HandlerList handlerList = new HandlerList(); 17 | private CreatureSpawnEvent.SpawnReason spawnReason; 18 | 19 | public NPCSpawnEvent(NPCAbstract npc, CreatureSpawnEvent.SpawnReason spawnReason) { 20 | super(npc); 21 | this.spawnReason = spawnReason; 22 | } 23 | 24 | public static HandlerList getHandlerList() { 25 | return handlerList; 26 | } 27 | 28 | /** 29 | * Get the location where the NPC was spawned 30 | * 31 | * @return the spawn {@link Location} 32 | */ 33 | public Location getLocation() { 34 | return getNpc().getBukkitEntity().getLocation(); 35 | } 36 | 37 | /** 38 | * Get the spawn reason 39 | * 40 | * @return the {@link org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason} 41 | */ 42 | public CreatureSpawnEvent.SpawnReason getSpawnReason() { 43 | return spawnReason; 44 | } 45 | 46 | /** 47 | * Set the spawn reason 48 | * 49 | * @param spawnReason the new spawn reason 50 | */ 51 | public void setSpawnReason(@Nonnull CreatureSpawnEvent.SpawnReason spawnReason) { 52 | Preconditions.checkNotNull(spawnReason); 53 | this.spawnReason = spawnReason; 54 | } 55 | 56 | @Override 57 | public HandlerList getHandlers() { 58 | return handlerList; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/NPCVelocityEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event; 30 | 31 | import org.bukkit.event.Cancellable; 32 | import org.bukkit.event.HandlerList; 33 | import org.inventivetalent.npclib.npc.NPCAbstract; 34 | 35 | public class NPCVelocityEvent extends NPCEvent implements Cancellable { 36 | 37 | private boolean cancelled; 38 | private double x; 39 | private double y; 40 | private double z; 41 | 42 | public NPCVelocityEvent(NPCAbstract npc, double x, double y, double z) { 43 | super(npc); 44 | this.x = x; 45 | this.y = y; 46 | this.z = z; 47 | } 48 | 49 | public double getX() { 50 | return x; 51 | } 52 | 53 | public void setX(double x) { 54 | this.x = x; 55 | } 56 | 57 | public double getY() { 58 | return y; 59 | } 60 | 61 | public void setY(double y) { 62 | this.y = y; 63 | } 64 | 65 | public double getZ() { 66 | return z; 67 | } 68 | 69 | public void setZ(double z) { 70 | this.z = z; 71 | } 72 | 73 | @Override 74 | public boolean isCancelled() { 75 | return cancelled; 76 | } 77 | 78 | @Override 79 | public void setCancelled(boolean b) { 80 | cancelled = b; 81 | } 82 | 83 | private static HandlerList handlerList = new HandlerList(); 84 | 85 | @Override 86 | public HandlerList getHandlers() { 87 | return handlerList; 88 | } 89 | 90 | public static HandlerList getHandlerList() { 91 | return handlerList; 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/nbt/NBTReadEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event.nbt; 30 | 31 | import org.bukkit.event.HandlerList; 32 | import org.inventivetalent.nbt.CompoundTag; 33 | import org.inventivetalent.npclib.npc.NPCAbstract; 34 | 35 | public class NBTReadEvent extends NPCNBTEvent { 36 | 37 | private static HandlerList handlerList = new HandlerList(); 38 | 39 | public NBTReadEvent(NPCAbstract npc, Object nbtTagHandle, CompoundTag nbtTag) { 40 | super(npc, nbtTagHandle, nbtTag); 41 | } 42 | 43 | public static HandlerList getHandlerList() { 44 | return handlerList; 45 | } 46 | 47 | @Override 48 | public CompoundTag getNbtTag() { 49 | return (CompoundTag) super.getNbtTag(); 50 | } 51 | 52 | @Override 53 | public HandlerList getHandlers() { 54 | return handlerList; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/nbt/NBTWriteEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event.nbt; 30 | 31 | import org.bukkit.event.HandlerList; 32 | import org.inventivetalent.nbt.CompoundTag; 33 | import org.inventivetalent.npclib.npc.NPCAbstract; 34 | 35 | public class NBTWriteEvent extends NPCNBTEvent { 36 | 37 | private static HandlerList handlerList = new HandlerList(); 38 | 39 | public NBTWriteEvent(NPCAbstract npc, Object nbtTagHandle, CompoundTag nbtTag) { 40 | super(npc, nbtTagHandle, nbtTag); 41 | } 42 | 43 | public static HandlerList getHandlerList() { 44 | return handlerList; 45 | } 46 | 47 | @Override 48 | public CompoundTag getNbtTag() { 49 | return (CompoundTag) super.getNbtTag(); 50 | } 51 | 52 | @Override 53 | public HandlerList getHandlers() { 54 | return handlerList; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/nbt/NPCNBTEvent.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.event.nbt; 2 | 3 | import org.inventivetalent.nbt.NBTTag; 4 | import org.inventivetalent.npclib.event.NPCEvent; 5 | import org.inventivetalent.npclib.npc.NPCAbstract; 6 | 7 | public abstract class NPCNBTEvent extends NPCEvent { 8 | 9 | private final Object nbtTagHandle; 10 | private final NBTTag nbtTag; 11 | 12 | public NPCNBTEvent(NPCAbstract npc, Object nbtTagHandle, NBTTag nbtTag) { 13 | super(npc); 14 | this.nbtTagHandle = nbtTagHandle; 15 | this.nbtTag = nbtTag; 16 | } 17 | 18 | public Object getNbtTagHandle() { 19 | return nbtTagHandle; 20 | } 21 | 22 | public NBTTag getNbtTag() { 23 | return nbtTag; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/event/path/NPCPathFinishEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-2016 inventivetalent. All rights reserved. 3 | * 4 | * Redistribution and use in source and binary forms, with or without modification, are 5 | * permitted provided that the following conditions are met: 6 | * 7 | * 1. Redistributions of source code must retain the above copyright notice, this list of 8 | * conditions and the following disclaimer. 9 | * 10 | * 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | * of conditions and the following disclaimer in the documentation and/or other materials 12 | * provided with the distribution. 13 | * 14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ''AS IS'' AND ANY EXPRESS OR IMPLIED 15 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 16 | * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR 17 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 19 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 20 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 21 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 22 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | * 24 | * The views and conclusions contained in the software and documentation are those of the 25 | * authors and contributors and should not be interpreted as representing official policies, 26 | * either expressed or implied, of anybody else. 27 | */ 28 | 29 | package org.inventivetalent.npclib.event.path; 30 | 31 | import org.bukkit.event.HandlerList; 32 | import org.inventivetalent.npclib.event.NPCEvent; 33 | import org.inventivetalent.npclib.npc.NPCAbstract; 34 | 35 | public class NPCPathFinishEvent extends NPCEvent { 36 | 37 | public NPCPathFinishEvent(NPCAbstract npc) { 38 | super(npc); 39 | } 40 | 41 | private static HandlerList handlerList = new HandlerList(); 42 | 43 | @Override 44 | public HandlerList getHandlers() { 45 | return handlerList; 46 | } 47 | 48 | public static HandlerList getHandlerList() { 49 | return handlerList; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/NPCExperienceOrb.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.ExperienceOrb; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.EntityExperienceOrb; 7 | 8 | @NPC(id = 2, 9 | type = EntityType.EXPERIENCE_ORB, 10 | bukkit = ExperienceOrb.class, 11 | nms = "EntityExperienceOrb", 12 | entity = EntityExperienceOrb.class) 13 | public class NPCExperienceOrb extends NPCAbstract { 14 | public NPCExperienceOrb(EntityExperienceOrb npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/NPCItem.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Item; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.EntityItem; 7 | 8 | @NPC(id = 1, 9 | type = EntityType.DROPPED_ITEM, 10 | bukkit = Item.class, 11 | nms = "EntityItem", 12 | entity = EntityItem.class) 13 | public class NPCItem extends NPCAbstract { 14 | public NPCItem(EntityItem npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/NPCArmorStand.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living; 2 | 3 | import org.bukkit.entity.ArmorStand; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.EntityArmorStand; 7 | 8 | @NPC(id = 30, 9 | type = EntityType.ARMOR_STAND, 10 | bukkit = ArmorStand.class, 11 | nms = "EntityArmorStand", 12 | entity = EntityArmorStand.class) 13 | public class NPCArmorStand extends NPCLivingAbstract { 14 | public NPCArmorStand(EntityArmorStand npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/NPCLivingAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living; 2 | 3 | import com.google.common.base.Predicate; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.entity.LivingEntity; 6 | import org.bukkit.entity.Player; 7 | import org.bukkit.event.entity.EntityDamageEvent; 8 | import org.bukkit.inventory.ItemStack; 9 | import org.inventivetalent.npclib.ObjectContainer; 10 | import org.inventivetalent.npclib.Reflection; 11 | import org.inventivetalent.npclib.SuperSwitch; 12 | import org.inventivetalent.npclib.entity.living.NPCEntityLiving; 13 | import org.inventivetalent.npclib.equipment.EquipmentSlot; 14 | import org.inventivetalent.npclib.event.NPCDeathEvent; 15 | import org.inventivetalent.npclib.event.path.NPCPathFinishEvent; 16 | import org.inventivetalent.npclib.npc.NPCAbstract; 17 | import org.inventivetalent.npclib.path.AStarPathfinder; 18 | import org.inventivetalent.npclib.path.PathfinderAbstract; 19 | import org.inventivetalent.npclib.watcher.Watch; 20 | import org.inventivetalent.reflection.minecraft.Minecraft; 21 | import org.inventivetalent.reflection.resolver.FieldResolver; 22 | import org.inventivetalent.reflection.resolver.MethodResolver; 23 | import org.inventivetalent.reflection.resolver.ResolverQuery; 24 | import org.inventivetalent.vectors.d3.Vector3DDouble; 25 | 26 | import javax.annotation.Nullable; 27 | 28 | import java.lang.reflect.Constructor; 29 | 30 | public abstract class NPCLivingAbstract extends NPCAbstract { 31 | 32 | // The static code gets run once, saves resources. 33 | protected static FieldResolver entityLivingFieldResolver = new FieldResolver(Reflection.nmsClassResolver.resolveSilent("EntityLiving")); 34 | protected static MethodResolver entityLivingMethodResolver = new MethodResolver(Reflection.nmsClassResolver.resolveSilent("EntityLiving")); 35 | 36 | private PathfinderAbstract pathfinder; 37 | 38 | public NPCLivingAbstract(N npcEntity) { 39 | super(npcEntity); 40 | } 41 | 42 | @Watch("void die(DamageSource)") 43 | public void onDie(ObjectContainer damageSource, SuperSwitch superSwitch) { 44 | String damageName = Reflection.getDamageSourceName(damageSource.value); 45 | EntityDamageEvent.DamageCause cause = Reflection.damageSourceToCause(damageName); 46 | NPCDeathEvent event = new NPCDeathEvent(this, damageName, cause); 47 | Bukkit.getPluginManager().callEvent(event); 48 | if (event.isCancelled()) { 49 | superSwitch.setCancelled(true); 50 | } 51 | } 52 | 53 | @Watch("void g(float,float)") 54 | public void onHeadingMove(ObjectContainer strafe, ObjectContainer forward, SuperSwitch superSwitch) { 55 | // System.out.println("onHeadingMove -> NPCLivingAbstract"); 56 | //TODO: NPCMoveEvent... 57 | } 58 | 59 | /** 60 | * Moves the entity forward (on the current heading) 61 | * 62 | * @param forward forward movement amount 63 | * @param strafe strafe movement amount 64 | */ 65 | public void moveForward(float forward, float strafe) { 66 | invokeEntityLivingMethod("g", new Class[] { 67 | float.class, 68 | float.class }, new Object[] { 69 | strafe, 70 | forward }); 71 | } 72 | 73 | public void setYaw(float yaw) { 74 | yaw = clampYaw(yaw); 75 | setBodyYaw(yaw); 76 | setHeadYaw(yaw); 77 | } 78 | 79 | public void setBodyYaw(float yaw) { 80 | getNpcEntity().setYaw(yaw); 81 | 82 | if(Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) { 83 | // The method is relatively consistent between versions. 84 | invokeEntityLivingMethod("i", new Class[] {float.class}, new Object[] {yaw}); 85 | } else { 86 | // 1.8. The field is consistent between all 1.8 versions, however on 1.8.0 it is shared with the head value. 87 | entityLivingFieldResolver.resolveWrapper("aI").set(getNpcEntity(), yaw); 88 | } 89 | } 90 | 91 | public void setHeadYaw(float yaw) { 92 | // Find it below getHeadRotation() in NMS class EntityLiving if it changes. 93 | if(Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) { 94 | // The method is relatively consistent between versions. 95 | invokeEntityLivingMethod("h", new Class[] {float.class}, new Object[] {yaw}); 96 | } else { 97 | // 1.8 98 | invokeEntityLivingMethod("f", new Class[] {float.class}, new Object[] {yaw}); 99 | } 100 | } 101 | 102 | public void setPitch(float pitch) { 103 | getNpcEntity().setPitch(pitch); 104 | } 105 | 106 | protected float clampYaw(float yaw) { 107 | while (yaw < -180.0F) { 108 | yaw += 360.0F; 109 | } 110 | 111 | while (yaw >= 180.0F) { 112 | yaw -= 360.0F; 113 | } 114 | 115 | return yaw; 116 | } 117 | 118 | public void lookAt(Vector3DDouble vector) { 119 | double dx = vector.getX() - getBukkitEntity().getEyeLocation().getX(); 120 | double dy = vector.getY() - getBukkitEntity().getEyeLocation().getY(); 121 | double dz = vector.getZ() - getBukkitEntity().getEyeLocation().getZ(); 122 | double xzd = Math.sqrt(dx * dx + dz * dz); 123 | double yd = Math.sqrt(xzd * xzd + dy * dy); 124 | 125 | double yaw = Math.toDegrees(Math.atan2(dz, dx)) - 90.0D; 126 | double pitch = -Math.toDegrees(Math.atan2(dy, yd)); 127 | 128 | setYaw((float) yaw); 129 | setPitch((float) pitch); 130 | } 131 | 132 | @Override 133 | public void tickAI() { 134 | super.tickAI(); 135 | if (this.pathfinder != null) { 136 | this.pathfinder.tick(); 137 | if (this.pathfinder.isFinished()) { 138 | this.pathfinder = null; 139 | 140 | Bukkit.getPluginManager().callEvent(new NPCPathFinishEvent(this)); 141 | } 142 | } 143 | } 144 | 145 | public void pathfindTo(Vector3DDouble target, double speed) { 146 | this.pathfinder = new AStarPathfinder(target, speed, 128); 147 | //noinspection unchecked 148 | this.pathfinder.setNpc(this); 149 | this.pathfinder.find(); 150 | } 151 | 152 | public void moveWithHeading(float strafeMotion, float forwardMotion) { 153 | try { 154 | entityLivingMethodResolver.resolve(new ResolverQuery("g", float.class, float.class)).invoke(getNpcEntity(), strafeMotion, forwardMotion); 155 | } catch (ReflectiveOperationException e) { 156 | throw new RuntimeException(e); 157 | } 158 | } 159 | 160 | public void refreshEquipment() { 161 | if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) { 162 | refreshSlot(EquipmentSlot.MAIN_HAND, getBukkitEntity().getEquipment().getItemInMainHand()); 163 | refreshSlot(EquipmentSlot.OFF_HAND, getBukkitEntity().getEquipment().getItemInOffHand()); 164 | } else { 165 | refreshSlot(EquipmentSlot.HAND, getBukkitEntity().getEquipment().getItemInHand()); 166 | } 167 | refreshSlot(EquipmentSlot.HEAD, getBukkitEntity().getEquipment().getHelmet()); 168 | refreshSlot(EquipmentSlot.CHEST, getBukkitEntity().getEquipment().getChestplate()); 169 | refreshSlot(EquipmentSlot.LEGS, getBukkitEntity().getEquipment().getLeggings()); 170 | refreshSlot(EquipmentSlot.FEET, getBukkitEntity().getEquipment().getBoots()); 171 | } 172 | 173 | protected void refreshSlot(EquipmentSlot slot, ItemStack itemStack) { 174 | try { 175 | Object nmsItemStack = Reflection.obcClassResolver.resolve("inventory.CraftItemStack").getMethod("asNMSCopy", ItemStack.class).invoke(null, itemStack); 176 | Object nmsSlot = slot.toNMS(); 177 | if (nmsSlot == null) { return; } 178 | 179 | Class packetClass = Reflection.nmsClassResolver.resolve("PacketPlayOutEntityEquipment"); 180 | Class itemClass = Reflection.nmsClassResolver.resolve("ItemStack"); 181 | Constructor constructor; 182 | if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_9_R1)) { 183 | constructor = packetClass.getConstructor(int.class, Reflection.nmsClassResolver.resolve("EnumItemSlot"), itemClass); 184 | } else if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_8_R1)) { 185 | constructor = packetClass.getConstructor(int.class, int.class, itemClass); 186 | } else { 187 | return; 188 | } 189 | final Object packet = constructor.newInstance(getBukkitEntity().getEntityId(), nmsSlot, nmsItemStack); 190 | updateNearby(32, new Predicate() { 191 | @Override 192 | public boolean apply(@Nullable Player player) { 193 | sendPacket(player, packet); 194 | return false; 195 | } 196 | }); 197 | } catch (Exception e) { 198 | throw new RuntimeException(e); 199 | } 200 | } 201 | 202 | public Object getEntityLivingField(String field) { 203 | return entityLivingFieldResolver.resolveWrapper(field).get(getNpcEntity()); 204 | } 205 | 206 | public void setEntityLivingField(String field, Object value) { 207 | entityLivingFieldResolver.resolveWrapper(field).set(getNpcEntity(), value); 208 | } 209 | 210 | public Object invokeEntityLivingMethod(String method, Class[] types, Object[] args) { 211 | return entityLivingMethodResolver.resolveWrapper(new ResolverQuery(method, types)).invoke(getNpcEntity(), args); 212 | } 213 | 214 | public Object invokeEntityLivingMethod(String method, Object... args) { 215 | return entityLivingMethodResolver.resolveWrapper(method).invoke(getNpcEntity(), args); 216 | } 217 | 218 | } 219 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/human/NPCHumanAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.human; 2 | 3 | import org.bukkit.Location; 4 | import org.bukkit.Material; 5 | import org.bukkit.entity.HumanEntity; 6 | import org.bukkit.entity.Player; 7 | import org.inventivetalent.nbt.annotation.NBT; 8 | import org.inventivetalent.npclib.ClassBuilder; 9 | import org.inventivetalent.npclib.Reflection; 10 | import org.inventivetalent.npclib.entity.living.human.NPCEntityHuman; 11 | import org.inventivetalent.npclib.npc.living.NPCLivingAbstract; 12 | import org.inventivetalent.npclib.skin.ISkinnableEntity; 13 | import org.inventivetalent.npclib.skin.SkinLayer; 14 | import org.inventivetalent.reflection.minecraft.DataWatcher; 15 | 16 | public abstract class NPCHumanAbstract extends NPCLivingAbstract implements ISkinnableEntity { 17 | 18 | @NBT(value = { 19 | "npclib.options", 20 | "human", 21 | "laying" }, 22 | read = false) 23 | private boolean laying; 24 | 25 | public NPCHumanAbstract(N npcEntity) { 26 | super(npcEntity); 27 | } 28 | 29 | @Override 30 | public void setSkinLayers(SkinLayer... visibleLayers) { 31 | setSkinLayerFlag(SkinLayer.getValue(visibleLayers)); 32 | } 33 | 34 | @NBT({ 35 | "npclib.options", 36 | "human", 37 | "skinLayers" }) 38 | protected void setSkinLayerFlag(@NBT int flag) { 39 | try { 40 | DataWatcher.setValue(Reflection.getDataWatcher(getBukkitEntity()), 10, DataWatcher.V1_9.ValueType.ENTITY_HUMAN_SKIN_LAYERS, (byte) flag); 41 | } catch (Exception e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | 46 | @NBT({ 47 | "npclib.options", 48 | "human", 49 | "skinLayers" }) 50 | protected int getSkinLayerFlag() { 51 | try { 52 | return (byte) DataWatcher.getValue(Reflection.getDataWatcher(getBukkitEntity()), 10, DataWatcher.V1_9.ValueType.ENTITY_HUMAN_SKIN_LAYERS); 53 | } catch (Exception e) { 54 | throw new RuntimeException(e); 55 | } 56 | } 57 | 58 | @NBT(value = { 59 | "npclib.options", 60 | "human", 61 | "laying" }) 62 | public void setLaying(@NBT boolean laying) { 63 | this.laying = laying; 64 | updateNearby(); 65 | } 66 | 67 | public boolean isLaying() { 68 | return laying; 69 | } 70 | 71 | @Override 72 | public void updateToPlayer(Player player) { 73 | if (getBukkitEntity().isDead()) { return; } 74 | super.updateToPlayer(player); 75 | if (isLaying()) { 76 | Location bedLocation = getBukkitEntity().getLocation().clone(); 77 | bedLocation.setY(0); 78 | // Create a fake bed block 79 | player.sendBlockChange(bedLocation, Material.BED_BLOCK, (byte) 0); 80 | 81 | sendPacket(player, ClassBuilder.buildPacketPlayOutBed(getBukkitEntity().getEntityId(), bedLocation.getBlockX(), bedLocation.getBlockY(), bedLocation.getBlockZ())); 82 | } 83 | } 84 | 85 | @Override 86 | public void respawnTo(Player player) { 87 | if (getBukkitEntity().isDead()) { return; } 88 | super.respawnTo(player); 89 | try { 90 | sendPacket(player, Reflection.nmsClassResolver.resolve("PacketPlayOutEntityDestroy").getConstructor(int[].class).newInstance(new int[] { getBukkitEntity().getEntityId() })); 91 | sendPacket(player, Reflection.nmsClassResolver.resolve("PacketPlayOutNamedEntitySpawn").getConstructor(Reflection.nmsClassResolver.resolve("EntityHuman")).newInstance(getNpcEntity())); 92 | } catch (ReflectiveOperationException e) { 93 | throw new RuntimeException(e); 94 | } 95 | } 96 | 97 | } 98 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/NPCEnderDragon.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient; 2 | 3 | import org.bukkit.entity.EnderDragon; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.EntityEnderDragon; 7 | 8 | @NPC(id = 63, 9 | type = EntityType.ENDER_DRAGON, 10 | bukkit = EnderDragon.class, 11 | nms = "EntityEnderDragon", 12 | entity = EntityEnderDragon.class) 13 | public class NPCEnderDragon extends NPCInsentientAbstract { 14 | public NPCEnderDragon(EntityEnderDragon npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/NPCInsentientAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient; 2 | 3 | import org.bukkit.entity.LivingEntity; 4 | import org.inventivetalent.npclib.Reflection; 5 | import org.inventivetalent.npclib.entity.living.insentient.NPCEntityInsentient; 6 | import org.inventivetalent.npclib.npc.living.NPCLivingAbstract; 7 | import org.inventivetalent.reflection.util.AccessUtil; 8 | 9 | import java.util.Collection; 10 | 11 | public abstract class NPCInsentientAbstract extends NPCLivingAbstract { 12 | 13 | public NPCInsentientAbstract(N npcEntity) { 14 | super(npcEntity); 15 | } 16 | 17 | @Override 18 | protected void postInit(String pluginName, double x, double y, double z, float yaw, float pitch) throws Exception { 19 | clearGoalSelector(); 20 | clearTargetSelector(); 21 | 22 | super.postInit(pluginName, x, y, z, yaw, pitch); 23 | } 24 | 25 | public Object getGoalSelector() throws ReflectiveOperationException { 26 | return AccessUtil.setAccessible(Reflection.nmsClassResolver.resolve("EntityInsentient").getDeclaredField("goalSelector")).get(getNpcEntity()); 27 | } 28 | 29 | public Collection getGoalListB() throws ReflectiveOperationException { 30 | return (Collection) AccessUtil.setAccessible(Reflection.nmsClassResolver.resolve("PathfinderGoalSelector").getDeclaredField("b")).get(getGoalSelector()); 31 | } 32 | 33 | public Collection getGoalListC() throws ReflectiveOperationException { 34 | return (Collection) AccessUtil.setAccessible(Reflection.nmsClassResolver.resolve("PathfinderGoalSelector").getDeclaredField("c")).get(getGoalSelector()); 35 | } 36 | 37 | public void clearGoalSelector() { 38 | try { 39 | getGoalListB().clear(); 40 | getGoalListC().clear(); 41 | } catch (ReflectiveOperationException e) { 42 | throw new RuntimeException(e); 43 | } 44 | } 45 | 46 | public Object getTargetSelector() throws ReflectiveOperationException { 47 | return AccessUtil.setAccessible(Reflection.nmsClassResolver.resolve("EntityInsentient").getDeclaredField("targetSelector")).get(getNpcEntity()); 48 | } 49 | 50 | public Collection getTargetListB() throws ReflectiveOperationException { 51 | return (Collection) AccessUtil.setAccessible(Reflection.nmsClassResolver.resolve("PathfinderGoalSelector").getDeclaredField("b")).get(getTargetSelector()); 52 | } 53 | 54 | public Collection getTargetListC() throws ReflectiveOperationException { 55 | return (Collection) AccessUtil.setAccessible(Reflection.nmsClassResolver.resolve("PathfinderGoalSelector").getDeclaredField("c")).get(getTargetSelector()); 56 | } 57 | 58 | public void clearTargetSelector() { 59 | try { 60 | getTargetListB().clear(); 61 | getTargetListC().clear(); 62 | } catch (ReflectiveOperationException e) { 63 | throw new RuntimeException(e); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/NPCPigZombie.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.PigZombie; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.EntityPigZombie; 7 | import org.inventivetalent.npclib.entity.living.insentient.EntityZombie; 8 | 9 | @NPC(id = 57, 10 | type = EntityType.PIG_ZOMBIE, 11 | bukkit = PigZombie.class, 12 | nms = "EntityPigZombie", 13 | entity = EntityPigZombie.class) 14 | public class NPCPigZombie extends NPCZombie { 15 | public NPCPigZombie(EntityZombie npcEntity) { 16 | super(npcEntity); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/NPCSlime.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Slime; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.EntitySlime; 7 | 8 | @NPC(id = 55, 9 | type = EntityType.SLIME, 10 | bukkit = Slime.class, 11 | nms = "EntitySlime", 12 | entity = EntitySlime.class) 13 | public class NPCSlime extends NPCInsentientAbstract { 14 | public NPCSlime(EntitySlime npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/NPCZombie.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Zombie; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.EntityZombie; 7 | 8 | @NPC(id = 54, 9 | type = EntityType.ZOMBIE, 10 | bukkit = Zombie.class, 11 | nms = "EntityZombie", 12 | entity = EntityZombie.class) 13 | public class NPCZombie extends NPCInsentientAbstract { 14 | 15 | public NPCZombie(EntityZombie npcEntity) { 16 | super(npcEntity); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/NPCCreatureAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature; 2 | 3 | import org.bukkit.entity.Creature; 4 | import org.inventivetalent.npclib.entity.living.insentient.creature.NPCEntityCreature; 5 | import org.inventivetalent.npclib.npc.living.insentient.NPCInsentientAbstract; 6 | 7 | public abstract class NPCCreatureAbstract extends NPCInsentientAbstract { 8 | public NPCCreatureAbstract(T npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/NPCAgeableAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable; 2 | 3 | import org.bukkit.entity.Ageable; 4 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.NPCEntityAgeable; 5 | import org.inventivetalent.npclib.npc.living.insentient.creature.NPCCreatureAbstract; 6 | 7 | public abstract class NPCAgeableAbstract extends NPCCreatureAbstract { 8 | public NPCAgeableAbstract(N npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/NPCVillager.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Villager; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.EntityVillager; 7 | 8 | @NPC(id = 120, 9 | type = EntityType.VILLAGER, 10 | bukkit = Villager.class, 11 | nms = "EntityVillager", 12 | entity = EntityVillager.class) 13 | public class NPCVillager extends NPCAgeableAbstract { 14 | public NPCVillager(EntityVillager npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCAnimalAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.Animals; 4 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.NPCEntityAnimal; 5 | import org.inventivetalent.npclib.npc.living.insentient.creature.ageable.NPCAgeableAbstract; 6 | 7 | public class NPCAnimalAbstract extends NPCAgeableAbstract { 8 | public NPCAnimalAbstract(N npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCChicken.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.Chicken; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityChicken; 7 | 8 | @NPC(id = 93, 9 | type = EntityType.CHICKEN, 10 | bukkit = Chicken.class, 11 | nms = "EntityChicken", 12 | entity = EntityChicken.class) 13 | public class NPCChicken extends NPCAnimalAbstract { 14 | public NPCChicken(EntityChicken npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCCow.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.Cow; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityCow; 7 | 8 | @NPC(id = 92, 9 | type = EntityType.COW, 10 | bukkit = Cow.class, 11 | nms = "EntityCow", 12 | entity = EntityCow.class) 13 | public class NPCCow extends NPCAnimalAbstract { 14 | public NPCCow(EntityCow npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCHorse.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Horse; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityHorse; 7 | 8 | @NPC(id = 100, 9 | type = EntityType.HORSE, 10 | bukkit = Horse.class, 11 | nms = "EntityHorse", 12 | entity = EntityHorse.class) 13 | public class NPCHorse extends NPCAnimalAbstract { 14 | public NPCHorse(EntityHorse npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCLlama.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Llama; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityLlama; 7 | 8 | @NPC(id = 103, 9 | type = EntityType.LLAMA, 10 | bukkit = Llama.class, 11 | nms = "EntityLlama", 12 | entity = EntityLlama.class) 13 | public class NPCLlama extends NPCAnimalAbstract { 14 | public NPCLlama(EntityLlama npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCMushroomCow.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.MushroomCow; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityCow; 7 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityMushroomCow; 8 | 9 | @NPC(id = 96, 10 | type = EntityType.MUSHROOM_COW, 11 | bukkit = MushroomCow.class, 12 | nms = "EntityMushroomCow", 13 | entity = EntityMushroomCow.class) 14 | public class NPCMushroomCow extends NPCCow { 15 | public NPCMushroomCow(EntityCow npcEntity) { 16 | super(npcEntity); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCPig.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Pig; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityPig; 7 | 8 | @NPC(id = 90, 9 | type = EntityType.PIG, 10 | bukkit = Pig.class, 11 | nms = "EntityPig", 12 | entity = EntityPig.class) 13 | public class NPCPig extends NPCAnimalAbstract { 14 | public NPCPig(EntityPig npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCPolarBear.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.PolarBear; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityPolarBear; 7 | 8 | @NPC(id = 102, 9 | type = EntityType.POLAR_BEAR, 10 | bukkit = PolarBear.class, 11 | nms = "EntityPolarBear", 12 | entity = EntityPolarBear.class) 13 | public class NPCPolarBear extends NPCAnimalAbstract { 14 | public NPCPolarBear(EntityPolarBear npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCRabbit.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Rabbit; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntityRabbit; 7 | 8 | @NPC(id = 101, 9 | type = EntityType.RABBIT, 10 | bukkit = Rabbit.class, 11 | nms = "EntityRabbit", 12 | entity = EntityRabbit.class) 13 | public class NPCRabbit extends NPCAnimalAbstract { 14 | public NPCRabbit(EntityRabbit npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/NPCSheep.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Sheep; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.EntitySheep; 7 | 8 | @NPC(id = 91, 9 | type = EntityType.SHEEP, 10 | bukkit = Sheep.class, 11 | nms = "EntitySheep", 12 | entity = EntitySheep.class) 13 | public class NPCSheep extends NPCAnimalAbstract { 14 | public NPCSheep(EntitySheep npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/tameable/NPCOcelot.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.tameable; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Ocelot; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.tameable.EntityOcelot; 7 | 8 | @NPC(id = 98, 9 | type = EntityType.OCELOT, 10 | bukkit = Ocelot.class, 11 | nms = "EntityOcelot", 12 | entity = EntityOcelot.class) 13 | public class NPCOcelot extends NPCTameableAbstract { 14 | public NPCOcelot(EntityOcelot npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/tameable/NPCTameableAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.tameable; 2 | 3 | import org.bukkit.entity.Animals; 4 | import org.bukkit.entity.Tameable; 5 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.tameable.NPCEntityTameable; 6 | import org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.NPCAnimalAbstract; 7 | 8 | // *sigh* why doesn't Tameable extend Animals?! 9 | public abstract class NPCTameableAbstract extends NPCAnimalAbstract { 10 | public NPCTameableAbstract(N npcEntity) { 11 | super(npcEntity); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/ageable/animal/tameable/NPCWolf.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.ageable.animal.tameable; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Wolf; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.ageable.animal.tameable.EntityWolf; 7 | 8 | @NPC(id = 95, 9 | type = EntityType.WOLF, 10 | bukkit = Wolf.class, 11 | nms = "EntityWolf", 12 | entity = EntityWolf.class) 13 | public class NPCWolf extends NPCTameableAbstract { 14 | public NPCWolf(EntityWolf npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/golem/NPCGolemAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.golem; 2 | 3 | import org.bukkit.entity.Golem; 4 | import org.inventivetalent.npclib.entity.living.insentient.creature.golem.NPCEntityGolem; 5 | import org.inventivetalent.npclib.npc.living.insentient.creature.NPCCreatureAbstract; 6 | 7 | public abstract class NPCGolemAbstract extends NPCCreatureAbstract { 8 | public NPCGolemAbstract(N npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/golem/NPCIronGolem.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.golem; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.IronGolem; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.golem.EntityIronGolem; 7 | 8 | @NPC(id = 99, 9 | type = EntityType.IRON_GOLEM, 10 | bukkit = IronGolem.class, 11 | nms = "EntityIronGolem", 12 | entity = EntityIronGolem.class) 13 | public class NPCIronGolem extends NPCGolemAbstract { 14 | public NPCIronGolem(EntityIronGolem npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/golem/NPCShulker.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.golem; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Shulker; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.golem.EntityShulker; 7 | 8 | @NPC(id = 69, 9 | type = EntityType.SHULKER, 10 | bukkit = Shulker.class, 11 | nms = "EntityShulker", 12 | entity = EntityShulker.class) 13 | public class NPCShulker extends NPCGolemAbstract { 14 | public NPCShulker(EntityShulker npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/golem/NPCSnowman.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.golem; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Snowman; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.golem.EntitySnowman; 7 | 8 | @NPC(id = 97, 9 | type = EntityType.SNOWMAN, 10 | bukkit = Snowman.class, 11 | nms = "EntitySnowman", 12 | entity = EntitySnowman.class) 13 | public class NPCSnowman extends NPCGolemAbstract { 14 | public NPCSnowman(EntitySnowman npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCCaveSpider.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.CaveSpider; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityCaveSpider; 7 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntitySpider; 8 | 9 | @NPC(id = 59, 10 | type = EntityType.CAVE_SPIDER, 11 | bukkit = CaveSpider.class, 12 | nms = "EntityCaveSpider", 13 | entity = EntityCaveSpider.class) 14 | public class NPCCaveSpider extends NPCSpider { 15 | public NPCCaveSpider(EntitySpider npcEntity) { 16 | super(npcEntity); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCCreeper.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.Creeper; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityCreeper; 7 | 8 | @NPC(id = 50, 9 | type = EntityType.CREEPER, 10 | bukkit = Creeper.class, 11 | nms = "EntityCreeper", 12 | entity = EntityCreeper.class) 13 | public class NPCCreeper extends NPCMonsterAbstract { 14 | public NPCCreeper(EntityCreeper npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCEnderman.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.Enderman; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityEnderman; 7 | 8 | @NPC(id = 58, 9 | type = EntityType.ENDERMAN, 10 | bukkit = Enderman.class, 11 | nms = "EntityEnderman", 12 | entity = EntityEnderman.class) 13 | public class NPCEnderman extends NPCMonsterAbstract { 14 | public NPCEnderman(EntityEnderman npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCEndermite.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.Endermite; 4 | import org.bukkit.entity.EntityType; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityEndermite; 7 | 8 | @NPC(id = 67, 9 | type = EntityType.ENDERMITE, 10 | bukkit = Endermite.class, 11 | nms = "EntityEndermite", 12 | entity = EntityEndermite.class) 13 | public class NPCEndermite extends NPCMonsterAbstract { 14 | public NPCEndermite(EntityEndermite npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCGiant.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Giant; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityGiant; 7 | 8 | @NPC(id = 53, 9 | type = EntityType.GIANT, 10 | bukkit = Giant.class, 11 | nms = "EntityGiantZombie", 12 | entity = EntityGiant.class) 13 | public class NPCGiant extends NPCMonsterAbstract { 14 | public NPCGiant(EntityGiant npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCGuardian.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Guardian; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityGuardian; 7 | 8 | @NPC(id = 68, 9 | type = EntityType.GUARDIAN, 10 | bukkit = Guardian.class, 11 | nms = "EntityGuardian", 12 | entity = EntityGuardian.class) 13 | public class NPCGuardian extends NPCMonsterAbstract { 14 | public NPCGuardian(EntityGuardian npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCHusk.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Husk; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.EntityZombie; 7 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityHusk; 8 | import org.inventivetalent.npclib.npc.living.insentient.NPCZombie; 9 | 10 | @NPC(id = 23, 11 | type = EntityType.HUSK, 12 | bukkit = Husk.class, 13 | nms = "EntityZombieHusk", 14 | entity = EntityHusk.class) 15 | public class NPCHusk extends NPCZombie { 16 | public NPCHusk(EntityZombie npcEntity) { 17 | super(npcEntity); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCMonsterAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.Monster; 4 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.NPCEntityMonster; 5 | import org.inventivetalent.npclib.npc.living.insentient.NPCInsentientAbstract; 6 | 7 | public abstract class NPCMonsterAbstract extends NPCInsentientAbstract { 8 | public NPCMonsterAbstract(N npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCSkeleton.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Skeleton; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntitySkeleton; 7 | 8 | @NPC(id = 51, 9 | type = EntityType.SKELETON, 10 | bukkit = Skeleton.class, 11 | nms = "EntitySkeleton", 12 | entity = EntitySkeleton.class) 13 | public class NPCSkeleton extends NPCMonsterAbstract { 14 | public NPCSkeleton(EntitySkeleton npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCSpider.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Spider; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntitySpider; 7 | 8 | @NPC(id = 52, 9 | type = EntityType.SPIDER, 10 | bukkit = Spider.class, 11 | nms = "EntitySpider", 12 | entity = EntitySpider.class) 13 | public class NPCSpider extends NPCMonsterAbstract { 14 | public NPCSpider(EntitySpider npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCWitch.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Witch; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityWitch; 7 | 8 | @NPC(id = 66, 9 | type = EntityType.WITCH, 10 | bukkit = Witch.class, 11 | nms = "EntityWitch", 12 | entity = EntityWitch.class) 13 | public class NPCWitch extends NPCMonsterAbstract { 14 | public NPCWitch(EntityWitch npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/creature/monster/NPCWither.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.creature.monster; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Wither; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.creature.monster.EntityWither; 7 | 8 | @NPC(id = 64, 9 | type = EntityType.WITHER, 10 | bukkit = Wither.class, 11 | nms = "EntityWither", 12 | entity = EntityWither.class) 13 | public class NPCWither extends NPCMonsterAbstract { 14 | public NPCWither(EntityWither npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/flying/NPCFlyingAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.flying; 2 | 3 | import org.bukkit.entity.Flying; 4 | import org.inventivetalent.npclib.entity.living.insentient.flying.NPCEntityFlying; 5 | import org.inventivetalent.npclib.npc.living.insentient.NPCInsentientAbstract; 6 | 7 | public abstract class NPCFlyingAbstract extends NPCInsentientAbstract { 8 | public NPCFlyingAbstract(N npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/flying/NPCGhast.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.flying; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Ghast; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.flying.EntityGhast; 7 | 8 | @NPC(id = 56, 9 | type = EntityType.GHAST, 10 | bukkit = Ghast.class, 11 | nms = "EntityGhast", 12 | entity = EntityGhast.class) 13 | public class NPCGhast extends NPCFlyingAbstract { 14 | public NPCGhast(EntityGhast npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/water/NPCSquid.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.water; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.bukkit.entity.Squid; 5 | import org.inventivetalent.npclib.annotation.NPC; 6 | import org.inventivetalent.npclib.entity.living.insentient.water.EntitySquid; 7 | 8 | @NPC(id = 94, 9 | type = EntityType.SQUID, 10 | bukkit = Squid.class, 11 | nms = "EntitySquid", 12 | entity = EntitySquid.class) 13 | public class NPCSquid extends NPCWaterAnimalAbstract { 14 | public NPCSquid(EntitySquid npcEntity) { 15 | super(npcEntity); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/npc/living/insentient/water/NPCWaterAnimalAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.npc.living.insentient.water; 2 | 3 | import org.bukkit.entity.WaterMob; 4 | import org.inventivetalent.npclib.entity.living.insentient.water.NPCEntityWaterAnimal; 5 | import org.inventivetalent.npclib.npc.living.insentient.NPCInsentientAbstract; 6 | 7 | public abstract class NPCWaterAnimalAbstract extends NPCInsentientAbstract { 8 | public NPCWaterAnimalAbstract(N npcEntity) { 9 | super(npcEntity); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/path/AStarPathfinder.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.path; 2 | 3 | import org.inventivetalent.npclib.npc.NPCAbstract; 4 | import org.inventivetalent.vectors.d3.Vector3DDouble; 5 | import org.inventivetalent.vectors.d3.Vector3DInt; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | public class AStarPathfinder> extends PathfinderAbstract { 11 | 12 | private final Vector3DInt intTarget; 13 | private final int maxIterations; 14 | 15 | private List currentPath = new ArrayList<>(); 16 | private int currentPathIndex = 0; 17 | 18 | public AStarPathfinder(Vector3DDouble target, double speed, int maxIterations) { 19 | super(target, speed); 20 | this.intTarget = new Vector3DInt(target); 21 | this.maxIterations = maxIterations; 22 | } 23 | 24 | @Override 25 | public void tick() { 26 | if (this.finished) { return; } 27 | super.tick(); 28 | 29 | // if (currentPathIndex < currentPath.size()) { 30 | // PathPoint currentPoint = currentPath.get(currentPathIndex); 31 | // Vector3DDouble doublePoint = new Vector3DDouble(currentPoint); 32 | // ((EntityPlayer) getNpc().getNpcEntity()).g(0, 0.9f); 33 | // ((NPCLivingAbstract) getNpc()).lookAt(new Vector3DDouble(currentPoint.getX(), ((LivingEntity) getNpc().getBukkitEntity()).getEyeLocation().getY(), currentPoint.getZ())); 34 | // // getNpc().getNpcEntity().move(currentPoint.getX(), currentPoint.getY(), currentPoint.getZ()); 35 | // System.out.println(doublePoint.distanceSquared(getNpcVector())); 36 | // if (doublePoint.distanceSquared(getNpcVector()) < targetThresholdSquared) { 37 | // currentPathIndex++; 38 | // } 39 | // } 40 | } 41 | 42 | @Override 43 | protected NMSPathEntity findPath() { 44 | List list = calculatePoints(); 45 | // Object[] pointHandles = new Object[list.size()]; 46 | // for (int i = 0; i < list.size(); i++) { 47 | // pointHandles[i] = new NMSPathPoint(list.get(i)).getHandle(); 48 | // } 49 | try { 50 | // System.out.println(pointHandles); 51 | // System.out.println(Arrays.toString(pointHandles)); 52 | // System.out.println(pointHandles.getClass()); 53 | return new NMSPathEntity(list); 54 | } catch (ReflectiveOperationException e) { 55 | throw new RuntimeException(e); 56 | } 57 | } 58 | 59 | List calculatePoints() { 60 | int iterations = 0; 61 | List pathPoints = new ArrayList<>(); 62 | 63 | PathPoint currentPoint = new PathPoint(getIntNpcVector()); 64 | PathPoint closestPoint = currentPoint; 65 | // double closestDistance = currentPoint.distanceSquared(intTarget)*2; 66 | while (true) { 67 | List neighbours = closestPoint.getNeighbours(getNpcWorld()); 68 | if (neighbours.isEmpty()) { 69 | // Can't go any further 70 | return pathPoints; 71 | } 72 | 73 | double closestDistance = closestPoint.distanceSquared(intTarget) * 2; 74 | PathPoint closestNeighbour = closestPoint; 75 | for (PathPoint neighbour : neighbours) { 76 | double distance = neighbour.distanceSquared(intTarget); 77 | if (distance < closestDistance) { 78 | closestDistance = distance; 79 | closestNeighbour = neighbour; 80 | } 81 | } 82 | closestPoint = closestNeighbour; 83 | pathPoints.add(new NMSPathPoint(closestNeighbour)); 84 | 85 | // if (closestPoint.distanceSquared(intTarget) < targetThresholdSquared) { 86 | // // We're close enough 87 | // return pathPoints; 88 | // } 89 | 90 | if (this.maxIterations >= 0 && iterations++ >= this.maxIterations) { 91 | // It's taking too long to find a path 92 | return pathPoints; 93 | } 94 | } 95 | } 96 | 97 | Vector3DInt getIntNpcVector() { 98 | return new Vector3DInt(getNpcVector()); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/path/NMSPathEntity.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.path; 2 | 3 | import com.google.common.collect.Iterables; 4 | import com.google.common.collect.ObjectArrays; 5 | import org.inventivetalent.npclib.Reflection; 6 | import org.inventivetalent.reflection.resolver.ConstructorResolver; 7 | import org.inventivetalent.reflection.resolver.FieldResolver; 8 | import org.inventivetalent.reflection.resolver.MethodResolver; 9 | import org.inventivetalent.vectors.d3.Vector3DDouble; 10 | 11 | public class NMSPathEntity { 12 | 13 | static final Class nmsPathEntity = Reflection.nmsClassResolver.resolveSilent("PathEntity"); 14 | static final Class nmsVector = Reflection.nmsClassResolver.resolveSilent("Vec3D"); 15 | static final Class nmsEntity = Reflection.nmsClassResolver.resolveSilent("Entity"); 16 | static final FieldResolver PathEntityFieldResolver = new FieldResolver(nmsPathEntity); 17 | static final FieldResolver Vec3DFieldResolver = new FieldResolver(nmsVector); 18 | static final ConstructorResolver PathEntityConstructorResolver = new ConstructorResolver(nmsPathEntity); 19 | static final MethodResolver PathEntityMethodResolver = new MethodResolver(nmsPathEntity); 20 | 21 | private final Object handle; 22 | 23 | public NMSPathEntity(Object handle) { 24 | this.handle = handle; 25 | } 26 | 27 | public NMSPathEntity(Object[] pointHandles) throws ReflectiveOperationException { 28 | this.handle = PathEntityConstructorResolver.resolveFirstConstructor().newInstance(new Object[] { pointHandles }); 29 | } 30 | 31 | public NMSPathEntity(NMSPathPoint[] points) throws ReflectiveOperationException { 32 | this(getHandles(points)); 33 | } 34 | 35 | public NMSPathEntity(Iterable points) throws ReflectiveOperationException { 36 | this(getHandles(points)); 37 | } 38 | 39 | static Vector3DDouble nmsToVector(Object vectorHandle) { 40 | try { 41 | return new Vector3DDouble( 42 | (double) Vec3DFieldResolver.resolve("x", "a").get(vectorHandle), 43 | (double) Vec3DFieldResolver.resolve("y", "b").get(vectorHandle), 44 | (double) Vec3DFieldResolver.resolve("z", "c").get(vectorHandle)); 45 | } catch (ReflectiveOperationException e) { 46 | throw new RuntimeException(e); 47 | } 48 | } 49 | 50 | static Object[] getHandles(NMSPathPoint[] points) { 51 | Object[] handles = ObjectArrays.newArray(NMSPathPoint.nmsPathPoint, points.length); 52 | for (int i = 0; i < points.length; i++) { 53 | handles[i] = points[i].getHandle(); 54 | } 55 | return handles; 56 | } 57 | 58 | static Object[] getHandles(Iterable points) { 59 | return getHandles(Iterables.toArray(points, NMSPathPoint.class)); 60 | } 61 | 62 | public void nextIndex() { 63 | try { 64 | nmsPathEntity.getMethod("a").invoke(handle); 65 | } catch (ReflectiveOperationException e) { 66 | throw new RuntimeException(e); 67 | } 68 | } 69 | 70 | public boolean isFinished() { 71 | try { 72 | return (boolean) nmsPathEntity.getMethod("b").invoke(handle); 73 | } catch (ReflectiveOperationException e) { 74 | throw new RuntimeException(e); 75 | } 76 | } 77 | 78 | public NMSPathPoint getTargetPoint() { 79 | try { 80 | return new NMSPathPoint(nmsPathEntity.getMethod("c").invoke(handle)); 81 | } catch (ReflectiveOperationException e) { 82 | throw new RuntimeException(e); 83 | } 84 | } 85 | 86 | public NMSPathPoint getPoint(int index) { 87 | try { 88 | return new NMSPathPoint(nmsPathEntity.getMethod("a", int.class).invoke(handle, index)); 89 | } catch (ReflectiveOperationException e) { 90 | throw new RuntimeException(e); 91 | } 92 | } 93 | 94 | public int getLength() { 95 | try { 96 | return (int) nmsPathEntity.getMethod("d").invoke(handle); 97 | } catch (ReflectiveOperationException e) { 98 | throw new RuntimeException(e); 99 | } 100 | } 101 | 102 | public int getIndex() { 103 | try { 104 | return (int) nmsPathEntity.getMethod("e").invoke(handle); 105 | } catch (ReflectiveOperationException e) { 106 | throw new RuntimeException(e); 107 | } 108 | } 109 | 110 | public Object getVectorHandle(Object entityHandle, int index) { 111 | try { 112 | return nmsPathEntity.getMethod("e", nmsEntity, int.class).invoke(handle, entityHandle, index); 113 | } catch (ReflectiveOperationException e) { 114 | throw new RuntimeException(e); 115 | } 116 | } 117 | 118 | public Object getVectorHandle(Object entityHandle) { 119 | try { 120 | return nmsPathEntity.getMethod("a", nmsEntity).invoke(handle, entityHandle); 121 | } catch (ReflectiveOperationException e) { 122 | throw new RuntimeException(e); 123 | } 124 | } 125 | 126 | public Vector3DDouble getVector(Object entityHandle) { 127 | return nmsToVector(getVectorHandle(entityHandle)); 128 | } 129 | 130 | } 131 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/path/NMSPathPoint.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.path; 2 | 3 | import org.inventivetalent.npclib.Reflection; 4 | import org.inventivetalent.reflection.resolver.ConstructorResolver; 5 | import org.inventivetalent.reflection.resolver.FieldResolver; 6 | import org.inventivetalent.vectors.d3.Vector3DDouble; 7 | import org.inventivetalent.vectors.d3.Vector3DInt; 8 | 9 | import javax.annotation.Nonnull; 10 | 11 | public class NMSPathPoint extends PathPoint { 12 | 13 | static final Class nmsPathPoint = Reflection.nmsClassResolver.resolveSilent("PathPoint"); 14 | static final FieldResolver PathPointFieldResolver = new FieldResolver(nmsPathPoint); 15 | static final ConstructorResolver PathPointConstructorResolver = new ConstructorResolver(nmsPathPoint); 16 | 17 | private final Object handle; 18 | 19 | public NMSPathPoint(Vector3DDouble doubleVector) { 20 | this(new Vector3DInt(doubleVector)); 21 | } 22 | 23 | public NMSPathPoint(Vector3DInt intVector) { 24 | this(intVector.getX(), intVector.getY(), intVector.getZ()); 25 | } 26 | 27 | public NMSPathPoint(int x, int y, int z) { 28 | super(x, y, z); 29 | this.handle = PathPointConstructorResolver.resolveWrapper(new Class[] { 30 | int.class, 31 | int.class, 32 | int.class }).newInstance(x, y, z); 33 | } 34 | 35 | public NMSPathPoint(@Nonnull Object handle) { 36 | super((int) PathPointFieldResolver.resolveWrapper("a").get(handle), (int) PathPointFieldResolver.resolveWrapper("b").get(handle), (int) PathPointFieldResolver.resolveWrapper("c").get(handle)); 37 | this.handle = handle; 38 | } 39 | 40 | public Object getHandle() { 41 | return this.handle; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/path/PathPoint.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.path; 2 | 3 | import org.bukkit.Material; 4 | import org.bukkit.World; 5 | import org.bukkit.block.Block; 6 | import org.inventivetalent.vectors.d3.Vector3DDouble; 7 | import org.inventivetalent.vectors.d3.Vector3DInt; 8 | 9 | import java.util.ArrayList; 10 | import java.util.List; 11 | 12 | public class PathPoint extends Vector3DInt { 13 | 14 | public PathPoint(Vector3DDouble doubleVector) { 15 | super(doubleVector); 16 | } 17 | 18 | public PathPoint(Vector3DInt intVector) { 19 | this(intVector.getX(), intVector.getY(), intVector.getZ()); 20 | } 21 | 22 | public PathPoint(int x, int y, int z) { 23 | super(x, y, z); 24 | } 25 | 26 | public List getNeighbours(World world) { 27 | List list = new ArrayList<>(); 28 | for (int x = -1; x <= 1; x++) { 29 | for (int z = -1; z <= 1; z++) { 30 | for (int y = -1; y <= 1; y++) { 31 | PathPoint point = new PathPoint(this.add(x, y, z)); 32 | if (point.equals(this)) { continue; } 33 | if (!point.canWalkIn(world)) { continue; } 34 | if (!point.canWalkOn(world)) { continue; } 35 | list.add(point); 36 | } 37 | } 38 | } 39 | return list; 40 | } 41 | 42 | public Block getBlock(World world) { 43 | return world.getBlockAt(getX(), getY(), getZ()); 44 | } 45 | 46 | public Block getBlockBelow(World world) { 47 | return world.getBlockAt(getX(), getY() - 1, getZ()); 48 | } 49 | 50 | public boolean canWalkIn(World world) { 51 | Block block = getBlock(world); 52 | Material type = block.getType(); 53 | if (type == Material.AIR) { return true; } 54 | if (type == Material.WATER || type == Material.STATIONARY_WATER) { return true; } 55 | if (type == Material.LAVA || type == Material.STATIONARY_LAVA) { return true; } 56 | if (!type.isSolid()) { return true; } 57 | return false; 58 | } 59 | 60 | public boolean canWalkOn(World world) { 61 | Block block = getBlockBelow(world); 62 | Material type = block.getType(); 63 | if (type == Material.AIR) { return false; } 64 | if (type == Material.WATER || type == Material.STATIONARY_WATER) { return false; } 65 | if (type == Material.LAVA || type == Material.STATIONARY_LAVA) { return false; } 66 | if (!type.isSolid()) { return false; } 67 | return true; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/path/PathfinderAbstract.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.path; 2 | 3 | import org.bukkit.Particle; 4 | import org.bukkit.World; 5 | import org.inventivetalent.npclib.ai.AIAbstract; 6 | import org.inventivetalent.npclib.entity.living.human.NPCEntityHuman; 7 | import org.inventivetalent.npclib.npc.NPCAbstract; 8 | import org.inventivetalent.npclib.npc.living.human.NPCHumanAbstract; 9 | import org.inventivetalent.vectors.d3.Vector3DDouble; 10 | 11 | public abstract class PathfinderAbstract> extends AIAbstract { 12 | 13 | protected final Vector3DDouble target; 14 | protected final double speed; 15 | 16 | protected boolean finished; 17 | protected double progress; 18 | 19 | private NMSPathEntity pathEntity; 20 | private Vector3DDouble currentPoint; 21 | 22 | public PathfinderAbstract(Vector3DDouble target, double speed) { 23 | super(); 24 | this.target = target; 25 | this.speed = speed; 26 | } 27 | 28 | @Override 29 | public void tick() { 30 | super.tick(); 31 | 32 | if (this.currentPoint == null) { 33 | // We have no points! 34 | finished = true; 35 | return; 36 | } 37 | 38 | int i = (int) this.progress; 39 | int current = this.progress >= i ? i : i - 1; 40 | double d = this.progress - current; 41 | double d1 = 1 - d; 42 | 43 | // Vector3DDouble currentPoint = this.currentPoint.add(.5, .5, .5); 44 | 45 | if (d + this.speed < 1) { 46 | double dx = (currentPoint.getX() - getNpcVector().getX()) * speed; 47 | double dz = (currentPoint.getZ() - getNpcVector().getZ()) * speed; 48 | 49 | //TODO: do we really need this? 50 | // dx += Math.random() / 10; 51 | // dz += Math.random() / 10; 52 | 53 | getNpc().getNpcEntity().move(dx, 0, dz); 54 | if (getNpc() instanceof NPCHumanAbstract) { 55 | ((NPCEntityHuman) getNpc().getNpcEntity()).checkMovement(dx, 0, dz); 56 | } 57 | this.progress += this.speed; 58 | } else { 59 | double bx = (currentPoint.getX() - getNpcVector().getX()) * d1; 60 | double bz = (currentPoint.getZ() - getNpcVector().getZ()) * d1; 61 | 62 | pathEntity.nextIndex(); 63 | if (!pathEntity.isFinished()) { 64 | this.currentPoint = pathEntity.getVector(getNpc().getNpcEntity()); 65 | 66 | double d2 = this.speed - d1; 67 | 68 | double dx = bx + (currentPoint.getX() - getNpcVector().getX()) * d2; 69 | double dy = currentPoint.getY() - getNpcVector().getY(); 70 | double dz = bz + (currentPoint.getZ() - getNpcVector().getZ()) * d2; 71 | 72 | //TODO: do we really need this? 73 | // dx += Math.random() / 10; 74 | // dz += Math.random() / 10; 75 | 76 | getNpc().getNpcEntity().move(dx, dy, dz); 77 | if (getNpc() instanceof NPCHumanAbstract) { 78 | ((NPCEntityHuman) getNpc().getNpcEntity()).checkMovement(dx, dy, dz); 79 | } 80 | this.progress += this.speed; 81 | } else { 82 | getNpc().getNpcEntity().move(bx, 0, bz); 83 | if (getNpc() instanceof NPCHumanAbstract) { 84 | ((NPCEntityHuman) getNpc().getNpcEntity()).checkMovement(bx, 0, bz); 85 | } 86 | finished = true; 87 | } 88 | } 89 | } 90 | 91 | public void find() { 92 | this.pathEntity = findPath(); 93 | this.currentPoint = this.pathEntity.getVector(getNpc().getNpcEntity()); 94 | } 95 | 96 | protected abstract NMSPathEntity findPath(); 97 | 98 | @Override 99 | public boolean isFinished() { 100 | return finished; 101 | } 102 | 103 | public World getNpcWorld() { 104 | return getNpc().getBukkitEntity().getWorld(); 105 | } 106 | 107 | public Vector3DDouble getNpcVector() { 108 | return getNpc().getNpcEntity().getLocationVector(); 109 | } 110 | 111 | public Vector3DDouble getTarget() { 112 | return target; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/registry/NPCRegistry.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.registry; 2 | 3 | import com.google.common.base.Strings; 4 | import com.google.common.collect.Maps; 5 | import javassist.ClassPool; 6 | import org.bukkit.Bukkit; 7 | import org.bukkit.Location; 8 | import org.bukkit.plugin.Plugin; 9 | import org.inventivetalent.mcwrapper.auth.GameProfileWrapper; 10 | import org.inventivetalent.npclib.ClassGenerator; 11 | import org.inventivetalent.npclib.NPCLib; 12 | import org.inventivetalent.npclib.NPCType; 13 | import org.inventivetalent.npclib.Reflection; 14 | import org.inventivetalent.npclib.annotation.NPCInfo; 15 | import org.inventivetalent.npclib.entity.NPCEntity; 16 | import org.inventivetalent.npclib.entity.living.human.EntityPlayer; 17 | import org.inventivetalent.npclib.npc.NPCAbstract; 18 | import org.inventivetalent.npclib.npc.living.human.NPCHumanAbstract; 19 | import org.inventivetalent.reflection.minecraft.Minecraft; 20 | import org.inventivetalent.reflection.resolver.ConstructorResolver; 21 | import org.inventivetalent.reflection.resolver.FieldResolver; 22 | import org.inventivetalent.reflection.resolver.MethodResolver; 23 | import org.inventivetalent.reflection.resolver.ResolverQuery; 24 | import org.inventivetalent.reflection.resolver.wrapper.MethodWrapper; 25 | 26 | import java.lang.reflect.Constructor; 27 | import java.util.*; 28 | 29 | import static com.google.common.base.Preconditions.checkNotNull; 30 | 31 | public class NPCRegistry implements Iterable> { 32 | 33 | static final Map> generatedClasses = new HashMap<>(); 34 | 35 | private static final Map registryMap = new HashMap<>(); 36 | 37 | private final Plugin plugin; 38 | private final Map> npcMap = Maps.newHashMap(); 39 | 40 | public NPCRegistry(Plugin plugin) { 41 | this.plugin = plugin; 42 | if (registryMap.containsKey(plugin.getName())) { 43 | throw new IllegalArgumentException("Registry for '" + plugin.getName() + "' already exists"); 44 | } 45 | registryMap.put(plugin.getName(), this); 46 | } 47 | 48 | public void destroy(boolean removeNpcs) { 49 | if (!registryMap.containsKey(plugin.getName())) { 50 | throw new IllegalStateException("Already destroyed"); 51 | } 52 | if (removeNpcs) { 53 | Set uuids = new HashSet<>(npcMap.keySet()); 54 | for (UUID uuid : uuids) { 55 | removeNpc(uuid); 56 | } 57 | } 58 | registryMap.remove(plugin.getName()); 59 | } 60 | 61 | public void destroy() { 62 | destroy(true); 63 | } 64 | 65 | public static NPCRegistry getRegistry(Plugin plugin) { 66 | return registryMap.get(plugin.getName()); 67 | } 68 | 69 | /** 70 | * Injects the specified NPC classes, so the entities can be loaded properly by the server 71 | * 72 | * @param classes classes to inject 73 | */ 74 | public static void injectClasses(Class... classes) { 75 | for (Class clazz : classes) { 76 | if (clazz == null) { 77 | continue; 78 | } 79 | getOrGenerateClass(NPCInfo.of(clazz)); 80 | } 81 | } 82 | 83 | static Class getOrGenerateClass(NPCInfo npcInfo) { 84 | if (generatedClasses.containsKey(npcInfo)) { 85 | return generatedClasses.get(npcInfo); 86 | } 87 | ClassPool classPool = ClassPool.getDefault(); 88 | try { 89 | Class generated = ClassGenerator.generateEntityClass(classPool, npcInfo); 90 | generatedClasses.put(npcInfo, generated); 91 | if (npcInfo.getId() != -1) { 92 | injectEntity(generated, npcInfo.getId(), npcInfo.getNPCClassName()); 93 | }// -1 -> special entity, don't inject 94 | return generated; 95 | } catch (Exception e) { 96 | System.err.println("[NPCLib] Failed to inject Entity " + npcInfo.getType()); 97 | System.err.println("[NPCLib] It won't be available for usage by plugins."); 98 | if (NPCLib.debug) { 99 | e.printStackTrace(); 100 | } 101 | } 102 | return null; 103 | } 104 | 105 | static void injectEntity(Class clazz, int id, String name) { 106 | Class EntityTypes = Reflection.nmsClassResolver.resolveSilent("EntityTypes"); 107 | if (Minecraft.VERSION.newerThan(Minecraft.Version.v1_11_R1)) { 108 | MethodResolver methodResolver = new MethodResolver(EntityTypes); 109 | MethodWrapper method = methodResolver.resolveWrapper(new ResolverQuery("a", int.class, 110 | String.class, Class.class, String.class)); 111 | if (method.exists()) { 112 | method.getMethod().setAccessible(true); 113 | method.invoke(null, id, name, clazz, name); 114 | } else { 115 | NPCLib.logger.warning("Could not inject " + clazz.getSimpleName() + " as " + name + 116 | " with id " + id + " due to incompatible Minecraft verson!"); 117 | } 118 | } else { 119 | FieldResolver fieldResolver = new FieldResolver(EntityTypes); 120 | 121 | ((Map) fieldResolver.resolveWrapper("c").get(null)).put(name, clazz); 122 | ((Map) fieldResolver.resolveWrapper("d").get(null)).put(clazz, name); 123 | ((Map) fieldResolver.resolveWrapper("f").get(null)).put(clazz, Integer.valueOf(id)); 124 | } 125 | NPCLib.logger.info("Injected " + clazz.getSimpleName() + " as " + name + " with id " + id); 126 | } 127 | 128 | /** 129 | * Creates and spawns the specified NPC Entity 130 | * 131 | * @param location {@link Location} to spawn the entity at 132 | * @param npcClass NPC-Class to spawn 133 | * @param a NPC class extending {@link NPCAbstract} 134 | * @return the spawned NPC Entity 135 | */ 136 | public > T spawnNPC(Location location, Class npcClass) { 137 | checkNotNull(location); 138 | checkNotNull(npcClass); 139 | try { 140 | NPCInfo npcInfo = NPCInfo.of(npcClass); 141 | NPCEntity npcEntity = createEntity(location, npcInfo); 142 | return wrapAndInitEntity(npcEntity, location, npcInfo, npcClass); 143 | } catch (Exception e) { 144 | throw new RuntimeException(e); 145 | } 146 | } 147 | 148 | /** 149 | * Creates and spawns the specified NPC Type 150 | * 151 | * @param location {@link Location} to spawn the entity at 152 | * @param npcType type of the NPC 153 | * @return the spawned NPC Entity 154 | */ 155 | 156 | public NPCAbstract spawnNPC(Location location, NPCType npcType) { 157 | return spawnNPC(location, checkNotNull(npcType).getNpcClass()); 158 | } 159 | 160 | /** 161 | * Creates and spawns a player NPC entity 162 | * 163 | * @param location {@link Location} to spawn the entity at 164 | * @param npcClass NPC-Class to spawn 165 | * @param gameProfile {@link GameProfileWrapper} to use for the player 166 | * @param a NPC class extending {@link NPCHumanAbstract} 167 | * @return the spawned NPC entity 168 | */ 169 | public > T spawnPlayerNPC(Location location, Class npcClass, 170 | GameProfileWrapper gameProfile) { 171 | checkNotNull(location); 172 | checkNotNull(npcClass); 173 | checkNotNull(gameProfile); 174 | try { 175 | NPCInfo npcInfo = NPCInfo.of(npcClass); 176 | NPCEntity npcEntity = createPlayerEntity(location, npcInfo, gameProfile); 177 | return wrapAndInitEntity(npcEntity, location, npcInfo, npcClass); 178 | } catch (Exception e) { 179 | throw new RuntimeException(e); 180 | } 181 | } 182 | 183 | /** 184 | * Creates and spawns a player NPC entity 185 | * 186 | * @param location {@link Location} to spawn the entity at 187 | * @param npcClass NPC-Class to spawn 188 | * @param uuid {@link UUID} of the player 189 | * @param name Name of the player 190 | * @param a NPC class extending {@link NPCHumanAbstract} 191 | * @return the spawned NPC entity 192 | */ 193 | public > T spawnPlayerNPC(Location location, Class npcClass, UUID uuid, String name) { 194 | if (uuid == null && Strings.isNullOrEmpty(name)) { 195 | throw new IllegalArgumentException("UUID and Name cannot both be empty"); 196 | } 197 | return spawnPlayerNPC(location, npcClass, new GameProfileWrapper(checkNotNull(uuid), name)); 198 | } 199 | 200 | public void registerNpc(NPCAbstract npc) { 201 | NPCLib.debug("Registered", npc, "with", plugin.getName()); 202 | npcMap.put(npc.getUniqueId(), npc); 203 | } 204 | 205 | public > T removeNpc(T npc) { 206 | npcMap.remove(checkNotNull(npc).getUniqueId()); 207 | npc.despawn(); 208 | return npc; 209 | } 210 | 211 | public NPCAbstract removeNpc(UUID uuid) { 212 | NPCAbstract npc = npcMap.remove(checkNotNull(uuid)); 213 | if (npc != null) { 214 | npc.despawn(); 215 | } 216 | return npc; 217 | } 218 | 219 | public Collection> getNpcs() { 220 | return new ArrayList<>(npcMap.values()); 221 | } 222 | 223 | protected T createEntity(Location location, NPCInfo npcInfo) { 224 | if ("EntityPlayer".equals(npcInfo.getNms())) { 225 | throw new IllegalArgumentException("cannot construct EntityPlayer using #createEntity"); 226 | } 227 | 228 | Class clazz = getOrGenerateClass(npcInfo); 229 | if (clazz == null) { 230 | throw new RuntimeException("Entity " + npcInfo.getType() + " is not available in this version!"); 231 | } 232 | 233 | try { 234 | // noinspection unchecked 235 | Constructor constructor = clazz.getConstructor(Reflection.nmsClassResolver.resolve("World")); 236 | // noinspection unchecked 237 | return (T) constructor.newInstance(Minecraft.getHandle(location.getWorld())); 238 | } catch (Exception e) { 239 | throw new RuntimeException(e); 240 | } 241 | } 242 | 243 | protected EntityPlayer createPlayerEntity(Location location, NPCInfo npcInfo, GameProfileWrapper gameProfile) { 244 | Class clazz = getOrGenerateClass(npcInfo); 245 | if (clazz == null) { 246 | throw new RuntimeException("Entity " + npcInfo.getType() + " is not available in this version!"); 247 | } 248 | try { 249 | Object minecraftServer = new MethodResolver(Bukkit.getServer().getClass()).resolveWrapper("getServer") 250 | .invoke(Bukkit.getServer()); 251 | Object worldServer = Minecraft.getHandle(location.getWorld()); 252 | Object interactManager = new ConstructorResolver( 253 | Reflection.nmsClassResolver.resolve("PlayerInteractManager")) 254 | .resolve(new Class[] { Reflection.nmsClassResolver.resolve("World") }) 255 | .newInstance(worldServer); 256 | 257 | // noinspection unchecked 258 | Constructor constructor = clazz.getConstructor(Reflection.nmsClassResolver.resolve("MinecraftServer"), 259 | Reflection.nmsClassResolver.resolve("WorldServer"), gameProfile.getHandle().getClass(), 260 | Reflection.nmsClassResolver.resolve("PlayerInteractManager")); 261 | return (EntityPlayer) constructor.newInstance(minecraftServer, worldServer, gameProfile.getHandle(), 262 | interactManager); 263 | } catch (Exception e) { 264 | throw new RuntimeException(e); 265 | } 266 | } 267 | 268 | protected > T wrapAndInitEntity(NPCEntity entity, Location location, NPCInfo npcInfo, 269 | Class npcClass) throws Exception { 270 | // NPCAbstract npcAbstract = (NPCAbstract) new 271 | // ConstructorResolver(npcClass).resolveFirstConstructorSilent().newInstance(entity); 272 | NPCAbstract npcAbstract = entity.getNPC(); 273 | entity.setNpcInfo(npcInfo); 274 | npcAbstract.postInit(this.plugin, location); 275 | npcAbstract.spawn(); 276 | // noinspection unchecked 277 | return (T) npcAbstract; 278 | } 279 | 280 | @Override 281 | public Iterator> iterator() { 282 | return npcMap.values().iterator(); 283 | } 284 | } 285 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/skin/ISkinnableEntity.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.skin; 2 | 3 | public interface ISkinnableEntity { 4 | 5 | void setSkinLayers(SkinLayer... visibleLayers); 6 | 7 | void setSkinTexture(String value, String signature); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/skin/SkinLayer.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.skin; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collection; 5 | import java.util.List; 6 | 7 | public enum SkinLayer { 8 | 9 | CAPE(0), 10 | JACKET(1), 11 | LEFT_SLEEVE(2), 12 | RIGHT_SLEEVE(3), 13 | LEFT_PANTS_LEG(4), 14 | RIGHT_PANTS_LEG(5), 15 | HAT(6); 16 | 17 | public static final SkinLayer[] ALL = new SkinLayer[] { 18 | CAPE, 19 | JACKET, 20 | LEFT_SLEEVE, 21 | RIGHT_SLEEVE, 22 | LEFT_PANTS_LEG, 23 | RIGHT_PANTS_LEG, 24 | HAT }; 25 | 26 | private final int id; 27 | private final int shifted; 28 | 29 | SkinLayer(int id) { 30 | this.id = id; 31 | this.shifted = 1 << id; 32 | } 33 | 34 | public int getID() { 35 | return this.id; 36 | } 37 | 38 | public int getShifted() { 39 | return this.shifted; 40 | } 41 | 42 | public boolean isActive(int value) { 43 | return (value & getShifted()) == getShifted(); 44 | } 45 | 46 | public static int getValue(Iterable active) { 47 | int i = 0; 48 | for (SkinLayer layer : active) { 49 | i |= layer.getShifted(); 50 | } 51 | return i; 52 | } 53 | 54 | public static int getValue(SkinLayer[] active) { 55 | int i = 0; 56 | for (SkinLayer layer : active) { 57 | i |= layer.getShifted(); 58 | } 59 | return i; 60 | } 61 | 62 | public static Collection getLayers(int value) { 63 | List layers = new ArrayList<>(); 64 | for (SkinLayer layer : values()) { 65 | if (layer.isActive(value)) { layers.add(layer); } 66 | } 67 | return layers; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/watcher/AnnotatedMethodWatcher.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.watcher; 2 | 3 | import lombok.AllArgsConstructor; 4 | import org.inventivetalent.npclib.NPCLib; 5 | import org.inventivetalent.npclib.ObjectContainer; 6 | import org.inventivetalent.npclib.Reflection; 7 | import org.inventivetalent.npclib.SuperSwitch; 8 | import org.inventivetalent.reflection.resolver.wrapper.MethodWrapper; 9 | 10 | import java.lang.reflect.Method; 11 | import java.util.Arrays; 12 | import java.util.Map; 13 | import java.util.concurrent.ConcurrentHashMap; 14 | 15 | public class AnnotatedMethodWatcher extends MethodWatcher { 16 | 17 | Object toWatch; 18 | Map watchedMethods = new ConcurrentHashMap<>(); 19 | 20 | public AnnotatedMethodWatcher(Object toWatch) { 21 | this(toWatch, true); 22 | } 23 | 24 | public AnnotatedMethodWatcher(Object toWatch, boolean searchSuper) { 25 | this.toWatch = toWatch; 26 | if (searchSuper) { 27 | Class superClazz = toWatch.getClass(); 28 | while (superClazz != null) { 29 | register(superClazz); 30 | superClazz = superClazz.getSuperclass(); 31 | } 32 | } else { 33 | register(toWatch.getClass()); 34 | } 35 | } 36 | 37 | void register(Class clazz) { 38 | for (Method method : clazz.getMethods()) { 39 | Watch annotation = method.getAnnotation(Watch.class); 40 | if (annotation != null) { 41 | String[] signatures = annotation.value(); 42 | if (signatures.length == 0) {signatures = new String[] { Reflection.getMethodSignature(method) }; } 43 | boolean passThrough = true; 44 | if (method.getReturnType().equals(Void.TYPE)) { passThrough = annotation.passThrough(); } 45 | boolean containers = annotation.containers(); 46 | // boolean ignoreThiz = annotation.ignoreThiz(); 47 | 48 | for (String signature : signatures) { 49 | MethodWrapper.MethodSignature methodSignature = MethodWrapper.MethodSignature.fromString(signature); 50 | if (!watchedMethods.containsKey(methodSignature)) { 51 | NPCLib.debug("@Watching method", methodSignature.getSignature(), "in", clazz.getName()); 52 | boolean hasSwitch = false; 53 | if (method.getParameterTypes().length >= 1) { 54 | if (SuperSwitch.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])) { 55 | hasSwitch = true; 56 | } 57 | } 58 | boolean hasWildcards = signature.contains("*") || signature.contains("?"); 59 | watchedMethods.put(methodSignature, new WatchedMethod(signature, passThrough, containers,/*ignoreThiz,*/method.getReturnType().equals(Void.TYPE), hasSwitch, hasWildcards, method)); 60 | } 61 | } 62 | } 63 | } 64 | } 65 | 66 | // @Override 67 | // public boolean methodCalled(Object thiz, String methodSignature, ObjectContainer[] containers) { 68 | // WatchedMethod watchedMethod = watchedMethods.get(methodSignature); 69 | // if (watchedMethod == null) { 70 | // return super.methodCalled(thiz, methodSignature, containers); 71 | // } 72 | // Object[] args = watchedMethod.containers ? containers : ObjectContainer.toObjects(containers); 73 | // try { 74 | // Object returned = watchedMethod.method.invoke(toWatch, args); 75 | // if (watchedMethod.isVoid) { 76 | // return watchedMethod.passThrough; 77 | // } 78 | // return (boolean) returned; 79 | // } catch (Exception e) { 80 | // throw new RuntimeException("Failed to invoke @Watch method " + methodSignature + " with args: " + Arrays.toString(args), e); 81 | // } 82 | // } 83 | 84 | @Override 85 | public Object methodCalled(Object thiz, String methodSignature, SuperSwitch superSwitch, ObjectContainer[] containers) { 86 | MethodWrapper.MethodSignature calledSignature = MethodWrapper.MethodSignature.fromString(methodSignature); 87 | WatchedMethod watchedMethod = null; 88 | for (Map.Entry entry : this.watchedMethods.entrySet()) { 89 | if (entry.getKey().matches(calledSignature)) { 90 | watchedMethod = entry.getValue(); 91 | break; 92 | } 93 | } 94 | if (watchedMethod == null) { 95 | return super.methodCalled(thiz, methodSignature, superSwitch, containers); 96 | } 97 | Object[] args = watchedMethod.containers ? containers : ObjectContainer.toObjects(containers); 98 | try { 99 | if (watchedMethod.hasSwitch) { 100 | args = Arrays.copyOf(args, args.length + 1, Object[].class); 101 | args[args.length - 1] = superSwitch; 102 | } 103 | return watchedMethod.method.invoke(toWatch, args); 104 | } catch (Exception e) { 105 | throw new RuntimeException("Failed to invoke @Watch method " + methodSignature + " in " + toWatch.getClass() + " with args: " + Arrays.toString(args), e); 106 | } 107 | } 108 | 109 | @AllArgsConstructor 110 | class WatchedMethod { 111 | String signature; 112 | boolean passThrough; 113 | boolean containers; 114 | // boolean ignoreThiz; 115 | boolean isVoid; 116 | boolean hasSwitch; 117 | boolean hasWildcards; 118 | Method method; 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/watcher/MethodWatcher.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.watcher; 2 | 3 | import org.inventivetalent.npclib.ObjectContainer; 4 | import org.inventivetalent.npclib.SuperSwitch; 5 | 6 | public class MethodWatcher { 7 | 8 | // /** 9 | // * Called for void methods only. If it returns true, the super method will be called 10 | // * 11 | // * @param methodSignature signature of the called method 12 | // * @param args method arguments 13 | // * @return whether the super method will be called 14 | // */ 15 | // public boolean methodCalled(Object thiz, String methodSignature, ObjectContainer[] args) { 16 | // return true; 17 | // } 18 | 19 | /** 20 | * Called for non-void methods. 21 | * 22 | * @param thiz The object instance to call the method on. 23 | * @param methodSignature signature of the called method 24 | * @param superSwitch {@link SuperSwitch} to decide the super-call behaviour 25 | * @param args method arguments 26 | * @return value the method returns 27 | */ 28 | public Object methodCalled(Object thiz, String methodSignature, SuperSwitch superSwitch, ObjectContainer[] args) { 29 | return null; 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /API/src/main/java/org/inventivetalent/npclib/watcher/Watch.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.watcher; 2 | 3 | import java.lang.annotation.ElementType; 4 | import java.lang.annotation.Retention; 5 | import java.lang.annotation.RetentionPolicy; 6 | import java.lang.annotation.Target; 7 | 8 | @Target(ElementType.METHOD) 9 | @Retention(RetentionPolicy.RUNTIME) 10 | public @interface Watch { 11 | 12 | /** 13 | * Possible method signatures to watch. If empty, this method's signature will be used. 14 | * 15 | * @return the watched method signature(s) 16 | */ 17 | String[] value() default {}; 18 | 19 | /** 20 | * Alternative for void methods to decide whether super is called. (Alternatively just return true/false) 21 | * 22 | * @return if true, the super method will be called 23 | */ 24 | boolean passThrough() default true; 25 | 26 | /** 27 | * Whether the annotated methods uses {@link org.inventivetalent.npclib.ObjectContainer}s as its parameters. Defaults to true 28 | * 29 | * @return true if all parameters of the annotated method are {@link org.inventivetalent.npclib.ObjectContainer}s, false if the parameters are raw types 30 | */ 31 | boolean containers() default true; 32 | 33 | // /** 34 | // * Whether to exclude the this parameter 35 | // * 36 | // * @return exclude this 37 | // */ 38 | // boolean ignoreThiz() default false; 39 | } 40 | -------------------------------------------------------------------------------- /API/src/main/resources/npclib.properties: -------------------------------------------------------------------------------- 1 | npclib.version=${project.version} -------------------------------------------------------------------------------- /API/src/test/java/org/inventivetalent/npclib/test/SkinLayerTest.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.test; 2 | 3 | import org.inventivetalent.npclib.skin.SkinLayer; 4 | import org.junit.Test; 5 | 6 | import java.util.List; 7 | 8 | import static org.junit.Assert.assertEquals; 9 | import static org.junit.Assert.assertTrue; 10 | 11 | public class SkinLayerTest { 12 | 13 | @Test 14 | public void skinLayerValueTest() { 15 | int value = SkinLayer.getValue(new SkinLayer[] { 16 | SkinLayer.CAPE, 17 | SkinLayer.LEFT_SLEEVE, 18 | SkinLayer.RIGHT_PANTS_LEG }); 19 | assertEquals(37, value); 20 | 21 | List layers = (List) SkinLayer.getLayers(value); 22 | assertTrue(layers.contains(SkinLayer.CAPE)); 23 | assertTrue(layers.contains(SkinLayer.LEFT_SLEEVE)); 24 | assertTrue(layers.contains(SkinLayer.RIGHT_PANTS_LEG)); 25 | } 26 | 27 | @Test 28 | public void allTest() { 29 | assertEquals(127, SkinLayer.getValue(SkinLayer.ALL)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /API/src/test/java/org/inventivetalent/npclib/test/TypeTest.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.test; 2 | 3 | import org.bukkit.entity.EntityType; 4 | import org.inventivetalent.npclib.NPCType; 5 | import org.junit.Test; 6 | 7 | import static org.junit.Assert.assertEquals; 8 | import static org.junit.Assert.assertNull; 9 | 10 | public class TypeTest { 11 | 12 | @Test 13 | public void entityTypeTest() { 14 | assertEquals(NPCType.ARMOR_STAND, NPCType.forEntityType(EntityType.ARMOR_STAND)); 15 | assertEquals(NPCType.HORSE, NPCType.forEntityType(EntityType.HORSE)); 16 | } 17 | 18 | @Test 19 | public void fromStringTest() { 20 | assertEquals(NPCType.CHICKEN, NPCType.fromString("chicken")); 21 | assertEquals(NPCType.MUSHROOM_COW, NPCType.fromString("mushroom cow")); 22 | assertEquals(NPCType.MUSHROOM_COW, NPCType.fromString("mushroomCow")); 23 | assertEquals(NPCType.SHULKER, NPCType.fromString("Shulker")); 24 | assertEquals(NPCType.ENDER_DRAGON, NPCType.fromString("EnderDragon")); 25 | 26 | assertNull(NPCType.fromString("does not exist")); 27 | assertNull(NPCType.fromString("noentity")); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## What steps will reproduce the problem? 2 | 1. 3 | 2. 4 | 3. 5 | 6 | ## What were you expecting to happen? What happened instead? 7 | 8 | ## What version of the plugin are you using? *Type /version <Plugin Name>* 9 | 10 | ## What Spigot version are you using? *Type /version* 11 | 12 | ## What plugins are you using? *Type /plugins* 13 | 14 | ## Do you have an error log? Use [pastebin.com](http://pastebin.com). *If you're not sure, upload your whole server log* 15 | 16 | ## Did your client crash? *Upload errors in .minecraft/logs/latest.log as well* 17 | 18 | ## Additional information? *(Are you using Bungeecord? Did it work in previous versions? etc.)* 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) inventivetalent 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Plugin/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 33 | 34 | parent 35 | org.inventivetalent.npc-lib 36 | parent 37 | 38 | 4.0.0 39 | 40 | plugin 41 | ${npclib.version} 42 | 43 | 44 | NPCLib_v${npclib.version} 45 | 46 | 47 | org.apache.maven.plugins 48 | maven-compiler-plugin 49 | 3.3 50 | 51 | 1.7 52 | 1.7 53 | 54 | 55 | 56 | org.apache.maven.plugins 57 | maven-shade-plugin 58 | 2.4 59 | 60 | 61 | package 62 | 63 | shade 64 | 65 | 66 | 67 | 68 | org.mcstats.* 69 | org.inventivetalent.npc-lib:** 70 | org.inventivetalent:reflectionhelper** 71 | org.inventivetalent:pluginannotations** 72 | org.inventivetalent:mc-wrappers** 73 | org.inventivetalent:vectors** 74 | org.inventivetalent:boundingboxapi** 75 | org.inventivetalent:apimanager** 76 | org.inventivetalent:nbt-lib** 77 | org.inventivetalent:mcstats-apimanager** 78 | org.inventivetalent:eventcallbacks** 79 | org.inventivetalent.spiget-update:bukkit** 80 | org.javassist:** 81 | 82 | 83 | 84 | 85 | org.mcstats 86 | org.inventivetalent.npclib.mcstats 87 | 88 | 89 | org.inventivetalent.reflection 90 | org.inventivetalent.npclib.reflection 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | inventive-repo 103 | https://repo.inventivetalent.org/content/groups/public/ 104 | 105 | 106 | 107 | 108 | 109 | 110 | org.inventivetalent.npc-lib 111 | api 112 | ${npclib.version} 113 | compile 114 | true 115 | 116 | 117 | 118 | org.inventivetalent 119 | eventcallbacks 120 | 1.0.2-SNAPSHOT 121 | 122 | 123 | 124 | org.inventivetalent.spiget-update 125 | bukkit 126 | 1.3.0 127 | 128 | 129 | 130 | 131 | -------------------------------------------------------------------------------- /Plugin/src/main/java/org/inventivetalent/npclib/NPCLibPlugin.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib; 2 | 3 | import org.bukkit.Bukkit; 4 | import org.bukkit.event.Listener; 5 | import org.bukkit.plugin.java.JavaPlugin; 6 | import org.inventivetalent.apihelper.APIManager; 7 | import org.inventivetalent.npclib.command.SpawnCommands; 8 | import org.inventivetalent.npclib.metrics.Metrics; 9 | import org.inventivetalent.npclib.registry.NPCRegistry; 10 | import org.inventivetalent.pluginannotations.PluginAnnotations; 11 | import org.inventivetalent.update.spiget.SpigetUpdate; 12 | import org.inventivetalent.update.spiget.UpdateCallback; 13 | import org.inventivetalent.update.spiget.comparator.VersionComparator; 14 | 15 | public class NPCLibPlugin extends JavaPlugin implements Listener { 16 | 17 | private NPCLib npcLibInstance = new NPCLib(); 18 | private NPCRegistry pluginNpcRegistry; 19 | 20 | @Override 21 | public void onLoad() { 22 | NPCLib.debug = getConfig().getBoolean("debug"); 23 | 24 | APIManager.registerAPI(npcLibInstance, this); 25 | } 26 | 27 | @Override 28 | public void onEnable() { 29 | saveDefaultConfig(); 30 | 31 | NPCLib.logger = getLogger(); 32 | 33 | APIManager.initAPI(NPCLib.class); 34 | pluginNpcRegistry = NPCLib.createRegistry(this); 35 | 36 | Bukkit.getPluginManager().registerEvents(this, this); 37 | PluginAnnotations.COMMAND.load(this, new SpawnCommands(this)); 38 | 39 | new Metrics(this); 40 | 41 | SpigetUpdate spigetUpdate = new SpigetUpdate(this, 5853).setUserAgent("NPCLib/" + getDescription().getVersion()).setVersionComparator(VersionComparator.SEM_VER); 42 | spigetUpdate.checkForUpdate(new UpdateCallback() { 43 | @Override 44 | public void updateAvailable(String s, String s1, boolean b) { 45 | getLogger().info("A new version is available (" + s + "). Download it from https://r.spiget.org/5853"); 46 | } 47 | 48 | @Override 49 | public void upToDate() { 50 | getLogger().info("The plugin is up-to-date."); 51 | } 52 | }); 53 | } 54 | 55 | @Override 56 | public void onDisable() { 57 | APIManager.disableAPI(NPCLib.class); 58 | } 59 | 60 | public NPCRegistry getPluginNpcRegistry() { 61 | return pluginNpcRegistry; 62 | } 63 | 64 | } -------------------------------------------------------------------------------- /Plugin/src/main/java/org/inventivetalent/npclib/command/SpawnCommands.java: -------------------------------------------------------------------------------- 1 | package org.inventivetalent.npclib.command; 2 | 3 | import com.google.common.base.Strings; 4 | import org.bukkit.Bukkit; 5 | import org.bukkit.Location; 6 | import org.bukkit.World; 7 | import org.bukkit.command.CommandSender; 8 | import org.bukkit.entity.Entity; 9 | import org.bukkit.entity.Player; 10 | import org.bukkit.event.player.PlayerInteractEntityEvent; 11 | import org.inventivetalent.eventcallbacks.EventCallbacks; 12 | import org.inventivetalent.eventcallbacks.PlayerEventCallback; 13 | import org.inventivetalent.npclib.NPCLib; 14 | import org.inventivetalent.npclib.NPCLibPlugin; 15 | import org.inventivetalent.npclib.NPCType; 16 | import org.inventivetalent.npclib.npc.NPCAbstract; 17 | import org.inventivetalent.npclib.npc.living.human.NPCPlayer; 18 | import org.inventivetalent.npclib.skin.SkinLayer; 19 | import org.inventivetalent.pluginannotations.command.*; 20 | 21 | import java.util.List; 22 | import java.util.UUID; 23 | 24 | public class SpawnCommands { 25 | 26 | private NPCLibPlugin plugin; 27 | private EventCallbacks eventCallbacks; 28 | 29 | public SpawnCommands(NPCLibPlugin plugin) { 30 | this.plugin = plugin; 31 | this.eventCallbacks = EventCallbacks.of(plugin); 32 | } 33 | 34 | @Command(name = "spawnNpc", 35 | aliases = {}, 36 | usage = " [x] [y] [z] [pitch] [yaw] [world]", 37 | description = "Spawn an NPC at your location or the specified coordinates", 38 | min = 1, 39 | max = 7, 40 | fallbackPrefix = "npclib", 41 | errorHandler = FeedbackErrorHandler.class) 42 | @Permission("npclib.command.spawn") 43 | public void spawnNPC(CommandSender sender, String typeString, @OptionalArg Double x, @OptionalArg Double y, @OptionalArg Double z, @OptionalArg Double pitch, @OptionalArg Double yaw, @OptionalArg String worldName) { 44 | NPCType npcType = NPCType.fromString(typeString); 45 | if (npcType == null) { 46 | sender.sendMessage("§cCould not find type for '" + typeString + "'"); 47 | return; 48 | } 49 | Location location = parseLocation(sender, x, y, z, pitch, yaw, worldName); 50 | if (location == null) { return; } 51 | 52 | plugin.getPluginNpcRegistry().spawnNPC(location, npcType); 53 | sender.sendMessage("§aNPC spawned at §7" + location.getWorld().getName() + "," + location.getX() + "," + location.getY() + "," + location.getZ()); 54 | } 55 | 56 | @Command(name = "spawnPlayer", 57 | aliases = { "spawnNpcPlayer" }, 58 | usage = " [skin] [x] [y] [z] [pitch] [yaw] [world]", 59 | description = "Spawn a Player NPC at your location or the specified coordinates", 60 | min = 1, 61 | max = 8, 62 | fallbackPrefix = "npclib", 63 | errorHandler = FeedbackErrorHandler.class) 64 | @Permission("npclib.command.spawnplayer") 65 | public void spawnPlayer(CommandSender sender, String name, @OptionalArg String skin, @OptionalArg Double x, @OptionalArg Double y, @OptionalArg Double z, @OptionalArg Double pitch, @OptionalArg Double yaw, @OptionalArg String worldName) { 66 | if (name.length() > 16) { 67 | sender.sendMessage("§cName is too long (" + name.length() + ">16)"); 68 | return; 69 | } 70 | Location location = parseLocation(sender, x, y, z, pitch, yaw, worldName); 71 | if (location == null) { return; } 72 | 73 | NPCPlayer npc = plugin.getPluginNpcRegistry().spawnPlayerNPC(location, NPCPlayer.class, UUID.randomUUID(), name); 74 | if (skin == null || skin.isEmpty() && !"none".equals(skin)) { 75 | skin = name; 76 | } 77 | if (!"none".equals(skin)) { 78 | npc.setSkin(skin); 79 | } 80 | npc.setSkinLayers(SkinLayer.ALL); 81 | sender.sendMessage("§aNPC spawned at §7" + location.getWorld().getName() + "," + location.getX() + "," + location.getY() + "," + location.getZ()); 82 | } 83 | 84 | @Command(name = "removeNpc", 85 | aliases = {}, 86 | usage = "", 87 | description = "Remove a previously created NPC by right-clicking it", 88 | fallbackPrefix = "npclib", 89 | errorHandler = FeedbackErrorHandler.class) 90 | @Permission("npclib.command.removenpc") 91 | public void removeNpc(final Player player) { 92 | int nearbyCount = 0; 93 | for (Entity entity : player.getNearbyEntities(8, 4, 8)) { 94 | if (NPCLib.isNPC(entity)) { nearbyCount++; } 95 | } 96 | if (nearbyCount == 0) { 97 | player.sendMessage("§cNo NPCs found nearby. Please stand closer and try again."); 98 | return; 99 | } 100 | eventCallbacks.listenFor(PlayerInteractEntityEvent.class, new PlayerEventCallback(player) { 101 | @Override 102 | public void callPlayer(PlayerInteractEntityEvent event) { 103 | if (event.isCancelled()) { return; } 104 | if (event.getPlayer().isSneaking()) {// Cancelled 105 | player.sendMessage("§aCancelled"); 106 | return; 107 | } 108 | Entity entity = event.getRightClicked(); 109 | NPCAbstract npc = NPCLib.getNPC(entity); 110 | if (npc == null) { 111 | player.sendMessage("§cThat's not an NPC"); 112 | return; 113 | } 114 | NPCAbstract removed = plugin.getPluginNpcRegistry().removeNpc(entity.getUniqueId()); 115 | if (removed != null) { 116 | player.sendMessage("§aNPC removed"); 117 | } else { 118 | player.sendMessage("§cCould not remove NPC, it was probably spawned by another plugin"); 119 | } 120 | } 121 | }); 122 | Bukkit.getScheduler().runTaskLater(plugin, new Runnable() { 123 | @Override 124 | public void run() { 125 | player.sendMessage("§ePlease §7right-click §athe NPC to remove it, or §7hold shift & right-click §eto cancel."); 126 | } 127 | }, 10); 128 | } 129 | 130 | @Completion(name = "spawnNpc") 131 | public void spawnNPC(List list, CommandSender sender, String typeString, @OptionalArg Double x, @OptionalArg Double y, @OptionalArg Double z, @OptionalArg Double pitch, @OptionalArg Double yaw, @OptionalArg String worldName) { 132 | if (x == null && NPCType.fromString(typeString) == null) { 133 | for (NPCType npcType : NPCType.values()) { 134 | list.add(npcType.name()); 135 | } 136 | return; 137 | } 138 | if (x != null && y != null && z != null) { 139 | for (World world : Bukkit.getWorlds()) { 140 | list.add(world.getName()); 141 | } 142 | } 143 | } 144 | 145 | @Completion(name = "spawnPlayer") 146 | public void spawnPlayer(List list, CommandSender sender, String name, @OptionalArg String skin, @OptionalArg Double x, @OptionalArg Double y, @OptionalArg Double z, @OptionalArg Double pitch, @OptionalArg Double yaw, @OptionalArg String worldName) { 147 | if (name != null && x != null && y != null && z != null) { 148 | for (World world : Bukkit.getWorlds()) { 149 | list.add(world.getName()); 150 | } 151 | } 152 | } 153 | 154 | Location parseLocation(CommandSender sender, Double x, Double y, Double z, Double pitch, Double yaw, String worldName) { 155 | Location location; 156 | if (sender instanceof Entity) { 157 | location = ((Entity) sender).getLocation(); 158 | if (x != null) { location.setX(x); } 159 | if (y != null) { location.setY(y); } 160 | if (z != null) { location.setZ(z); } 161 | if (pitch != null) { location.setPitch(pitch.floatValue()); } 162 | if (yaw != null) { location.setYaw(yaw.floatValue()); } 163 | 164 | if (worldName != null) { 165 | World world = Bukkit.getWorld(worldName); 166 | if (world == null) { 167 | sender.sendMessage("§cWorld '" + worldName + "' does not exist"); 168 | return null; 169 | } 170 | location.setWorld(world); 171 | } 172 | } else { 173 | if (Strings.isNullOrEmpty(worldName)) { 174 | sender.sendMessage("§cPlease specify the location"); 175 | return null; 176 | } 177 | World world = Bukkit.getWorld(worldName); 178 | if (world == null) { 179 | sender.sendMessage("§cWorld '" + worldName + "' does not exist"); 180 | return null; 181 | } 182 | location = new Location(world, x, y, z, pitch.floatValue(), yaw.floatValue()); 183 | } 184 | return location; 185 | } 186 | 187 | } 188 | -------------------------------------------------------------------------------- /Plugin/src/main/resources/config.yml: -------------------------------------------------------------------------------- 1 | debug: false -------------------------------------------------------------------------------- /Plugin/src/main/resources/plugin.yml: -------------------------------------------------------------------------------- 1 | name: NPCLib 2 | main: org.inventivetalent.npclib.NPCLibPlugin 3 | author: inventivetalent 4 | version: ${project.version} 5 | 6 | load: STARTUP 7 | depend: [PacketListenerApi] 8 | softdepend: [NickNamer] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # CompactNPCLib 2 | 3 | [![Build Status](https://travis-ci.org/InventivetalentDev/CompactNPCLib.svg?branch=master)](https://travis-ci.org/InventivetalentDev/CompactNPCLib) 4 | [![GitHub release](https://img.shields.io/github/release/InventivetalentDev/CompactNPCLib.svg)](https://github.com/InventivetalentDev/CompactNPCLib/releases/latest) 5 | 6 | Library to create NPCs. 7 | 8 | This is a "*compact*" (& experimental) version of [NPCLib](https://github.com/InventivetalentDev/NPCLib), which uses Javassist and Reflection to create NPC classes for any Minecraft entity. 9 | 10 | Please check the [Wiki](https://github.com/InventivetalentDev/CompactNPCLib/wiki) or the [SpigotMC page](https://www.spigotmc.org/resources/api-npclib-1-7-1-8-1-9.5853/) for more information. 11 | 12 | ## Maven 13 | ```xml 14 | 15 | 16 | inventive-repo 17 | https://repo.inventivetalent.org/content/groups/public/ 18 | 19 | 20 | 21 | 22 | org.inventivetalent.npc-lib 23 | api 24 | VERSION 25 | 26 | 27 | ``` 28 | 29 | ## Contributing 30 | Please open a new pull request for any feature you think this API could need. 31 | Especially for methods you think should be directly available in the NPC classes, without having to call `#getBukkitEntiy` first. 32 | There are currently also many classes that are not fully documented yet, so feel free to complete those as well ;) 33 | 34 | Please also create pull requests for entities currently not available/added in new Minecraft versions. Refer to the [**Creating custom NPC classes**](https://github.com/InventivetalentDev/CompactNPCLib/wiki/Creating-custom-NPC-classes) Wiki if you need help. 35 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 29 | 30 | 33 | 4.0.0 34 | 35 | org.inventivetalent.npc-lib 36 | parent 37 | pom 38 | parent 39 | https://github.com/InventivetalentDev/CompactNPCLib 40 | 41 | 42 | API 43 | Plugin 44 | 45 | 46 | 47 | 2.5.2-SNAPSHOT 48 | 49 | 3.5.0 50 | 1.13.1-SNAPSHOT 51 | 1.4.7-SNAPSHOT 52 | 1.0.3-SNAPSHOT 53 | 1.0.0 54 | 1.2.3 55 | 1.0.3-SNAPSHOT 56 | 1.0.1-SNAPSHOT 57 | 3.14.1-SNAPSHOT 58 | 59 | 60 | 61 | 62 | 63 | src/main/resources 64 | true 65 | 66 | plugin.yml 67 | config.yml 68 | npclib.properties 69 | 70 | 71 | 72 | 73 | 74 | org.apache.maven.plugins 75 | maven-compiler-plugin 76 | 3.3 77 | 78 | 1.8 79 | 1.8 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | sonatype-nexus-releases 88 | http://repo.inventivetalent.org/content/repositories/releases/ 89 | 90 | 91 | sonatype-nexus-snapshots 92 | http://repo.inventivetalent.org/content/repositories/snapshots/ 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ], 5 | "maven": { 6 | "enabled": true 7 | }, 8 | "ignoreUnstable": false, 9 | "hostRules": [{ 10 | "hostType": "maven", 11 | "endpoint": "https://repo.inventivetalent.org/content/groups/public/" 12 | }] 13 | } 14 | -------------------------------------------------------------------------------- /settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | sonatype-nexus-releases 5 | ${env.CI_DEPLOY_USERNAME} 6 | ${env.CI_DEPLOY_PASSWORD} 7 | 8 | 9 | sonatype-nexus-snapshots 10 | ${env.CI_DEPLOY_USERNAME} 11 | ${env.CI_DEPLOY_PASSWORD} 12 | 13 | 14 | 15 | --------------------------------------------------------------------------------