BlockCommands.java 12 KB

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