BlockCommands.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. package me.km.snuviscript.commands;
  2. import com.mojang.brigadier.StringReader;
  3. import me.hammerle.snuviscript.code.ScriptManager;
  4. import me.hammerle.snuviscript.code.SnuviUtils;
  5. import me.km.inventory.InventoryUtils;
  6. import me.km.utils.Location;
  7. import me.km.utils.Mapper;
  8. import me.km.utils.ReflectionUtils;
  9. import net.minecraft.block.*;
  10. import net.minecraft.command.arguments.BlockStateParser;
  11. import net.minecraft.entity.EntityType;
  12. import net.minecraft.entity.player.ServerPlayerEntity;
  13. import net.minecraft.inventory.IInventory;
  14. import net.minecraft.item.ItemStack;
  15. import net.minecraft.nbt.CompoundNBT;
  16. import net.minecraft.network.play.server.SUpdateTileEntityPacket;
  17. import net.minecraft.state.Property;
  18. import net.minecraft.state.properties.ChestType;
  19. import net.minecraft.tags.BlockTags;
  20. import net.minecraft.tags.Tag;
  21. import net.minecraft.tileentity.*;
  22. import net.minecraft.util.Direction;
  23. import net.minecraft.util.ResourceLocation;
  24. import net.minecraft.util.math.BlockPos;
  25. import net.minecraft.util.text.StringTextComponent;
  26. import net.minecraft.world.IWorld;
  27. import net.minecraft.world.World;
  28. public class BlockCommands {
  29. private static class Offset {
  30. private final int x;
  31. private final int y;
  32. private final int z;
  33. public Offset(int x, int y, int z) {
  34. this.x = x;
  35. this.y = y;
  36. this.z = z;
  37. }
  38. }
  39. private static final Offset[] OFFSETS = new Offset[]{
  40. //new Offset(-1, -1, -1),
  41. new Offset(0, -1, -1),
  42. //new Offset(1, -1, -1),
  43. new Offset(-1, 0, -1),
  44. new Offset(0, 0, -1),
  45. new Offset(1, 0, -1),
  46. //new Offset(-1, 1, -1),
  47. new Offset(0, 1, -1),
  48. //new Offset(1, 1, -1),
  49. new Offset(-1, -1, 0),
  50. new Offset(0, -1, 0),
  51. new Offset(1, -1, 0),
  52. new Offset(-1, 0, 0),
  53. new Offset(0, 0, 0),
  54. new Offset(1, 0, 0),
  55. new Offset(-1, 1, 0),
  56. new Offset(0, 1, 0),
  57. new Offset(1, 1, 0),
  58. //new Offset(-1, -1, 1),
  59. new Offset(0, -1, 1),
  60. //new Offset(1, -1, 1),
  61. new Offset(-1, 0, 1),
  62. new Offset(0, 0, 1),
  63. new Offset(1, 0, 1),
  64. //new Offset(-1, 1, 1),
  65. new Offset(0, 1, 1), //new Offset(1, 1, 1),
  66. };
  67. public static void registerFunctions(ScriptManager sm) {
  68. sm.registerFunction("block.gettag", (sc, in) -> BlockTags.getCollection().get(new ResourceLocation(in[0].getString(sc))));
  69. sm.registerFunction("block.hastag", (sc, in) -> ((Tag<Block>) in[0].get(sc)).contains((Block) in[1].get(sc)));
  70. sm.registerFunction("block.gettype", (sc, in) -> {
  71. Location l = (Location) in[0].get(sc);
  72. return l.getWorld().getBlockState(l.getBlockPos()).getBlock().getRegistryName().toString();
  73. });
  74. sm.registerFunction("block.isair", (sc, in) -> {
  75. Location l = (Location) in[0].get(sc);
  76. return l.getWorld().isAirBlock(l.getBlockPos());
  77. });
  78. sm.registerFunction("block.countair", (sc, in) -> {
  79. Location l = (Location) in[0].get(sc);
  80. IWorld w = l.getWorld();
  81. BlockPos oldPos = l.getBlockPos();
  82. BlockPos.Mutable pos = new BlockPos.Mutable(oldPos.getX(), oldPos.getY(), oldPos.getZ());
  83. int ox = pos.getX();
  84. int oy = pos.getY();
  85. int oz = pos.getZ();
  86. double counter = 0;
  87. for(Offset off : OFFSETS) {
  88. pos.setPos(ox + off.x, oy + off.y, oz + off.z);
  89. if(w.isAirBlock(pos)) {
  90. counter++;
  91. }
  92. }
  93. return counter;
  94. });
  95. sm.registerFunction("block.get", (sc, in) -> {
  96. Location l = (Location) in[0].get(sc);
  97. return l.getWorld().getBlockState(l.getBlockPos()).getBlock();
  98. });
  99. sm.registerFunction("block.getproperty", (sc, in) -> Mapper.getProperty(in[0].getString(sc)));
  100. sm.registerFunction("block.getstate", (sc, in) -> {
  101. Location l = (Location) in[0].get(sc);
  102. Property prop = (Property) in[1].get(sc);
  103. BlockState state = l.getWorld().getBlockState(l.getBlockPos());
  104. if(state.hasProperty(prop)) {
  105. Object o = l.getWorld().getBlockState(l.getBlockPos()).get(prop);
  106. if(o instanceof Number) {
  107. return ((Number) o).doubleValue();
  108. } else if(o instanceof Boolean) {
  109. return o;
  110. }
  111. return o.toString();
  112. }
  113. return null;
  114. });
  115. sm.registerConsumer("block.clone", (sc, in) -> {
  116. Location l0 = (Location) in[0].get(sc);
  117. Location l1 = (Location) in[1].get(sc);
  118. IWorld w0 = l0.getWorld();
  119. BlockPos pos0 = l0.getBlockPos();
  120. BlockState state = w0.getBlockState(pos0);
  121. TileEntity tileEnt0 = w0.getTileEntity(pos0);
  122. IWorld w1 = l1.getWorld();
  123. BlockPos pos1 = l1.getBlockPos();
  124. w1.setBlockState(pos1, state, 2);
  125. TileEntity tileEnt1 = w1.getTileEntity(pos1);
  126. if(tileEnt0 != null && tileEnt1 != null) {
  127. CompoundNBT nbt = tileEnt0.write(new CompoundNBT());
  128. nbt.putInt("x", pos1.getX());
  129. nbt.putInt("y", pos1.getY());
  130. nbt.putInt("z", pos1.getZ());
  131. tileEnt1.read(w1.getBlockState(pos1), nbt);
  132. tileEnt1.markDirty();
  133. }
  134. });
  135. sm.registerConsumer("block.set", (sc, in) -> {
  136. Location l = (Location) in[0].get(sc);
  137. BlockStateParser parser = new BlockStateParser(new StringReader(in[1].getString(sc)), true);
  138. BlockState state = parser.parse(true).getState();
  139. int flag = 2;
  140. if(in.length >= 3 && in[2].getBoolean(sc)) {
  141. flag |= 16;
  142. }
  143. l.getWorld().setBlockState(l.getBlockPos(), state, flag);
  144. });
  145. sm.registerFunction("block.newstate", (sc, in) -> {
  146. BlockStateParser parser = new BlockStateParser(new StringReader(in[0].getString(sc)), true);
  147. return parser.parse(true).getState();
  148. });
  149. sm.registerConsumer("block.setstate", (sc, in) -> {
  150. Location l = (Location) in[0].get(sc);
  151. int flag = 2;
  152. if(in.length >= 3 && in[2].getBoolean(sc)) {
  153. flag |= 16;
  154. }
  155. l.getWorld().setBlockState(l.getBlockPos(), (BlockState) in[1].get(sc), flag);
  156. });
  157. sm.registerFunction("block.setsign", (sc, in) -> {
  158. Location l = (Location) in[0].get(sc);
  159. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  160. if(te == null || !(te instanceof SignTileEntity)) {
  161. return false;
  162. }
  163. SignTileEntity sign = (SignTileEntity) te;
  164. sign.setText(in[1].getInt(sc), new StringTextComponent(SnuviUtils.connect(sc, in, 2)));
  165. SUpdateTileEntityPacket packet = sign.getUpdatePacket();
  166. l.getWorld().getPlayers().forEach(p -> ((ServerPlayerEntity) p).connection.sendPacket(packet));
  167. return true;
  168. });
  169. sm.registerFunction("block.getsign", (sc, in) -> {
  170. Location l = (Location) in[0].get(sc);
  171. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  172. if(te == null || !(te instanceof SignTileEntity)) {
  173. return null;
  174. }
  175. return ReflectionUtils.getSignText((SignTileEntity) te, in[1].getInt(sc)).getString();
  176. });
  177. sm.registerConsumer("block.setdoorstatus", (sc, in) -> {
  178. Location l = (Location) in[0].get(sc);
  179. BlockPos pos = l.getBlockPos();
  180. BlockState state = l.getWorld().getBlockState(pos);
  181. ((DoorBlock) state.getBlock()).openDoor((World) l.getWorld(), state, pos, in[1].getBoolean(sc));
  182. });
  183. sm.registerFunction("block.getdoorstatus", (sc, in) -> {
  184. Location l = (Location) in[0].get(sc);
  185. return l.getBlockState().get(DoorBlock.OPEN);
  186. });
  187. sm.registerFunction("block.isdoor", (sc, in) -> {
  188. Location l = (Location) in[0].get(sc);
  189. return l.getWorld().getBlockState(l.getBlockPos()).getBlock() instanceof DoorBlock;
  190. });
  191. sm.registerFunction("block.issolid", (sc, in) -> {
  192. return CommandUtils.getBlockState((Location) in[0].get(sc)).isSolid();
  193. });
  194. sm.registerFunction("block.tostack", (sc, in) -> {
  195. Location l = (Location) in[0].get(sc);
  196. return new ItemStack(l.getBlockState().getBlock().asItem());
  197. });
  198. sm.registerFunction("block.getitemamount", (sc, in) -> {
  199. Location l = (Location) in[0].get(sc);
  200. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  201. if(te == null || !(te instanceof ChestTileEntity)) {
  202. return 0.0d;
  203. }
  204. return (double) InventoryUtils.searchInventoryFor((ChestTileEntity) te, (ItemStack) in[2].get(sc), in[1].getBoolean(sc));
  205. });
  206. sm.registerFunction("block.getsecchest", (sc, in) -> {
  207. Location l = (Location) in[0].get(sc);
  208. BlockPos pos = l.getBlockPos();
  209. BlockState state = l.getWorld().getBlockState(pos);
  210. ChestType chesttype = state.get(ChestBlock.TYPE);
  211. if(chesttype == ChestType.SINGLE) {
  212. return null;
  213. }
  214. Direction dir = ChestBlock.getDirectionToAttached(state);
  215. return l.copyAdd(dir.getXOffset(), dir.getYOffset(), dir.getZOffset());
  216. });
  217. sm.registerFunction("block.additem", (sc, in) -> {
  218. Location l = (Location) in[0].get(sc);
  219. ItemStack stack = ((ItemStack) in[1].get(sc));
  220. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  221. if(te == null || !(te instanceof ChestTileEntity)) {
  222. return stack;
  223. }
  224. stack.setCount(InventoryUtils.addToInventory((ChestTileEntity) te, stack));
  225. return stack;
  226. });
  227. sm.registerFunction("block.subitem", (sc, in) -> {
  228. Location l = (Location) in[0].get(sc);
  229. ItemStack stack = ((ItemStack) in[1].get(sc));
  230. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  231. if(te == null || !(te instanceof ChestTileEntity)) {
  232. return stack;
  233. }
  234. stack.setCount(InventoryUtils.removeFromInventory((ChestTileEntity) te, stack));
  235. return stack;
  236. });
  237. sm.registerConsumer("block.setspawnertype", (sc, in) -> {
  238. Location l = (Location) in[0].get(sc);
  239. MobSpawnerTileEntity spawner = (MobSpawnerTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
  240. spawner.getSpawnerBaseLogic().setEntityType(EntityType.byKey(in[1].getString(sc)).get());
  241. });
  242. sm.registerFunction("block.getinv", (sc, in) -> {
  243. Location l = (Location) in[0].get(sc);
  244. return (IInventory) l.getWorld().getTileEntity(l.getBlockPos());
  245. });
  246. }
  247. }