LivingCommands.java 10 KB

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