ScriptEvents.java 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807
  1. package me.km.snuviscript;
  2. import java.util.ArrayList;
  3. import java.util.Arrays;
  4. import java.util.List;
  5. import java.util.Optional;
  6. import java.util.function.Consumer;
  7. import java.util.stream.Collectors;
  8. import me.hammerle.snuviscript.code.Script;
  9. import me.hammerle.snuviscript.code.SnuviUtils;
  10. import me.hammerle.snuviscript.inputprovider.Variable;
  11. import me.kcm.BlockHarvest;
  12. import me.kcm.Craft;
  13. import me.km.utils.Utils;
  14. import me.km.entities.EntityHuman;
  15. import me.km.entities.EntityItemProjectile;
  16. import me.km.events.CommandEvent;
  17. import me.km.inventory.ModInventory;
  18. import me.km.utils.ExplosionUtils;
  19. import me.km.utils.Location;
  20. import net.minecraft.block.Block;
  21. import net.minecraft.block.BlockState;
  22. import net.minecraft.command.ICommandSource;
  23. import net.minecraft.entity.Entity;
  24. import net.minecraft.entity.LivingEntity;
  25. import net.minecraft.entity.player.PlayerEntity;
  26. import net.minecraft.entity.player.ServerPlayerEntity;
  27. import net.minecraft.inventory.CraftResultInventory;
  28. import net.minecraft.inventory.CraftingInventory;
  29. import net.minecraft.inventory.container.ClickType;
  30. import net.minecraft.item.ItemStack;
  31. import net.minecraft.item.crafting.ICraftingRecipe;
  32. import net.minecraft.item.crafting.IRecipeType;
  33. import net.minecraft.network.play.server.SSetSlotPacket;
  34. import net.minecraft.server.MinecraftServer;
  35. import net.minecraft.server.management.PlayerList;
  36. import net.minecraft.tileentity.TileEntity;
  37. import net.minecraft.util.math.*;
  38. import net.minecraft.util.text.ITextComponent;
  39. import net.minecraft.util.text.StringTextComponent;
  40. import net.minecraft.world.GameRules;
  41. import net.minecraft.world.World;
  42. import net.minecraft.world.server.ServerWorld;
  43. import net.minecraft.world.storage.loot.LootContext;
  44. import net.minecraft.world.storage.loot.LootParameters;
  45. import net.minecraftforge.event.ServerChatEvent;
  46. import net.minecraftforge.event.TickEvent;
  47. import net.minecraftforge.event.entity.*;
  48. import net.minecraftforge.event.entity.item.ItemTossEvent;
  49. import net.minecraftforge.event.entity.living.*;
  50. import net.minecraftforge.event.entity.living.LivingEvent.LivingJumpEvent;
  51. import net.minecraftforge.event.entity.player.*;
  52. import net.minecraftforge.event.world.BlockEvent;
  53. import net.minecraftforge.event.world.ExplosionEvent;
  54. import net.minecraftforge.eventbus.api.*;
  55. import net.minecraftforge.event.entity.player.PlayerEvent;
  56. import net.minecraftforge.eventbus.api.Event.Result;
  57. public class ScriptEvents implements BlockHarvest, Craft {
  58. private static void setLivingEntity(Script sc, LivingEntity ent) {
  59. sc.setVar("living_entity", ent);
  60. }
  61. private static void setItem(Script sc, ItemStack stack) {
  62. sc.setVar("item", stack);
  63. }
  64. private static void setPlayer(Script sc, PlayerEntity p) {
  65. sc.setVar("player", p);
  66. }
  67. private final Scripts scripts;
  68. private final MinecraftServer server;
  69. public ScriptEvents(Scripts scripts, MinecraftServer server) {
  70. this.scripts = scripts;
  71. this.server = server;
  72. }
  73. private void handleEvent(Event e, String event, Consumer<Script> before, Consumer<Script> after) {
  74. if(e.isCancelable()) {
  75. scripts.getScriptManager().callEvent(event, sc -> {
  76. if(before != null) {
  77. before.accept(sc);
  78. }
  79. sc.setVar("cancel", e.isCanceled());
  80. }, sc -> {
  81. if(after != null) {
  82. after.accept(sc);
  83. }
  84. handleVar(sc, event, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  85. });
  86. } else {
  87. scripts.getScriptManager().callEvent(event, before, after);
  88. }
  89. }
  90. private void handleEvent(PlayerEntity p, String event, Consumer<Script> before, Consumer<Script> after) {
  91. scripts.getScriptManager().callEvent(event, (sc) -> {
  92. ScriptVars.setPlayerVars(sc, p);
  93. before.accept(sc);
  94. }, after);
  95. if(p != null) {
  96. Script data = scripts.getScript(p);
  97. if(data != null) {
  98. scripts.getScriptManager().callEvent(event, data, (sc) -> {
  99. ScriptVars.setPlayerVars(sc, p);
  100. before.accept(sc);
  101. }, after);
  102. }
  103. }
  104. }
  105. @Deprecated
  106. private void handlePlayerEvent(PlayerEntity p, String event, Consumer<Script> before, Consumer<Script> after) {
  107. if(p != null) {
  108. Script data = scripts.getScript(p);
  109. if(data != null) {
  110. scripts.getScriptManager().callEvent(event, data, (sc) -> {
  111. ScriptVars.setPlayerVars(sc, p);
  112. before.accept(sc);
  113. }, after);
  114. }
  115. }
  116. }
  117. private void handleEvent(PlayerEntity p, String event, Consumer<Script> before) {
  118. handleEvent(p, event, before, null);
  119. }
  120. private void handleVar(Script sc, String event, String name, Consumer<Variable> c) {
  121. try {
  122. ifVarNotNull(sc, name, c);
  123. } catch(Exception ex) {
  124. scripts.getLogger().print(String.format("invalid var in '%s' event", event), ex, null, sc.getName(), sc, sc.getStackTrace());
  125. }
  126. }
  127. private void ifVarNotNull(Script sc, String name, Consumer<Variable> c) {
  128. Variable v = sc.getVar(name);
  129. if(v != null) {
  130. c.accept(v);
  131. }
  132. }
  133. private void simpleCancel(Script sc, Event e, String name) {
  134. try {
  135. ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  136. } catch(Exception ex) {
  137. scripts.getLogger().print(String.format("invalid var in '%s' event", name), ex, null, sc.getName(), sc, sc.getStackTrace());
  138. }
  139. }
  140. public void onPlayerDataTick(PlayerEntity p, String var) {
  141. handleEvent(p, "player_data_tick", sc -> {
  142. sc.setVar("var", var);
  143. });
  144. }
  145. public void onPlayerMove(PlayerEntity p, int id) {
  146. handleEvent(p, "player_move", sc -> {
  147. sc.setVar("id", (double) id);
  148. });
  149. }
  150. public boolean onInventoryClick(Script script, ITextComponent text, ModInventory inv, int slot, ClickType click, PlayerEntity p) {
  151. scripts.getScriptManager().callEvent("inv_click", script, sc -> {
  152. ScriptVars.setPlayerVars(sc, p);
  153. sc.setVar("inv", inv);
  154. sc.setVar("inv_id", (double) inv.getModId());
  155. sc.setVar("inv_name", text.getFormattedText());
  156. sc.setVar("inv_slot", (double) slot);
  157. setItem(sc, inv.getStackInSlot(slot));
  158. sc.setVar("cancel", false);
  159. }, null);
  160. Variable v = script.getVar("cancel");
  161. return v != null && v.getBoolean(script);
  162. }
  163. public void onInventoryClose(Script script, ITextComponent text, ModInventory inv, PlayerEntity p) {
  164. scripts.getScriptManager().callEvent("inv_close", script, sc -> {
  165. ScriptVars.setPlayerVars(sc, p);
  166. sc.setVar("inv", inv);
  167. sc.setVar("inv_id", (double) inv.getModId());
  168. sc.setVar("inv_name", text.getFormattedText());
  169. }, null);
  170. }
  171. public void onHumanHurt(Entity attacker, EntityHuman h) {
  172. handleEvent(null, "human_hurt", sc -> {
  173. ScriptVars.setEntityVars(sc, attacker);
  174. sc.setVar("human", h);
  175. });
  176. }
  177. @SubscribeEvent(receiveCanceled = true)
  178. public void onPlayerPostRespawn(PlayerEvent.PlayerRespawnEvent e) {
  179. handleEvent(e.getPlayer(), "player_post_respawn", sc -> {
  180. });
  181. }
  182. public void onPlayerPreRespawn(PlayerEntity p) {
  183. handleEvent(p, "player_pre_respawn", sc -> {
  184. });
  185. }
  186. @SubscribeEvent(receiveCanceled = true)
  187. public void onOldPlayerDamage(LivingHurtEvent e) {
  188. if(!(e.getEntityLiving() instanceof ServerPlayerEntity)) {
  189. return;
  190. }
  191. PlayerEntity p = (PlayerEntity) e.getEntityLiving();
  192. handleEvent(p, "player_hurt", (sc) -> {
  193. sc.setVar("player_killed", p.getHealth() <= e.getAmount());
  194. sc.setVar("player_damage", (double) e.getAmount());
  195. sc.setVar("player_damage_cause", e.getSource());
  196. PlayerEntity ent = Utils.getDamager(e.getSource());
  197. if(ent != null) {
  198. sc.setVar("player_involved", true);
  199. ScriptVars.setSecPlayer(sc, ent);
  200. } else {
  201. sc.setVar("player_involved", false);
  202. }
  203. sc.setVar("cancel", e.isCanceled());
  204. }, (sc) -> {
  205. try {
  206. ifVarNotNull(sc, "player_damage", v -> e.setAmount(v.getFloat(sc)));
  207. ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  208. } catch(Exception ex) {
  209. scripts.getLogger().print("invalid var in 'player_hurt' event", ex, null, sc.getName(), sc, sc.getStackTrace());
  210. }
  211. });
  212. }
  213. @SubscribeEvent(receiveCanceled = true)
  214. public void onLivingHurt(LivingHurtEvent e) {
  215. handleEvent(e, "living_hurt", (sc) -> {
  216. setLivingEntity(sc, e.getEntityLiving());
  217. sc.setVar("damage_source", e.getSource());
  218. sc.setVar("damage_amount", (double) e.getAmount());
  219. }, (sc) -> {
  220. handleVar(sc, "living_hurt", "damage_amount", v -> e.setAmount(v.getFloat(sc)));
  221. });
  222. }
  223. @SubscribeEvent(receiveCanceled = true)
  224. public void onLivingAttacked(LivingAttackEvent e) {
  225. LivingEntity liv = e.getEntityLiving();
  226. if(liv instanceof PlayerEntity) {
  227. PlayerEntity p = (PlayerEntity) liv;
  228. // deprecated
  229. handleEvent(p, "player_is_attacked", (sc) -> {
  230. sc.setVar("player_killed", p.getHealth() <= e.getAmount());
  231. sc.setVar("player_damage_cause", e.getSource());
  232. PlayerEntity ent = Utils.getDamager(e.getSource());
  233. if(ent != null) {
  234. sc.setVar("player_involved", true);
  235. ScriptVars.setSecPlayer(sc, ent);
  236. } else {
  237. sc.setVar("player_involved", false);
  238. }
  239. sc.setVar("cancel", e.isCanceled());
  240. }, (sc) -> {
  241. simpleCancel(sc, e, "player_is_attacked");
  242. });
  243. }
  244. handleEvent(e, "living_is_attacked", (sc) -> {
  245. setLivingEntity(sc, e.getEntityLiving());
  246. sc.setVar("damage_source", e.getSource());
  247. sc.setVar("damage_amount", (double) e.getAmount());
  248. }, null);
  249. }
  250. @SubscribeEvent(receiveCanceled = true)
  251. public void onLivingHeal(LivingHealEvent e) {
  252. handleEvent(e, "living_heal", (sc) -> {
  253. setLivingEntity(sc, e.getEntityLiving());
  254. sc.setVar("heal_amount", (double) e.getAmount());
  255. }, (sc) -> {
  256. handleVar(sc, "living_heal", "heal_amount", v -> e.setAmount(v.getFloat(sc)));
  257. });
  258. }
  259. @SubscribeEvent(receiveCanceled = true)
  260. public void onLivingDeath(LivingDeathEvent e) {
  261. handleEvent(e, "living_death", (sc) -> {
  262. setLivingEntity(sc, e.getEntityLiving());
  263. sc.setVar("damage_source", e.getSource());
  264. }, null);
  265. if(!(e.getEntityLiving() instanceof PlayerEntity)) {
  266. return;
  267. }
  268. // deprecated
  269. PlayerEntity p = (PlayerEntity) e.getEntity();
  270. handleEvent(p, "player_death", (sc) -> {
  271. sc.setVar("clear", false);
  272. sc.setVar("player_damage_cause", e.getSource());
  273. PlayerEntity ent = Utils.getDamager(e.getSource());
  274. if(ent != null) {
  275. ScriptVars.setSecPlayer(sc, ent);
  276. }
  277. sc.setVar("cancel", e.isCanceled());
  278. }, (sc) -> {
  279. try {
  280. Variable clear = sc.getVar("clear");
  281. if(clear != null && clear.getBoolean(sc)) {
  282. p.inventory.clear();
  283. }
  284. ifVarNotNull(sc, "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  285. } catch(Exception ex) {
  286. scripts.getLogger().print("invalid var in 'player_death' event", ex, null, sc.getName(), sc, sc.getStackTrace());
  287. }
  288. });
  289. }
  290. @SubscribeEvent(receiveCanceled = true)
  291. public void onLivingDrop(LivingDropsEvent e) {
  292. handleEvent(e, "living_drop", (sc) -> {
  293. setLivingEntity(sc, e.getEntityLiving());
  294. sc.setVar("drops", e.getDrops());
  295. sc.setVar("damage_source", e.getSource());
  296. sc.setVar("looting", (double) e.getLootingLevel());
  297. }, null);
  298. }
  299. @SubscribeEvent(receiveCanceled = true)
  300. public void onLivingExperienceDrop(LivingExperienceDropEvent e) {
  301. handleEvent(e, "living_experience_drop", (sc) -> {
  302. setLivingEntity(sc, e.getEntityLiving());
  303. sc.setVar("experience", (double) e.getDroppedExperience());
  304. }, (sc) -> {
  305. handleVar(sc, "living_experience_drop", "experience", v -> e.setDroppedExperience(v.getInt(sc)));
  306. });
  307. }
  308. @SubscribeEvent(receiveCanceled = true)
  309. public void onProjectileHit(ProjectileImpactEvent e) {
  310. final Entity hitEntity;
  311. final Location loc;
  312. RayTraceResult ray = e.getRayTraceResult();
  313. switch(ray.getType()) {
  314. case ENTITY:
  315. hitEntity = ((EntityRayTraceResult) e.getRayTraceResult()).getEntity();
  316. loc = null;
  317. break;
  318. case BLOCK:
  319. loc = new Location(e.getEntity().world, ((BlockRayTraceResult) e.getRayTraceResult()).getPos());
  320. hitEntity = null;
  321. break;
  322. default:
  323. return;
  324. }
  325. handleEvent(e, "projectile_hit", (sc) -> {
  326. sc.setVar("projectile", e.getEntity());
  327. sc.setVar("entity_hit", hitEntity);
  328. sc.setVar("loc_hit", loc);
  329. sc.setVar("shooter", Utils.getEntityFromProjectile(e.getEntity()));
  330. }, null);
  331. }
  332. public void onEntityItemProjectileHit(EntityItemProjectile ent, LivingEntity liv, ItemStack stack, Entity hitEntity, BlockPos pos) {
  333. Location loc = (pos == null) ? null : new Location(ent.world, pos);
  334. handleEvent(null, "item_hit", (sc) -> {
  335. sc.setVar("projectile", ent);
  336. setItem(sc, stack);
  337. sc.setVar("entity_hit", hitEntity);
  338. sc.setVar("loc_hit", loc);
  339. sc.setVar("shooter", liv);
  340. });
  341. // deprecated
  342. if(liv instanceof PlayerEntity) {
  343. handlePlayerEvent((PlayerEntity) liv, "item_hit", (sc) -> {
  344. sc.setVar("projectile", ent);
  345. setItem(sc, stack);
  346. sc.setVar("entity_hit", hitEntity);
  347. sc.setVar("loc_hit", loc);
  348. sc.setVar("shooter", liv);
  349. }, null);
  350. }
  351. }
  352. @Override
  353. public List<ItemStack> onBlockHarvest(BlockState state, ServerWorld w, BlockPos pos, TileEntity tileEnt, Entity ent, ItemStack stack) {
  354. LootContext.Builder loot = new LootContext.Builder(w)
  355. .withRandom(w.getRandom())
  356. .withParameter(LootParameters.POSITION, pos)
  357. .withParameter(LootParameters.TOOL, stack == null ? ItemStack.EMPTY : stack)
  358. .withNullableParameter(LootParameters.THIS_ENTITY, ent)
  359. .withNullableParameter(LootParameters.BLOCK_ENTITY, tileEnt);
  360. List<ItemStack> list = state.getDrops(loot);
  361. try {
  362. final Block b = state.getBlock();
  363. final String name = b.getRegistryName().toString();
  364. scripts.getScriptManager().callEvent("block_drop", sc -> {
  365. sc.setVar("drops", list);
  366. sc.setVar("block_type", name);
  367. sc.setVar("block", b);
  368. sc.setVar("location", new Location(w, pos));
  369. ScriptVars.setEntityVars(sc, ent);
  370. setItem(sc, stack);
  371. }, sc -> {
  372. });
  373. } catch(Exception ex) {
  374. ex.printStackTrace();
  375. }
  376. return list;
  377. }
  378. @SubscribeEvent(receiveCanceled = true)
  379. public void onBlockHarvest(BlockEvent.HarvestDropsEvent e) {
  380. handleEvent(e, "block_harvest", (sc) -> {
  381. setPlayer(sc, e.getHarvester());
  382. sc.setVar("location", new Location(e.getWorld(), e.getPos()));
  383. sc.setVar("drop_chance", (double) e.getDropChance());
  384. sc.setVar("drops", e.getDrops());
  385. sc.setVar("fortune", (double) e.getFortuneLevel());
  386. sc.setVar("silktouch", e.isSilkTouching());
  387. }, (sc) -> {
  388. handleVar(sc, "block_harvest", "drop_chance", v -> e.setDropChance(v.getFloat(sc)));
  389. });
  390. }
  391. @SubscribeEvent(receiveCanceled = true)
  392. public void onBlockBreak(BlockEvent.BreakEvent e) {
  393. handleEvent(e.getPlayer(), "block_break", (sc) -> {
  394. ScriptVars.setBlockVars(sc, e.getWorld(), e.getPos(), e.getState());
  395. sc.setVar("cancel", e.isCanceled());
  396. }, (sc) -> {
  397. simpleCancel(sc, e, "block_break");
  398. });
  399. }
  400. @SubscribeEvent(receiveCanceled = true)
  401. public void onBlockPlace(BlockEvent.EntityPlaceEvent e) {
  402. if(!(e.getEntity() instanceof PlayerEntity)) {
  403. return;
  404. }
  405. handleEvent((PlayerEntity) e.getEntity(), "block_place", (sc) -> {
  406. sc.setVar("block_type_after", e.getPlacedBlock().getBlock().getRegistryName());
  407. ScriptVars.setBlockVars(sc, e.getWorld(), e.getPos(), e.getState());
  408. sc.setVar("cancel", e.isCanceled());
  409. }, (sc) -> {
  410. simpleCancel(sc, e, "block_place");
  411. });
  412. }
  413. @SubscribeEvent(receiveCanceled = true)
  414. public void onPlayerLogin(PlayerEvent.PlayerLoggedInEvent e) {
  415. PlayerEntity p = e.getPlayer();
  416. if(p == null) {
  417. return;
  418. }
  419. handleEvent(p, "player_login", (sc) -> {
  420. PlayerList list = server.getPlayerList();
  421. sc.setVar("is_banned", list.getBannedPlayers().isBanned(p.getGameProfile()));
  422. sc.setVar("is_whitelisted", list.getWhitelistedPlayers().isWhitelisted(p.getGameProfile()));
  423. });
  424. }
  425. @SubscribeEvent(receiveCanceled = true)
  426. public void onPlayerLogout(PlayerEvent.PlayerLoggedOutEvent e) {
  427. PlayerEntity p = e.getPlayer();
  428. if(p == null || e.getPlayer().ticksExisted < 20) {
  429. return;
  430. }
  431. handleEvent(p, "player_logout", sc -> {
  432. });
  433. }
  434. @SubscribeEvent(receiveCanceled = true)
  435. public void onBucketFill(FillBucketEvent e) {
  436. handleEvent(e.getPlayer(), "bucket_use", (sc) -> {
  437. RayTraceResult ray = e.getTarget();
  438. if(ray != null && ray.hitInfo != null && ray.hitInfo instanceof BlockPos) {
  439. BlockPos pos = (BlockPos) ray.hitInfo;
  440. sc.setVar("has_block", true);
  441. ScriptVars.setBlockVars(sc, e.getWorld(), pos);
  442. } else {
  443. sc.setVar("has_block", false);
  444. }
  445. sc.setVar("cancel", e.isCanceled());
  446. }, (sc) -> {
  447. simpleCancel(sc, e, "bucket_use");
  448. });
  449. }
  450. @SubscribeEvent(receiveCanceled = true)
  451. public void onRightClickBlock(PlayerInteractEvent.RightClickBlock e) {
  452. handleEvent(e.getPlayer(), "block_click", (sc) -> {
  453. sc.setVar("action", "right");
  454. sc.setVar("hand", e.getHand().name());
  455. ScriptVars.setBlockVars(sc, e.getWorld(), e.getPos());
  456. sc.setVar("cancel", e.isCanceled());
  457. }, (sc) -> {
  458. simpleCancel(sc, e, "block_click");
  459. });
  460. }
  461. @SubscribeEvent(receiveCanceled = true)
  462. public void onLeftClickBlock(PlayerInteractEvent.LeftClickBlock e) {
  463. handleEvent(e.getPlayer(), "block_click", (sc) -> {
  464. sc.setVar("action", "left");
  465. sc.setVar("hand", e.getHand().name());
  466. ScriptVars.setBlockVars(sc, e.getWorld(), e.getPos());
  467. sc.setVar("cancel", e.isCanceled());
  468. }, (sc) -> {
  469. simpleCancel(sc, e, "block_click");
  470. });
  471. }
  472. @SubscribeEvent(receiveCanceled = true)
  473. public void onEntityClick(PlayerInteractEvent.EntityInteract e) {
  474. handleEvent(e.getPlayer(), "entity_click", (sc) -> {
  475. sc.setVar("hand", e.getHand().name());
  476. ScriptVars.setEntityVars(sc, e.getTarget());
  477. sc.setVar("cancel", e.isCanceled());
  478. }, (sc) -> {
  479. simpleCancel(sc, e, "entity_click");
  480. });
  481. }
  482. public void onEmptyLeftClick(PlayerEntity p) {
  483. handleEvent(p, "left_click_air", (sc) -> {
  484. });
  485. }
  486. @SubscribeEvent(receiveCanceled = true)
  487. public void onItemClick(PlayerInteractEvent.RightClickItem e) {
  488. handleEvent(e.getPlayer(), "item_air_click", (sc) -> {
  489. setItem(sc, e.getItemStack());
  490. sc.setVar("hand", e.getHand().toString());
  491. sc.setVar("cancel", e.isCanceled());
  492. }, (sc) -> {
  493. simpleCancel(sc, e, "item_air_click");
  494. });
  495. }
  496. @SubscribeEvent(receiveCanceled = true)
  497. public void onItemUseStart(LivingEntityUseItemEvent.Start e) {
  498. handleEvent(e, "item_use_start", (sc) -> {
  499. setLivingEntity(sc, e.getEntityLiving());
  500. sc.setVar("duration", (double) e.getDuration());
  501. setItem(sc, e.getItem());
  502. }, (sc) -> {
  503. handleVar(sc, "item_use_start", "duration", v -> e.setDuration(v.getInt(sc)));
  504. });
  505. }
  506. @SubscribeEvent(receiveCanceled = true)
  507. public void onConsuming(LivingEntityUseItemEvent.Finish e) {
  508. handleEvent(e, "item_use_finish", (sc) -> {
  509. setLivingEntity(sc, e.getEntityLiving());
  510. setItem(sc, e.getItem());
  511. sc.setVar("result", e.getResultStack());
  512. }, (sc) -> {
  513. handleVar(sc, "item_use_finish", "result", v -> {
  514. ItemStack stack = (ItemStack) v.get(sc);
  515. if(stack == null) {
  516. e.setResultStack(ItemStack.EMPTY);
  517. } else {
  518. e.setResultStack(stack);
  519. }
  520. });
  521. });
  522. }
  523. @SubscribeEvent(receiveCanceled = true)
  524. public void onFishing(ItemFishedEvent e) {
  525. handleEvent(e.getPlayer(), "fishing", (sc) -> {
  526. sc.setVar("drops", e.getDrops());
  527. sc.setVar("hook", e.getHookEntity());
  528. sc.setVar("rod_damage", (double) e.getRodDamage());
  529. sc.setVar("cancel", e.isCanceled());
  530. }, (sc) -> {
  531. simpleCancel(sc, e, "fishing");
  532. handleVar(sc, "fishing", "rod_damage", v -> e.damageRodBy(v.getInt(sc)));
  533. });
  534. }
  535. @SubscribeEvent(receiveCanceled = true)
  536. public void onCrafting(PlayerEvent.ItemCraftedEvent e) {
  537. handleEvent(e.getPlayer(), "craft", (sc) -> {
  538. setItem(sc, e.getCrafting());
  539. });
  540. }
  541. @SubscribeEvent(receiveCanceled = true)
  542. public void onItemDrop(ItemTossEvent e) {
  543. handleEvent(e.getPlayer(), "player_toss", (sc) -> {
  544. setItem(sc, e.getEntityItem().getItem());
  545. sc.setVar("cancel", e.isCanceled());
  546. }, (sc) -> {
  547. simpleCancel(sc, e, "player_toss");
  548. });
  549. }
  550. @SubscribeEvent(receiveCanceled = true)
  551. public void onItemPickup(EntityItemPickupEvent e) {
  552. handleEvent(e.getPlayer(), "player_pickup", (sc) -> {
  553. ScriptVars.setEntityVars(sc, e.getItem());
  554. setItem(sc, e.getItem().getItem());
  555. sc.setVar("cancel", e.isCanceled());
  556. }, (sc) -> {
  557. simpleCancel(sc, e, "player_pickup");
  558. });
  559. }
  560. @SubscribeEvent(receiveCanceled = true)
  561. public void onEntityMount(EntityMountEvent e) {
  562. handleEvent(e, "entity_mount", (sc) -> {
  563. sc.setVar("mounting", e.isMounting());
  564. ScriptVars.setEntityVars(sc, e.getEntityBeingMounted());
  565. sc.setVar("rider", e.getEntityMounting());
  566. }, null);
  567. }
  568. @SubscribeEvent(receiveCanceled = true)
  569. public void onPlayerUsePortal(PlayerEvent.PlayerChangedDimensionEvent e) {
  570. handleEvent(e.getPlayer(), "portal", (sc) -> {
  571. sc.setVar("from", e.getFrom().getRegistryName().getPath());
  572. sc.setVar("to", e.getTo().getRegistryName().getPath());
  573. });
  574. }
  575. public void onCommand(CommandEvent e) {
  576. handleEvent(e.getPlayer(), "command", (sc) -> {
  577. sc.setVar("command", e.getName());
  578. sc.setVar("cancel", e.isCanceled());
  579. }, (sc) -> {
  580. handleVar(sc, "command", "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  581. });
  582. }
  583. public void onCustomCommand(PlayerEntity p, String command, String[] args) {
  584. handleEvent(p, "custom_command", (sc) -> {
  585. sc.setVar("command", command);
  586. if(args.length == 0) {
  587. sc.setVar("args", new ArrayList<>());
  588. } else {
  589. sc.setVar("args", Arrays.stream(args).map(s -> SnuviUtils.convert(s)).collect(Collectors.toList()));
  590. }
  591. });
  592. }
  593. public void onFunctionKey(ServerPlayerEntity p, int key) {
  594. handleEvent(p, "function_key", (sc) -> {
  595. sc.setVar("key", (double) key);
  596. });
  597. }
  598. @SubscribeEvent(receiveCanceled = true)
  599. public void onChatEvent(ServerChatEvent e) {
  600. handleEvent(e.getPlayer(), "chat", (sc) -> {
  601. sc.setVar("message", e.getMessage());
  602. sc.setVar("cancel", e.isCanceled());
  603. }, (sc) -> {
  604. handleVar(sc, "chat", "message", v -> e.setComponent(new StringTextComponent(v.getString(sc))));
  605. handleVar(sc, "chat", "cancel", v -> e.setCanceled(v.getBoolean(sc)));
  606. });
  607. }
  608. @SubscribeEvent(receiveCanceled = true, priority = EventPriority.HIGHEST)
  609. public void onPreExplosion(ExplosionEvent.Start e) {
  610. e.setCanceled(true);
  611. handleEvent(e, "pre_explosion", sc -> {
  612. sc.setVar("damage_source", e.getExplosion().getDamageSource());
  613. sc.setVar("location", new Location(e.getWorld(), e.getExplosion().getPosition()));
  614. }, null);
  615. }
  616. @SubscribeEvent
  617. public void onExplosion(ExplosionEvent.Detonate e) {
  618. ExplosionUtils.explosion(e.getExplosion(), e.getWorld());
  619. handleEvent(e, "explosion", sc -> {
  620. sc.setVar("affected_blocks", e.getAffectedBlocks());
  621. sc.setVar("affected_entities", e.getAffectedEntities());
  622. sc.setVar("damage_source", e.getExplosion().getDamageSource());
  623. sc.setVar("location", new Location(e.getWorld(), e.getExplosion().getPosition()));
  624. }, null);
  625. }
  626. private static String getName(ICommandSource cs) {
  627. if(cs instanceof PlayerEntity) {
  628. return ((PlayerEntity) cs).getName().getFormattedText();
  629. } else if(cs instanceof MinecraftServer) {
  630. return "Server";
  631. }
  632. return null;
  633. }
  634. public void onMissingCommand(ICommandSource cs, String command) {
  635. PlayerEntity p = null;
  636. if(cs instanceof PlayerEntity) {
  637. p = (PlayerEntity) cs;
  638. }
  639. handleEvent(p, "missing_command", (sc) -> {
  640. sc.setVar("command_name", command);
  641. sc.setVar("sender_name", getName(cs));
  642. });
  643. }
  644. public void onMissingPermission(ICommandSource cs, String command) {
  645. PlayerEntity p = null;
  646. if(cs instanceof PlayerEntity) {
  647. p = (PlayerEntity) cs;
  648. }
  649. handleEvent(p, "missing_perm", (sc) -> {
  650. sc.setVar("command_name", command);
  651. sc.setVar("sender_name", getName(cs));
  652. });
  653. }
  654. @SubscribeEvent(receiveCanceled = true)
  655. public void onEntityJoinWorld(EntityJoinWorldEvent e) {
  656. Entity ent = e.getEntity();
  657. if(!e.getEntity().isPassenger() && !scripts.getEntityLimits().isAllowedToSpawn(ent.getType())) {
  658. e.getEntity().getPassengers().forEach(rider -> {
  659. if(rider == null || rider instanceof PlayerEntity) {
  660. return;
  661. }
  662. rider.remove();
  663. });
  664. e.getEntity().removePassengers();
  665. e.setCanceled(true);
  666. return;
  667. }
  668. handleEvent(e, "entity_join", (sc) -> {
  669. ScriptVars.setEntityVars(sc, ent);
  670. }, null);
  671. }
  672. @SubscribeEvent
  673. public void onServerTick(TickEvent.ServerTickEvent e) {
  674. if(e.phase == TickEvent.Phase.END) {
  675. scripts.getEntityLimits().tick(server.getWorlds());
  676. }
  677. }
  678. @SubscribeEvent(receiveCanceled = true)
  679. public void onAnimalTame(AnimalTameEvent e) {
  680. handleEvent(e, "animal_tame", (sc) -> {
  681. sc.setVar("animal", e.getAnimal());
  682. sc.setVar("tamer", e.getTamer());
  683. }, null);
  684. }
  685. @SubscribeEvent(receiveCanceled = true)
  686. public void onJump(LivingJumpEvent e) {
  687. handleEvent(e, "living_jump", (sc) -> {
  688. setLivingEntity(sc, e.getEntityLiving());
  689. }, null);
  690. }
  691. public void onSneak(PlayerEntity p, boolean sneak) {
  692. handleEvent(p, "player_sneak", (sc) -> {
  693. sc.setVar("sneak", sneak);
  694. }, null);
  695. }
  696. @SubscribeEvent(receiveCanceled = true)
  697. public void onSneak(EntityMobGriefingEvent e) {
  698. handleEvent(e, "mob_griefing", (sc) -> {
  699. ScriptVars.setEntityVars(sc, e.getEntity());
  700. sc.setVar("cancel", !e.getEntity().world.getGameRules().getBoolean(GameRules.MOB_GRIEFING));
  701. }, (sc) -> {
  702. handleVar(sc, "mob_griefing", "cancel", (v) -> {
  703. e.setResult(v.getBoolean(sc) ? Result.DENY : Result.ALLOW);
  704. });
  705. });
  706. }
  707. @Override
  708. public void onCraft(int id, World w, PlayerEntity p, CraftingInventory inv, CraftResultInventory result) {
  709. if(w.isRemote) {
  710. return;
  711. }
  712. ServerPlayerEntity serverplayerentity = (ServerPlayerEntity) p;
  713. Wrapper<ItemStack> wrapper = new Wrapper(ItemStack.EMPTY);
  714. Optional<ICraftingRecipe> optional = w.getServer().getRecipeManager().getRecipe(IRecipeType.CRAFTING, inv, w);
  715. if(optional.isPresent()) {
  716. ICraftingRecipe icraftingrecipe = optional.get();
  717. if(result.canUseRecipe(w, serverplayerentity, icraftingrecipe)) {
  718. wrapper.set(icraftingrecipe.getCraftingResult(inv));
  719. scripts.getScriptManager().callEvent("craft", (sc) -> {
  720. ScriptVars.setPlayerVars(sc, p);
  721. sc.setVar("result", wrapper.get());
  722. }, (sc) -> {
  723. handleVar(sc, "craft", "result", (v) -> {
  724. ItemStack stack = (ItemStack) v.get(sc);
  725. if(stack == null) {
  726. wrapper.set(ItemStack.EMPTY);
  727. } else {
  728. wrapper.set(stack);
  729. }
  730. });
  731. });
  732. }
  733. }
  734. result.setInventorySlotContents(0, wrapper.get());
  735. serverplayerentity.connection.sendPacket(new SSetSlotPacket(id, 0, wrapper.get()));
  736. }
  737. }