diff --git a/src/main/java/com/hbm/handler/neutron/package-info.java b/src/main/java/com/hbm/handler/neutron/package-info.java new file mode 100644 index 000000000..17b5ba872 --- /dev/null +++ b/src/main/java/com/hbm/handler/neutron/package-info.java @@ -0,0 +1,76 @@ +package com.hbm.handler.neutron; + +/* +Hello all, especially Bobcat!! +This very well could be my last contribution here, so let's make it quick (I am 24 vicodin deep and in a majorly depressive state). + +Neutron Nodespace: + The neutron nodespace is a system inspired by the power net nodespace that allows for caching and + calculation of neutron streams from node to node. This is used in both the RBMK and the Chicago Pile, + and is planned to be used in future reactors if needed. + +How actually does the Neutron Nodespace work? + The neutron system is separated into a few different parts: + 1. The Neutron Node World + Neutron node worlds hold, well, the neutron nodes for a world. Each world has its own list, and the + nodes are updated based on their respective adding/removing functions. Only adding nodes is done automatically when a stream + passes through an unregistered node, so unregistering nodes must be done manually. This can also be done using a system + that automatically clears any unused nodes after a certain amount of time, see checkNode() in RBMKNeutronHandler for an example. + + 2. The Neutron Node + Neutron nodes are the actual nodes that interact with neutron streams. These hold a few parameters, + namely the neutron type (held as a NeutronType enum), the position of the node, the TileEntity + the node is encapsulating (optional for blocks), and a special data field. The data field is fully + optional and is mostly used in the RBMK space for holding data about the columns themselves to speed + up grabbing data. This field can hold any sort of data and is meant to be used similar to an NBT storage. + + 3. The Neutron Stream + Neutron streams are where the magic happens (figuratively speaking). Neutron streams can be defined + as a specific type, allowing them only to interact with one type of neutron node. Neutron streams have + a few values, including their origin (in the form of a NeutronNode object), flux quantity, flux ratio, and the + stream vector. The flux quantity and ratio (double 0-1) is a special way of handling the slow/fast flux. The flux ratio can be + calculated by taking the amount of fast flux over the total amount of flux (flux quantity). The amount of fast flux + can be calculated by doing the inverse of this, meaning multiplying the flux quantity by the flux ratio. The slow + flux can be found in nearly the same way, simply by multiplying the flux quantity by one minus the flux ratio. The stream + vector determines the "direction" of the neutron stream, and can be defined as any rotational vector. + The neutron stream class has a few functions that can be used: + 1. Iterator getBlocks(int range): This function returns an iterator over all the blocks in a stream's + path, determined by a given range and the stream's vector. + 2. void runStreamInteraction(World worldObj): This abstract function must be defined in any implementation of the + neutron stream algorithm. This can be seen in the `RBMKNeutronHandler` and the `PileNeutronHandler`. This function + will be run *once* for each and every stream, then they will be removed from the list. + *Each neutron stream only lasts for a single tick in an optimal system.* + +Using the Neutron Nodespace: + Using the neutron nodespace in a new system is not extremely complex, but also requires a few interlocking steps. + New systems should contain a main handler class, normally in the format of nameOfSystemNeutronHandler (see PileNeutronHandler + and RBMKNeutronHandler). This is required to contain at least two things: + 1. Extension of the abstract NeutronStream class. + This is required for the system to operate, as it contains the main code for actually handling the interactions for the stream. + 2. Extension of the abstract NeutronNode class. + This is also required, as this holds the constructor for defining the node type. This can also, optionally, contain special + functions for interfacing with the data field inside the node structure. + + Additional code for handling the streams as they are processed can be placed inside the NeutronHandler class, right above the loop + for processing all the stream interactions. This can be done for optimizing out gamerule checking and the like. + + As mentioned before, the nodes have to be manually destroyed by the TE, normally done within `invalidate()`. + There is also an experimental system for automatically clearing nodes from the nodespace when streams have not passed through + them every second. This can be seen at the end of the onServerTick() function in the NeutronHandler class. Additional + checks for other types can be added here if needed/desired. + +As a final note, this system is potentially way more complicated than it could need to be. +For any extra examples, below is a few files that contain some basic neutron nodespace code that can serve as a base for making new +systems. + +Stream Creation: + 2D Generic stream creation: spreadFlux() in tileentity.machine.rbmk.TileEntityRBMKRod + 2D Non-cardinal direction stream creation: spreadFlux() in tileentity.machine.rbmk.TileEntityRBMKRodReaSim + 3D non-cardinal direction stream creation: castRay() in tileentity.machine.pile.TileEntityPileBase + +Node Management: + Node invalidation: invalidate() in tileentity.machine.rbmk.TileEntityRBMKBase and tileentity.machine.pile.TileEntityPileBase + +See handler.neutron.PileNeutronHandler and handler.neutron.RBMKNeutronHandler for example system handlers. +See handler.neutron.NeutronHandler for the overarching class. +*/ diff --git a/src/main/java/com/hbm/items/block/ItemBlockStorageCrate.java b/src/main/java/com/hbm/items/block/ItemBlockStorageCrate.java index c3d68c3db..1ed2a9d56 100644 --- a/src/main/java/com/hbm/items/block/ItemBlockStorageCrate.java +++ b/src/main/java/com/hbm/items/block/ItemBlockStorageCrate.java @@ -90,16 +90,18 @@ public class ItemBlockStorageCrate extends ItemBlockBase implements IGUIProvider public ItemStack[] slots; public InventoryCrate(EntityPlayer player, ItemStack crate) { + this.player = player; this.crate = crate; slots = new ItemStack[this.getSizeInventory()]; if(crate.stackTagCompound == null) crate.stackTagCompound = new NBTTagCompound(); - else { + else if(!player.worldObj.isRemote) { for (int i = 0; i < this.getSizeInventory(); i++) - this.setInventorySlotContents(i, ItemStack.loadItemStackFromNBT(crate.stackTagCompound.getCompoundTag("slot" + i))); + this.setInventorySlotContents(i, ItemStack.loadItemStackFromNBT(crate.stackTagCompound.getCompoundTag("slot" + i)), false); } + this.markDirty(); } @Nonnull @@ -152,13 +154,18 @@ public class ItemBlockStorageCrate extends ItemBlockBase implements IGUIProvider @Override public void setInventorySlotContents(int slot, ItemStack stack) { + setInventorySlotContents(slot, stack, true); + } + + public void setInventorySlotContents(int slot, ItemStack stack, boolean markDirty) { if(stack != null) { stack.stackSize = Math.min(stack.stackSize, this.getInventoryStackLimit()); } slots[slot] = stack; - markDirty(); + if(markDirty) // This is purely so we don't re-serialize *all* the data when *each* item is loaded during the inventory creation. + markDirty(); } @Override diff --git a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java index 14bff0eb1..92b5ecfe2 100644 --- a/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java +++ b/src/main/java/com/hbm/tileentity/machine/rbmk/TileEntityRBMKRod.java @@ -413,7 +413,7 @@ public class TileEntityRBMKRod extends TileEntityRBMKSlottedBase implements IRBM @Callback(direct = true) @Optional.Method(modid = "OpenComputers") public Object[] getFluxQuantity(Context context, Arguments args) { - return new Object[] {fluxQuantity}; + return new Object[] {lastFluxQuantity}; } @Callback(direct = true) diff --git a/src/main/java/com/hbm/tileentity/network/TileEntityRadioTelex.java b/src/main/java/com/hbm/tileentity/network/TileEntityRadioTelex.java index 3db91ad96..751904a4f 100644 --- a/src/main/java/com/hbm/tileentity/network/TileEntityRadioTelex.java +++ b/src/main/java/com/hbm/tileentity/network/TileEntityRadioTelex.java @@ -302,14 +302,15 @@ public class TileEntityRadioTelex extends TileEntityLoadedBase implements IContr // check if it was never given or if it's an empty string // if it was never given then just assign it as an empty string // this also checks if it's even a string at all - if(args.checkAny(i) == null || args.checkString(i).equals("")) + if(args.checkAny(i) == null || args.checkString(i).isEmpty()) { this.txBuffer[i] = ""; - if(!args.checkString(i).equals("")) { // if it isn't an empty string - if(args.checkString(i).length() > TileEntityRadioTelex.lineWidth) { // line longer than allowed - this.txBuffer[i] = args.checkString(i).substring(0, TileEntityRadioTelex.lineWidth); // truncate it - } else - this.txBuffer[i] = args.checkString(i); // else just set it directly + continue; } + // if it isn't an empty string + if(args.checkString(i).length() > TileEntityRadioTelex.lineWidth) // line longer than allowed + this.txBuffer[i] = args.checkString(i).substring(0, TileEntityRadioTelex.lineWidth); // truncate it + else + this.txBuffer[i] = args.checkString(i); // else just set it directly } return new Object[] {true}; }