PageRenderTime 24ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/src/main/java/crazypants/enderio/machine/tank/TileTank.java

https://gitlab.com/MineYourMind/EnderIO
Java | 400 lines | 347 code | 53 blank | 0 comment | 131 complexity | 0767e48ae67e1836a5fd5d7dc8ff7f10 MD5 | raw file
  1. package crazypants.enderio.machine.tank;
  2. import net.minecraft.init.Items;
  3. import net.minecraft.item.ItemStack;
  4. import net.minecraft.nbt.NBTTagCompound;
  5. import net.minecraft.util.MathHelper;
  6. import net.minecraftforge.common.util.ForgeDirection;
  7. import net.minecraftforge.fluids.Fluid;
  8. import net.minecraftforge.fluids.FluidContainerRegistry;
  9. import net.minecraftforge.fluids.FluidContainerRegistry.FluidContainerData;
  10. import net.minecraftforge.fluids.FluidStack;
  11. import net.minecraftforge.fluids.FluidTankInfo;
  12. import net.minecraftforge.fluids.IFluidHandler;
  13. import crazypants.enderio.machine.AbstractMachineEntity;
  14. import crazypants.enderio.machine.IoMode;
  15. import crazypants.enderio.machine.SlotDefinition;
  16. import crazypants.enderio.network.PacketHandler;
  17. import crazypants.util.BlockCoord;
  18. import crazypants.util.FluidUtil;
  19. public class TileTank extends AbstractMachineEntity implements IFluidHandler {
  20. private static int IO_MB_TICK = 100;
  21. protected FluidTankEio tank;// = new FluidTankEio(16000);
  22. protected int lastUpdateLevel = -1;
  23. private boolean tankDirty = false;
  24. public TileTank(int meta) {
  25. super(new SlotDefinition(0, 1, 2, 3, -1, -1));
  26. if(meta == 1) {
  27. tank = new FluidTankEio(32000);
  28. } else {
  29. tank = new FluidTankEio(16000);
  30. }
  31. }
  32. public TileTank() {
  33. this(0);
  34. }
  35. @Override
  36. protected boolean doPush(ForgeDirection dir) {
  37. if(isSideDisabled(dir.ordinal())) {
  38. return false;
  39. }
  40. boolean res = super.doPush(dir);
  41. if(tank.getFluidAmount() > 0) {
  42. BlockCoord loc = getLocation().getLocation(dir);
  43. IFluidHandler target = FluidUtil.getFluidHandler(worldObj, loc);
  44. if(target != null) {
  45. if(target.canFill(dir.getOpposite(), tank.getFluid().getFluid())) {
  46. FluidStack push = tank.getFluid().copy();
  47. push.amount = Math.min(push.amount, IO_MB_TICK);
  48. int filled = target.fill(dir.getOpposite(), push, true);
  49. if(filled > 0) {
  50. tank.drain(filled, true);
  51. tankDirty = true;
  52. return res;
  53. }
  54. }
  55. }
  56. }
  57. return res;
  58. }
  59. @Override
  60. protected boolean doPull(ForgeDirection dir) {
  61. if(isSideDisabled(dir.ordinal())) {
  62. return false;
  63. }
  64. boolean res = super.doPull(dir);
  65. if(tank.getFluidAmount() < tank.getCapacity()) {
  66. BlockCoord loc = getLocation().getLocation(dir);
  67. IFluidHandler target = FluidUtil.getFluidHandler(worldObj, loc);
  68. if(target != null) {
  69. if(tank.getFluidAmount() > 0) {
  70. FluidStack canPull = tank.getFluid().copy();
  71. canPull.amount = tank.getCapacity() - tank.getFluidAmount();
  72. canPull.amount = Math.min(canPull.amount, IO_MB_TICK);
  73. FluidStack drained = target.drain(dir.getOpposite(), canPull, true);
  74. if(drained != null && drained.amount > 0) {
  75. tank.fill(drained, true);
  76. tankDirty = true;
  77. return res;
  78. }
  79. } else {
  80. FluidTankInfo[] infos = target.getTankInfo(dir.getOpposite());
  81. if(infos != null) {
  82. for (FluidTankInfo info : infos) {
  83. if(info.fluid != null && info.fluid.amount > 0) {
  84. if(canFill(dir, info.fluid.getFluid())) {
  85. FluidStack canPull = info.fluid.copy();
  86. canPull.amount = Math.min(IO_MB_TICK, canPull.amount);
  87. FluidStack drained = target.drain(dir.getOpposite(), canPull, true);
  88. if(drained != null && drained.amount > 0) {
  89. tank.fill(drained, true);
  90. tankDirty = true;
  91. return res;
  92. }
  93. }
  94. }
  95. }
  96. }
  97. }
  98. }
  99. }
  100. return res;
  101. }
  102. @Override
  103. public int fill(ForgeDirection from, FluidStack resource, boolean doFill) {
  104. if(!canFill(from)) {
  105. return 0;
  106. }
  107. return fillInternal(resource, doFill);
  108. }
  109. int fillInternal(FluidStack resource, boolean doFill) {
  110. int res = tank.fill(resource, doFill);
  111. if(res > 0 && doFill) {
  112. tankDirty = true;
  113. }
  114. return res;
  115. }
  116. @Override
  117. public FluidStack drain(ForgeDirection from, FluidStack resource, boolean doDrain) {
  118. if(!canDrain(from)) {
  119. return null;
  120. }
  121. return drainInternal(resource, doDrain);
  122. }
  123. FluidStack drainInternal(FluidStack resource, boolean doDrain) {
  124. FluidStack res = tank.drain(resource, doDrain);
  125. if(res != null && res.amount > 0 && doDrain) {
  126. tankDirty = true;
  127. }
  128. return res;
  129. }
  130. @Override
  131. public FluidStack drain(ForgeDirection from, int maxDrain, boolean doDrain) {
  132. if(!canDrain(from)) {
  133. return null;
  134. }
  135. return drainInternal(maxDrain, doDrain);
  136. }
  137. FluidStack drainInternal(int maxDrain, boolean doDrain) {
  138. FluidStack res = tank.drain(maxDrain, doDrain);
  139. if(res != null && res.amount > 0 && doDrain) {
  140. tankDirty = true;
  141. }
  142. return res;
  143. }
  144. @Override
  145. public boolean canFill(ForgeDirection from, Fluid fluid) {
  146. return canFill(from) && fluid != null && (tank.getFluidAmount() > 0 && tank.getFluid().fluidID == fluid.getID() || tank.getFluidAmount() == 0);
  147. }
  148. private boolean canFill(ForgeDirection from) {
  149. IoMode mode = getIoMode(from);
  150. return mode != IoMode.PUSH && mode != IoMode.DISABLED;
  151. }
  152. @Override
  153. public boolean canDrain(ForgeDirection from, Fluid fluid) {
  154. return canDrain(from) && tank.canDrainFluidType(fluid);
  155. }
  156. private boolean canDrain(ForgeDirection from) {
  157. IoMode mode = getIoMode(from);
  158. return mode != IoMode.PULL && mode != IoMode.DISABLED;
  159. }
  160. @Override
  161. public FluidTankInfo[] getTankInfo(ForgeDirection from) {
  162. return new FluidTankInfo[] { new FluidTankInfo(tank) };
  163. }
  164. private int getFilledLevel() {
  165. int level = (int) Math.floor(16 * tank.getFilledRatio());
  166. if(level == 0 && tank.getFluidAmount() > 0) {
  167. level = 1;
  168. }
  169. return level;
  170. }
  171. @Override
  172. public String getMachineName() {
  173. return "tank";
  174. }
  175. @Override
  176. protected boolean isMachineItemValidForSlot(int i, ItemStack item) {
  177. if(i == 0) {
  178. FluidStack fluid = FluidContainerRegistry.getFluidForFilledItem(item);
  179. if(fluid != null) {
  180. return true;
  181. }
  182. if(item.getItem() == Items.water_bucket) {
  183. return true;
  184. }
  185. if(item.getItem() == Items.lava_bucket) {
  186. return true;
  187. }
  188. return false;
  189. } else if(i == 1) {
  190. return FluidContainerRegistry.isEmptyContainer(item) || item.getItem() == Items.bucket;
  191. }
  192. return false;
  193. }
  194. @Override
  195. public boolean isActive() {
  196. return false;
  197. }
  198. @Override
  199. public float getProgress() {
  200. return 0;
  201. }
  202. @Override
  203. protected boolean processTasks(boolean redstoneCheckPassed) {
  204. boolean res = processItems(redstoneCheckPassed);
  205. int filledLevel = getFilledLevel();
  206. if(lastUpdateLevel != filledLevel) {
  207. lastUpdateLevel = filledLevel;
  208. tankDirty = false;
  209. return true;
  210. }
  211. if(tankDirty && worldObj.getTotalWorldTime() % 10 == 0) {
  212. PacketHandler.sendToAllAround(new PacketTank(this), this);
  213. worldObj.func_147453_f(xCoord, yCoord, zCoord, getBlockType());
  214. tankDirty = false;
  215. }
  216. return res;
  217. }
  218. public int getComparatorOutput() {
  219. FluidTankInfo info = getTankInfo(null)[0];
  220. return info == null || info.fluid == null ? 0 : (int) (((double) info.fluid.amount / (double) info.capacity) * 15);
  221. }
  222. private boolean processItems(boolean redstoneCheckPassed) {
  223. if(!redstoneCheckPassed) {
  224. return false;
  225. }
  226. if(worldObj.getTotalWorldTime() % 20 != 0) {
  227. return false;
  228. }
  229. return drainFullContainer() || fillEmptyContainer();
  230. }
  231. private boolean fillEmptyContainer() {
  232. ItemStack toFill = inventory[1];
  233. if(toFill == null) {
  234. return false;
  235. }
  236. if(tank.getFluidAmount() <= 0) {
  237. return false;
  238. }
  239. ItemStack filledItem = FluidContainerRegistry.fillFluidContainer(tank.getFluid(), toFill);
  240. FluidStack filledFluid = FluidContainerRegistry.getFluidForFilledItem(filledItem);
  241. if(filledFluid == null) { //this shouldn't be necessary but it appears to be a bug as the above method doesnt work
  242. FluidContainerData[] datas = FluidContainerRegistry.getRegisteredFluidContainerData();
  243. for (FluidContainerData data : datas) {
  244. if(data.fluid.getFluid().getName().equals(tank.getFluid().getFluid().getName()) && data.emptyContainer.isItemEqual(toFill)) {
  245. filledItem = data.filledContainer.copy();
  246. filledFluid = FluidContainerRegistry.getFluidForFilledItem(filledItem);
  247. }
  248. }
  249. }
  250. if(filledFluid == null || filledItem == null) {
  251. return false;
  252. }
  253. if(filledFluid.amount > tank.getFluidAmount()) {
  254. return false;
  255. }
  256. if(inventory[3] != null) {
  257. if(!inventory[3].isItemEqual(filledItem) || inventory[3].getMaxStackSize() < inventory[3].stackSize + 1) {
  258. return false; //can't stack the full container
  259. }
  260. }
  261. tank.drain(filledFluid.amount, true);
  262. tankDirty = true;
  263. toFill = toFill.copy();
  264. toFill.stackSize--;
  265. if(toFill.stackSize == 0) {
  266. setInventorySlotContents(1, null);
  267. } else {
  268. setInventorySlotContents(1, toFill);
  269. }
  270. if(inventory[3] == null) {
  271. setInventorySlotContents(3, filledItem);
  272. } else {
  273. ItemStack newStack = inventory[3].copy();
  274. newStack.stackSize++;
  275. setInventorySlotContents(3, newStack);
  276. }
  277. markDirty();
  278. return false;
  279. }
  280. private boolean drainFullContainer() {
  281. ItemStack fillFrom = inventory[0];
  282. if(fillFrom == null) {
  283. return false;
  284. }
  285. FluidStack fluid = FluidUtil.getFluidFromItem(fillFrom);
  286. if(fluid == null) {
  287. return false;
  288. }
  289. ItemStack emptyItem = FluidUtil.getEmptyContainer(fillFrom);
  290. if(emptyItem != null && inventory[2] != null) {
  291. if(!inventory[2].isItemEqual(emptyItem) || inventory[2].getMaxStackSize() < inventory[2].stackSize + 1) {
  292. return false; //can't stack the empty container
  293. }
  294. }
  295. int filled = fillInternal(fluid, false);
  296. if(filled < fluid.amount) {
  297. return false; //can't empty the entire thing
  298. }
  299. fillInternal(fluid, true);
  300. fillFrom = fillFrom.copy();
  301. fillFrom.stackSize--;
  302. if(fillFrom.stackSize == 0) {
  303. setInventorySlotContents(0, null);
  304. } else {
  305. setInventorySlotContents(0, fillFrom);
  306. }
  307. if(emptyItem == null) {
  308. return true;
  309. }
  310. if(inventory[2] == null) {
  311. setInventorySlotContents(2, emptyItem);
  312. } else {
  313. ItemStack newStack = inventory[2].copy();
  314. newStack.stackSize++;
  315. setInventorySlotContents(2, newStack);
  316. }
  317. markDirty();
  318. return false;
  319. }
  320. @Override
  321. public void writeCommon(NBTTagCompound nbtRoot) {
  322. super.writeCommon(nbtRoot);
  323. nbtRoot.setInteger("tankType",getBlockMetadata());
  324. if(tank.getFluidAmount() > 0) {
  325. NBTTagCompound fluidRoot = new NBTTagCompound();
  326. tank.getFluid().writeToNBT(fluidRoot);
  327. nbtRoot.setTag("tankContents", fluidRoot);
  328. }
  329. }
  330. @Override
  331. public void readCommon(NBTTagCompound nbtRoot) {
  332. super.readCommon(nbtRoot);
  333. int tankType = nbtRoot.getInteger("tankType");
  334. tankType = MathHelper.clamp_int(tankType, 0, 1);
  335. if(tankType == 1) {
  336. tank = new FluidTankEio(32000);
  337. } else {
  338. tank = new FluidTankEio(16000);
  339. }
  340. if(nbtRoot.hasKey("tankContents")) {
  341. FluidStack fl = FluidStack.loadFluidStackFromNBT((NBTTagCompound) nbtRoot.getTag("tankContents"));
  342. tank.setFluid(fl);
  343. } else {
  344. tank.setFluid(null);
  345. }
  346. }
  347. }