BlockCommands.java 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  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.block.material.Material;
  11. import net.minecraft.command.arguments.BlockStateParser;
  12. import net.minecraft.entity.Entity;
  13. import net.minecraft.entity.EntityType;
  14. import net.minecraft.entity.player.ServerPlayerEntity;
  15. import net.minecraft.fluid.Fluids;
  16. import net.minecraft.inventory.IInventory;
  17. import net.minecraft.item.ItemStack;
  18. import net.minecraft.nbt.CompoundNBT;
  19. import net.minecraft.network.play.server.SUpdateTileEntityPacket;
  20. import net.minecraft.state.BooleanProperty;
  21. import net.minecraft.state.EnumProperty;
  22. import net.minecraft.state.IntegerProperty;
  23. import net.minecraft.state.Property;
  24. import net.minecraft.state.properties.ChestType;
  25. import net.minecraft.tags.BlockTags;
  26. import net.minecraft.tags.Tag;
  27. import net.minecraft.tileentity.*;
  28. import net.minecraft.util.Direction;
  29. import net.minecraft.util.ResourceLocation;
  30. import net.minecraft.util.math.BlockPos;
  31. import net.minecraft.util.text.StringTextComponent;
  32. import net.minecraft.world.IWorld;
  33. import net.minecraft.world.World;
  34. public class BlockCommands {
  35. private static class Offset {
  36. private final int x;
  37. private final int y;
  38. private final int z;
  39. public Offset(int x, int y, int z) {
  40. this.x = x;
  41. this.y = y;
  42. this.z = z;
  43. }
  44. }
  45. private static final Offset[] OFFSETS = new Offset[] {
  46. // new Offset(-1, -1, -1),
  47. new Offset(0, -1, -1),
  48. // new Offset(1, -1, -1),
  49. new Offset(-1, 0, -1), new Offset(0, 0, -1), new Offset(1, 0, -1),
  50. // new Offset(-1, 1, -1),
  51. new Offset(0, 1, -1),
  52. // new Offset(1, 1, -1),
  53. new Offset(-1, -1, 0), new Offset(0, -1, 0), new Offset(1, -1, 0), new Offset(-1, 0, 0),
  54. new Offset(0, 0, 0), new Offset(1, 0, 0), new Offset(-1, 1, 0), new Offset(0, 1, 0),
  55. new Offset(1, 1, 0),
  56. // new Offset(-1, -1, 1),
  57. new Offset(0, -1, 1),
  58. // new Offset(1, -1, 1),
  59. new Offset(-1, 0, 1), new Offset(0, 0, 1), new Offset(1, 0, 1),
  60. // new Offset(-1, 1, 1),
  61. new Offset(0, 1, 1), // new Offset(1, 1, 1),
  62. };
  63. @SuppressWarnings({"unchecked", "rawtypes"})
  64. public static void registerFunctions(ScriptManager sm) {
  65. sm.registerFunction("block.gettag", (sc, in) -> BlockTags.getCollection()
  66. .get(new ResourceLocation(in[0].getString(sc))));
  67. sm.registerFunction("block.hastag",
  68. (sc, in) -> ((Tag<Block>) in[0].get(sc)).contains((Block) in[1].get(sc)));
  69. sm.registerFunction("block.gettype", (sc, in) -> {
  70. Location l = (Location) in[0].get(sc);
  71. return l.getWorld().getBlockState(l.getBlockPos()).getBlock().getRegistryName()
  72. .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 =
  83. new BlockPos.Mutable(oldPos.getX(), oldPos.getY(), oldPos.getZ());
  84. int ox = pos.getX();
  85. int oy = pos.getY();
  86. int oz = pos.getZ();
  87. double counter = 0;
  88. for(Offset off : OFFSETS) {
  89. pos.setPos(ox + off.x, oy + off.y, oz + off.z);
  90. if(w.isAirBlock(pos)) {
  91. counter++;
  92. }
  93. }
  94. return counter;
  95. });
  96. sm.registerFunction("block.get", (sc, in) -> {
  97. Location l = (Location) in[0].get(sc);
  98. return l.getWorld().getBlockState(l.getBlockPos()).getBlock();
  99. });
  100. sm.registerFunction("block.getstate", (sc, in) -> {
  101. Location l = (Location) in[0].get(sc);
  102. return l.getWorld().getBlockState(l.getBlockPos());
  103. });
  104. sm.registerFunction("block.getproperties", (sc, in) -> {
  105. Location l = (Location) in[0].get(sc);
  106. return l.getWorld().getBlockState(l.getBlockPos()).getBlock().getStateContainer()
  107. .getProperties();
  108. });
  109. sm.registerFunction("block.getproperty",
  110. (sc, in) -> Mapper.getProperty(in[0].getString(sc)));
  111. sm.registerFunction("block.property.getvalue", (sc, in) -> {
  112. Location l = (Location) in[0].get(sc);
  113. Property<?> prop = (Property) in[1].get(sc);
  114. BlockState state = l.getWorld().getBlockState(l.getBlockPos());
  115. if(state.hasProperty(prop)) {
  116. Object o = l.getWorld().getBlockState(l.getBlockPos()).get(prop);
  117. if(o instanceof Number) {
  118. return ((Number) o).doubleValue();
  119. } else if(o instanceof Boolean) {
  120. return o;
  121. }
  122. return o.toString();
  123. }
  124. return null;
  125. });
  126. sm.registerConsumer("block.property.setint", (sc, in) -> {
  127. Location l = (Location) in[0].get(sc);
  128. World w = l.getWorld();
  129. BlockPos pos = l.getBlockPos();
  130. IntegerProperty prop = (IntegerProperty) in[1].get(sc);
  131. BlockState state = w.getBlockState(pos);
  132. w.setBlockState(pos, state.with(prop, in[2].getInt(sc)), 18);
  133. });
  134. sm.registerConsumer("block.property.setbool", (sc, in) -> {
  135. Location l = (Location) in[0].get(sc);
  136. World w = l.getWorld();
  137. BlockPos pos = l.getBlockPos();
  138. BooleanProperty prop = (BooleanProperty) in[1].get(sc);
  139. BlockState state = w.getBlockState(pos);
  140. w.setBlockState(pos, state.with(prop, in[2].getBoolean(sc)), 18);
  141. });
  142. sm.registerConsumer("block.property.setenum", (sc, in) -> {
  143. Location l = (Location) in[0].get(sc);
  144. World w = l.getWorld();
  145. BlockPos pos = l.getBlockPos();
  146. EnumProperty prop = (EnumProperty) in[1].get(sc);
  147. Enum e = (Enum) prop.parseValue(in[2].getString(sc)).get();
  148. BlockState state = w.getBlockState(pos);
  149. w.setBlockState(pos, state.with(prop, e), 18);
  150. });
  151. sm.registerConsumer("block.clone", (sc, in) -> {
  152. Location l0 = (Location) in[0].get(sc);
  153. Location l1 = (Location) in[1].get(sc);
  154. IWorld w0 = l0.getWorld();
  155. BlockPos pos0 = l0.getBlockPos();
  156. BlockState state = w0.getBlockState(pos0);
  157. TileEntity tileEnt0 = w0.getTileEntity(pos0);
  158. IWorld w1 = l1.getWorld();
  159. BlockPos pos1 = l1.getBlockPos();
  160. w1.setBlockState(pos1, state, 2);
  161. TileEntity tileEnt1 = w1.getTileEntity(pos1);
  162. if(tileEnt0 != null && tileEnt1 != null) {
  163. CompoundNBT nbt = tileEnt0.write(new CompoundNBT());
  164. nbt.putInt("x", pos1.getX());
  165. nbt.putInt("y", pos1.getY());
  166. nbt.putInt("z", pos1.getZ());
  167. tileEnt1.read(w1.getBlockState(pos1), nbt);
  168. tileEnt1.markDirty();
  169. }
  170. });
  171. sm.registerConsumer("block.break", (sc, in) -> {
  172. Location l = (Location) in[0].get(sc);
  173. Entity ent = (Entity) in[1].get(sc);
  174. l.getWorld().destroyBlock(l.getBlockPos(), true, ent);
  175. });
  176. sm.registerConsumer("block.set", (sc, in) -> {
  177. Location l = (Location) in[0].get(sc);
  178. BlockStateParser parser =
  179. new BlockStateParser(new StringReader(in[1].getString(sc)), true);
  180. BlockState state = parser.parse(true).getState();
  181. int flag = 2;
  182. if(in.length >= 3 && in[2].getBoolean(sc)) {
  183. flag |= 16;
  184. }
  185. l.getWorld().setBlockState(l.getBlockPos(), state, flag);
  186. });
  187. sm.registerFunction("block.newstate", (sc, in) -> {
  188. try {
  189. BlockStateParser parser =
  190. new BlockStateParser(new StringReader(in[0].getString(sc)), true);
  191. return parser.parse(true).getState();
  192. } catch(Exception e) {
  193. return null;
  194. }
  195. });
  196. sm.registerConsumer("block.setstate", (sc, in) -> {
  197. Location l = (Location) in[0].get(sc);
  198. int flag = 2;
  199. if(in.length >= 3 && in[2].getBoolean(sc)) {
  200. flag |= 16;
  201. }
  202. l.getWorld().setBlockState(l.getBlockPos(), (BlockState) in[1].get(sc), flag);
  203. });
  204. sm.registerFunction("block.setsign", (sc, in) -> {
  205. Location l = (Location) in[0].get(sc);
  206. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  207. if(te == null || !(te instanceof SignTileEntity)) {
  208. return false;
  209. }
  210. SignTileEntity sign = (SignTileEntity) te;
  211. sign.setText(in[1].getInt(sc), new StringTextComponent(SnuviUtils.connect(sc, in, 2)));
  212. SUpdateTileEntityPacket packet = sign.getUpdatePacket();
  213. l.getWorld().getPlayers()
  214. .forEach(p -> ((ServerPlayerEntity) p).connection.sendPacket(packet));
  215. return true;
  216. });
  217. sm.registerFunction("block.getsign", (sc, in) -> {
  218. Location l = (Location) in[0].get(sc);
  219. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  220. if(te == null || !(te instanceof SignTileEntity)) {
  221. return null;
  222. }
  223. return ReflectionUtils.getSignText((SignTileEntity) te, in[1].getInt(sc)).getString();
  224. });
  225. sm.registerConsumer("block.settrapdoorstatus", (sc, in) -> {
  226. Location l = (Location) in[0].get(sc);
  227. BlockPos pos = l.getBlockPos();
  228. BlockState state = l.getWorld().getBlockState(pos);
  229. World w = l.getWorld();
  230. state = state.with(TrapDoorBlock.OPEN, in[1].getBoolean(sc));
  231. w.setBlockState(pos, state, 2);
  232. if(state.get(TrapDoorBlock.WATERLOGGED)) {
  233. w.getPendingFluidTicks().scheduleTick(pos, Fluids.WATER,
  234. Fluids.WATER.getTickRate(w));
  235. }
  236. Material m = state.getMaterial();
  237. if(state.get(TrapDoorBlock.OPEN)) {
  238. int i = m == Material.IRON ? 1037 : 1007;
  239. w.playEvent(null, i, pos, 0);
  240. } else {
  241. int j = m == Material.IRON ? 1036 : 1013;
  242. w.playEvent(null, j, pos, 0);
  243. }
  244. });
  245. sm.registerFunction("block.gettrapdoorstatus", (sc, in) -> {
  246. Location l = (Location) in[0].get(sc);
  247. return l.getBlockState().get(TrapDoorBlock.OPEN);
  248. });
  249. sm.registerConsumer("block.setdoorstatus", (sc, in) -> {
  250. Location l = (Location) in[0].get(sc);
  251. BlockPos pos = l.getBlockPos();
  252. BlockState state = l.getWorld().getBlockState(pos);
  253. ((DoorBlock) state.getBlock()).openDoor((World) l.getWorld(), state, pos,
  254. in[1].getBoolean(sc));
  255. });
  256. sm.registerFunction("block.getdoorstatus", (sc, in) -> {
  257. Location l = (Location) in[0].get(sc);
  258. return l.getBlockState().get(DoorBlock.OPEN);
  259. });
  260. sm.registerFunction("block.issolid", (sc, in) -> {
  261. return CommandUtils.getBlockState((Location) in[0].get(sc)).isSolid();
  262. });
  263. sm.registerFunction("block.tostack", (sc, in) -> {
  264. Location l = (Location) in[0].get(sc);
  265. return new ItemStack(l.getBlockState().getBlock().asItem());
  266. });
  267. sm.registerFunction("block.getitemamount", (sc, in) -> {
  268. Location l = (Location) in[0].get(sc);
  269. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  270. if(te == null || !(te instanceof ChestTileEntity)) {
  271. return 0.0d;
  272. }
  273. return (double) InventoryUtils.searchInventoryFor((ChestTileEntity) te,
  274. (ItemStack) in[2].get(sc), in[1].getBoolean(sc));
  275. });
  276. sm.registerFunction("block.getsecchest", (sc, in) -> {
  277. Location l = (Location) in[0].get(sc);
  278. BlockPos pos = l.getBlockPos();
  279. BlockState state = l.getWorld().getBlockState(pos);
  280. ChestType chesttype = state.get(ChestBlock.TYPE);
  281. if(chesttype == ChestType.SINGLE) {
  282. return null;
  283. }
  284. Direction dir = ChestBlock.getDirectionToAttached(state);
  285. return l.copyAdd(dir.getXOffset(), dir.getYOffset(), dir.getZOffset());
  286. });
  287. sm.registerFunction("block.additem", (sc, in) -> {
  288. Location l = (Location) in[0].get(sc);
  289. ItemStack stack = ((ItemStack) in[1].get(sc));
  290. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  291. if(te == null || !(te instanceof ChestTileEntity)) {
  292. return stack;
  293. }
  294. stack.setCount(InventoryUtils.addToInventory((ChestTileEntity) te, stack));
  295. return stack;
  296. });
  297. sm.registerFunction("block.subitem", (sc, in) -> {
  298. Location l = (Location) in[0].get(sc);
  299. ItemStack stack = ((ItemStack) in[1].get(sc));
  300. TileEntity te = l.getWorld().getTileEntity(l.getBlockPos());
  301. if(te == null || !(te instanceof ChestTileEntity)) {
  302. return stack;
  303. }
  304. stack.setCount(InventoryUtils.removeFromInventory((ChestTileEntity) te, stack));
  305. return stack;
  306. });
  307. sm.registerConsumer("block.setspawnertype", (sc, in) -> {
  308. Location l = (Location) in[0].get(sc);
  309. MobSpawnerTileEntity spawner =
  310. (MobSpawnerTileEntity) l.getWorld().getTileEntity(l.getBlockPos());
  311. spawner.getSpawnerBaseLogic()
  312. .setEntityType(EntityType.byKey(in[1].getString(sc)).get());
  313. });
  314. sm.registerFunction("block.getinv", (sc, in) -> {
  315. Location l = (Location) in[0].get(sc);
  316. return (IInventory) l.getWorld().getTileEntity(l.getBlockPos());
  317. });
  318. }
  319. }