LivingCommands.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237
  1. package me.km.snuviscript.commands;
  2. import java.util.UUID;
  3. import me.hammerle.snuviscript.code.ScriptManager;
  4. import me.hammerle.snuviscript.exceptions.StackTrace;
  5. import me.km.scheduler.SnuviScheduler;
  6. import me.km.utils.Location;
  7. import me.km.utils.ReflectionUtils;
  8. import me.km.utils.Utils;
  9. import net.minecraft.entity.Entity;
  10. import net.minecraft.entity.LivingEntity;
  11. import net.minecraft.entity.MobEntity;
  12. import net.minecraft.entity.ai.attributes.Attribute;
  13. import net.minecraft.entity.ai.attributes.AttributeModifier;
  14. import net.minecraft.entity.ai.attributes.ModifiableAttributeInstance;
  15. import net.minecraft.util.DamageSource;
  16. import net.minecraftforge.registries.ForgeRegistries;
  17. import me.km.entities.EntityItemProjectile;
  18. import static me.km.snuviscript.commands.CommandUtils.getNamedClass;
  19. import net.minecraft.entity.item.*;
  20. import net.minecraft.entity.projectile.*;
  21. import net.minecraft.item.ItemStack;
  22. import net.minecraft.util.math.vector.Vector3d;
  23. import net.minecraft.world.World;
  24. import net.minecraft.inventory.EquipmentSlotType;
  25. public class LivingCommands {
  26. private static String getName(Attribute attribute) {
  27. String name = attribute.getAttributeName();
  28. int index = name.lastIndexOf(".");
  29. if(index != -1) {
  30. name = name.substring(index + 1);
  31. }
  32. name = name.replace("_", "");
  33. name = name.toLowerCase();
  34. return name;
  35. }
  36. public static void registerFunctions(ScriptManager sm, SnuviScheduler scheduler) {
  37. for(Attribute attribute : ForgeRegistries.ATTRIBUTES.getValues()) {
  38. String name = getName(attribute);
  39. sm.registerConsumer("living.set" + name, (sc, in) -> {
  40. ModifiableAttributeInstance a =
  41. ((LivingEntity) in[0].get(sc)).getAttribute(attribute);
  42. if(a == null) {
  43. return;
  44. }
  45. double amount = in[1].getDouble(sc) - a.getBaseValue();
  46. UUID uuid = new UUID(name.length(), name.hashCode());
  47. a.removeModifier(uuid);
  48. a.applyNonPersistentModifier(new AttributeModifier(uuid, name, amount,
  49. AttributeModifier.Operation.ADDITION));
  50. });
  51. sm.registerConsumer("living.setpersistent" + name, (sc, in) -> {
  52. ModifiableAttributeInstance a =
  53. ((LivingEntity) in[0].get(sc)).getAttribute(attribute);
  54. if(a == null) {
  55. return;
  56. }
  57. double amount = in[1].getDouble(sc) - a.getBaseValue();
  58. UUID uuid = new UUID(name.length(), name.hashCode());
  59. a.removeModifier(uuid);
  60. a.applyPersistentModifier(new AttributeModifier(uuid, name, amount,
  61. AttributeModifier.Operation.ADDITION));
  62. });
  63. sm.registerFunction("living.get" + name, (sc, in) -> {
  64. ModifiableAttributeInstance a =
  65. ((LivingEntity) in[0].get(sc)).getAttribute(attribute);
  66. return a == null ? null : a.getValue();
  67. });
  68. sm.registerFunction("living.getbase" + name, (sc, in) -> {
  69. ModifiableAttributeInstance a =
  70. ((LivingEntity) in[0].get(sc)).getAttribute(attribute);
  71. return a == null ? null : a.getBaseValue();
  72. });
  73. }
  74. sm.registerConsumer("living.removeai", (sc, in) -> {
  75. LivingEntity ent = (LivingEntity) in[0].get(sc);
  76. if(ent instanceof MobEntity) {
  77. MobEntity mob = (MobEntity) in[0].get(sc);
  78. ReflectionUtils.getGoals(mob.goalSelector).clear();
  79. ReflectionUtils.getGoals(mob.targetSelector).clear();
  80. }
  81. });
  82. sm.registerFunction("living.near", (sc, in) -> {
  83. Object o = in[0].get(sc);
  84. if(o instanceof Location) {
  85. return Utils.getLiving((Location) o, in[1].getDouble(sc));
  86. }
  87. return Utils.getLiving((Entity) o, in[1].getDouble(sc));
  88. });
  89. sm.registerFunction("living.gethealth",
  90. (sc, in) -> (double) ((LivingEntity) in[0].get(sc)).getHealth());
  91. sm.registerConsumer("living.sethealth",
  92. (sc, in) -> ((LivingEntity) in[0].get(sc)).setHealth(in[1].getFloat(sc)));
  93. sm.registerConsumer("living.damage", (sc, in) -> {
  94. LivingEntity liv = (LivingEntity) in[0].get(sc);
  95. float damage = in[1].getFloat(sc);
  96. DamageSource damageSource =
  97. (in.length >= 3) ? (DamageSource) in[2].get(sc) : DamageSource.GENERIC;
  98. StackTrace trace = sc.getStackTrace();
  99. scheduler.scheduleTask("living.damage", () -> {
  100. try {
  101. liv.attackEntityFrom(damageSource, damage);
  102. } catch(Exception ex) {
  103. sc.getScriptManager().getLogger().print(null, ex, "living.damage", sc.getName(),
  104. sc, trace);
  105. }
  106. });
  107. });
  108. sm.registerConsumer("living.heal", (sc, in) -> {
  109. LivingEntity liv = (LivingEntity) in[0].get(sc);
  110. float heal = in[1].getFloat(sc);
  111. StackTrace trace = sc.getStackTrace();
  112. scheduler.scheduleTask("living.heal", () -> {
  113. try {
  114. liv.heal(heal);
  115. } catch(Exception ex) {
  116. sc.getScriptManager().getLogger().print(null, ex, "living.heal", sc.getName(),
  117. sc, trace);
  118. }
  119. });
  120. });
  121. sm.registerFunction("living.shootprojectile",
  122. (sc, in) -> launchProjectile((LivingEntity) in[0].get(sc),
  123. getNamedClass(in[1].getString(sc)), in[2].getDouble(sc),
  124. in.length >= 4 ? in[3].get(sc) : null));
  125. sm.registerFunction("living.isblocking",
  126. (sc, in) -> ((LivingEntity) in[0].get(sc)).isActiveItemStackBlocking());
  127. sm.registerConsumer("living.setequip", (sc, in) -> {
  128. LivingEntity liv = (LivingEntity) in[0].get(sc);
  129. ItemStack stack = ((ItemStack) in[2].get(sc)).copy();
  130. switch(in[1].getString(sc)) {
  131. case "hand":
  132. liv.setItemStackToSlot(EquipmentSlotType.MAINHAND, stack);
  133. return;
  134. case "head":
  135. liv.setItemStackToSlot(EquipmentSlotType.HEAD, stack);
  136. return;
  137. case "chest":
  138. liv.setItemStackToSlot(EquipmentSlotType.CHEST, stack);
  139. return;
  140. case "legs":
  141. liv.setItemStackToSlot(EquipmentSlotType.LEGS, stack);
  142. return;
  143. case "feet":
  144. liv.setItemStackToSlot(EquipmentSlotType.FEET, stack);
  145. return;
  146. case "offhand":
  147. liv.setItemStackToSlot(EquipmentSlotType.OFFHAND, stack);
  148. }
  149. });
  150. sm.registerFunction("living.getequip", (sc, in) -> {
  151. LivingEntity liv = (LivingEntity) in[0].get(sc);
  152. switch(in[1].getString(sc)) {
  153. case "hand":
  154. return liv.getItemStackFromSlot(EquipmentSlotType.MAINHAND);
  155. case "head":
  156. return liv.getItemStackFromSlot(EquipmentSlotType.HEAD);
  157. case "chest":
  158. return liv.getItemStackFromSlot(EquipmentSlotType.CHEST);
  159. case "legs":
  160. return liv.getItemStackFromSlot(EquipmentSlotType.LEGS);
  161. case "feet":
  162. return liv.getItemStackFromSlot(EquipmentSlotType.FEET);
  163. case "offhand":
  164. return liv.getItemStackFromSlot(EquipmentSlotType.OFFHAND);
  165. }
  166. return ItemStack.EMPTY;
  167. });
  168. }
  169. @SuppressWarnings("unchecked")
  170. private static <T> T launchProjectile(LivingEntity liv, Class<? extends T> projectile,
  171. double scale, Object data) {
  172. World w = liv.world;
  173. Entity launch = null;
  174. if(EntityItemProjectile.class == projectile) {
  175. if(data == null) {
  176. throw new NullPointerException("Data musn't be null for EntityItemProjectile");
  177. }
  178. ItemStack stack = (ItemStack) data;
  179. if(stack.isEmpty()) {
  180. throw new IllegalArgumentException("Empty ItemStack not allowed here");
  181. }
  182. launch = new EntityItemProjectile(liv, stack.copy());
  183. ((EntityItemProjectile) launch).setHeadingFromThrower(liv, liv.rotationPitch,
  184. liv.rotationYaw, 0.0f, 1.5f, 1.0f);
  185. } else if(SnowballEntity.class == projectile) {
  186. launch = new SnowballEntity(w, liv);
  187. ((SnowballEntity) launch).shoot(liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
  188. } else if(EggEntity.class == projectile) {
  189. launch = new EggEntity(w, liv);
  190. ((EggEntity) launch).shoot(liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
  191. } else if(EnderPearlEntity.class == projectile) {
  192. launch = new EnderPearlEntity(w, liv);
  193. ((EnderPearlEntity) launch).shoot(liv.rotationPitch, liv.rotationYaw, 0.0f, 1.5f, 1.0f);
  194. } else if(PotionEntity.class == projectile) {
  195. launch = new PotionEntity(w, liv);
  196. ((PotionEntity) launch).setItem((ItemStack) data);
  197. ((PotionEntity) launch).shoot(liv.rotationPitch, liv.rotationYaw, -20.0f, 0.5f, 1.0f);
  198. } else if(ExperienceBottleEntity.class == projectile) {
  199. launch = new ExperienceBottleEntity(w, liv);
  200. ((ExperienceBottleEntity) launch).shoot(liv.rotationPitch, liv.rotationYaw, -20.0f,
  201. 0.7f, 1.0f);
  202. } else if(AbstractArrowEntity.class.isAssignableFrom(projectile)) {
  203. if(SpectralArrowEntity.class == projectile) {
  204. launch = new SpectralArrowEntity(w, liv);
  205. } else {
  206. launch = new ArrowEntity(w, liv);
  207. if(data != null) {
  208. ((ArrowEntity) launch).setPotionEffect((ItemStack) data);
  209. }
  210. }
  211. ((AbstractArrowEntity) launch).shoot(liv.rotationPitch, liv.rotationYaw, 0.0F, 3.0F,
  212. 1.0F);
  213. } else if(DamagingProjectileEntity.class.isAssignableFrom(projectile)) {
  214. Vector3d v = liv.getLookVec().scale(10);
  215. if(SmallFireballEntity.class == projectile) {
  216. launch = new SmallFireballEntity(w, liv, v.x, v.y, v.z);
  217. } else if(WitherSkullEntity.class == projectile) {
  218. launch = new WitherSkullEntity(w, liv, v.x, v.y, v.z);
  219. } else if(DragonFireballEntity.class == projectile) {
  220. launch = new DragonFireballEntity(w, liv, v.x, v.y, v.z);
  221. } else {
  222. launch = new FireballEntity(w, liv, v.x, v.y, v.z);
  223. }
  224. } else {
  225. return null;
  226. }
  227. launch.setMotion(launch.getMotion().scale(scale));
  228. w.addEntity(launch);
  229. return (T) launch;
  230. }
  231. }