Merge branch 'HbmMods:master' into master

This commit is contained in:
arantirnecrolord 2025-06-20 12:07:55 +03:00 committed by GitHub
commit dd5e4e1343
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
57 changed files with 19825 additions and 426 deletions

View File

@ -1,13 +1,41 @@
## Added
* New chemical factory
* New form factor, uses a smaller 5x5 footprint
* Only does four recipes instead of eight
* Double base speed, but also double power draw
* Three upgrade slots, upgrades follow the same rules as on the new chemplant
* Upgrades stack with the double base speed
* Stackable!
* Water consumption rate is fixed at 100mB/t for each active recipe
* Has a dedicated coolant line, so that the coolant water doesn't get used up by recipes
* Coolant line has a tooltip which should make it clear that the machine uses water and produces LPS
* Also has sound, unlike the old chemical factory
* Output fluids are now automatically sent to input tanks, at a rate of up to 50mB/t for somewhat fair fluid sharing
* This means that a chemical factory can make hydrogen peroxide, sulfuric acid and nitric acid, and the only fluid input needed is water
## Changed
* Opening the tool ability configuration menu is now its own keybind instead of using the copy tool's alt keybind + right click
* Cycling though tool abilities is now a custom keybind (still right click by default)
* Removed legacy hardron cooler
* Removed 20hz transformers
* High-octane diesel is now called high-cetane diesel
* The DNT suit now has a damage threshold of 1,000
* Compressed biomass now has a nice cube shape
* The new chemical plant's indicator lights are now functional
* The new chemical plant can now use upgrades
* Reeds now drop sticks when broken
* Switching the recipe in the new chemplant now annihilates residual fluid that is not overwritten by the new recipe
* I don't know why people wanted this, but here you go
* The alternate recipe for oxyhydrogen now uses compressed air instead of nothing
* Improved threaded Mk5, should be a smidge faster now
* Spires no longer progress phases on peaceful difficulty
* Spires now have a 20% chance of coming with instructions
* New chemical plant now has sound
* Old chemical plant and factory have been renamed and their recipes removed
* The new recipe selector no longer changes recipe instantly on click, rather as soon as the selector GUI is closed. This should prevent issues when misclicking, which would destroy buffered fluids
## Fixed
* Fixed new chemical plant ports not initializing their proxies properly
* Fixed chunkloading entities immediately throwing away their loader ticket
* Fixed builder jetpack not resetting flight time properly
* Fixed new chemplant's ferric schrabidate recipe
* Fixed single reload guns reloading multiple rounds at once when having multiple valid ammo stacks
* Chemical plant ports. For real this time.
* Fixed cable and pipe gauges returning the incomplete delta second value for OC and ROR readers
* Fixed new chemical plant not saving power values to disk
* Fixed laser rifle scope texture being missing
* Potentially fixed shift clicking issue with the new chemical plant
* Fixed blowtorch having a minimum gas requirement of 1,000mB despite only using 250mB
* The gas turbine now uses audio with a 20 tick timeout, fixing a rare issue where the loop gets stuck and never ends
* Potentially fixed a dupe caused by using InventoryBogoSorter in combination with crates
* Rapidly spinning dyx should no longer have a state leak that would rotate lighting of unrelated TESRs with it

View File

@ -1008,6 +1008,7 @@ public class ModBlocks {
@Deprecated public static Block machine_chemplant;
public static Block machine_chemical_plant;
public static Block machine_chemfac;
public static Block machine_chemical_factory;
public static Block machine_mixer;
public static Block machine_fluidtank;
@ -2227,6 +2228,7 @@ public class ModBlocks {
machine_chemplant = new MachineChemplant(Material.iron).setBlockName("machine_chemplant").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
machine_chemical_plant = new MachineChemicalPlant(Material.iron).setBlockName("machine_chemical_plant").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
machine_chemfac = new MachineChemfac(Material.iron).setBlockName("machine_chemfac").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
machine_chemical_factory = new MachineChemicalFactory(Material.iron).setBlockName("machine_chemical_factory").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
machine_mixer = new MachineMixer(Material.iron).setBlockName("machine_mixer").setHardness(5.0F).setResistance(30.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
machine_fluidtank = new MachineFluidTank(Material.iron).setBlockName("machine_fluidtank").setHardness(5.0F).setResistance(20.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":machine_fluidtank");
machine_bat9000 = new MachineBigAssTank9000(Material.iron).setBlockName("machine_bat9000").setHardness(5.0F).setResistance(10.0F).setCreativeTab(MainRegistry.machineTab).setBlockTextureName(RefStrings.MODID + ":block_steel");
@ -3267,6 +3269,7 @@ public class ModBlocks {
GameRegistry.registerBlock(machine_chemplant, machine_chemplant.getUnlocalizedName());
register(machine_chemical_plant);
register(machine_chemfac);
register(machine_chemical_factory);
register(machine_arc_welder);
register(machine_soldering_station);
register(machine_arc_furnace);

View File

@ -11,6 +11,7 @@ import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.client.renderer.texture.IIconRegister;
import net.minecraft.init.Blocks;
import net.minecraft.init.Items;
import net.minecraft.item.Item;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.IIcon;
@ -66,7 +67,7 @@ public class BlockReeds extends Block {
@Override
public Item getItemDropped(int meta, Random rand, int fortune) {
return null;
return Items.stick;
}
@Override

View File

@ -81,6 +81,7 @@ public class DungeonSpawner extends BlockContainer {
public static Function<TileEntityDungeonSpawner, Boolean> CON_ABERRATOR = (tile) -> {
World world = tile.getWorldObj();
if(world.difficultySetting.ordinal() == 0) return false;
int x = tile.xCoord;
int y = tile.yCoord;
int z = tile.zCoord;
@ -122,7 +123,11 @@ public class DungeonSpawner extends BlockContainer {
TileEntity te = world.getTileEntity(x, y + 18, z);
if(te instanceof TileEntitySkeletonHolder) {
TileEntitySkeletonHolder skeleton = (TileEntitySkeletonHolder) te;
skeleton.item = new ItemStack(ModItems.item_secret, 1, EnumSecretType.ABERRATOR.ordinal());
if(world.rand.nextInt(5) == 0) {
skeleton.item = new ItemStack(ModItems.item_secret, 1, EnumSecretType.ABERRATOR.ordinal());
} else {
skeleton.item = new ItemStack(ModItems.clay_tablet, 1, 1);
}
skeleton.markDirty();
world.markBlockForUpdate(x, y + 18, z);
}

View File

@ -10,6 +10,7 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
@Deprecated
public class MachineChemfac extends BlockDummyable {
public MachineChemfac(Material mat) {

View File

@ -0,0 +1,88 @@
package com.hbm.blocks.machine;
import java.util.ArrayList;
import java.util.List;
import com.hbm.blocks.BlockDummyable;
import com.hbm.blocks.ILookOverlay;
import com.hbm.blocks.ITooltipProvider;
import com.hbm.tileentity.TileEntityProxyDyn;
import com.hbm.tileentity.machine.TileEntityMachineChemicalFactory;
import com.hbm.util.fauxpointtwelve.DirPos;
import com.hbm.util.i18n.I18nUtil;
import net.minecraft.block.material.Material;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraftforge.client.event.RenderGameOverlayEvent.Pre;
import net.minecraftforge.common.util.ForgeDirection;
public class MachineChemicalFactory extends BlockDummyable implements ITooltipProvider, ILookOverlay {
public MachineChemicalFactory(Material mat) {
super(mat);
}
@Override
public TileEntity createNewTileEntity(World world, int meta) {
if(meta >= 12) return new TileEntityMachineChemicalFactory();
if(meta >= 6) return new TileEntityProxyDyn().inventory().power().fluid();
return null;
}
@Override
public boolean onBlockActivated(World world, int x, int y, int z, EntityPlayer player, int side, float hitX, float hitY, float hitZ) {
return this.standardOpenBehavior(world, x, y, z, player, 0);
}
@Override public int[] getDimensions() { return new int[] {2, 0, 2, 2, 2, 2}; }
@Override public int getOffset() { return 2; }
@Override
public void fillSpace(World world, int x, int y, int z, ForgeDirection dir, int o) {
super.fillSpace(world, x, y, z, dir, o);
x -= dir.offsetX * 2;
z -= dir.offsetZ * 2;
for(int i = -2; i <= 2; i++) for(int j = -2; j <= 2; j++) {
if(Math.abs(i) == 2 || Math.abs(j) == 2) this.makeExtra(world, x + i, y, z + j);
}
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
for(int i = -2; i <= 2; i++) {
this.makeExtra(world, x + dir.offsetX * i + rot.offsetX * 2, y + 2, z + dir.offsetZ * i + rot.offsetZ * 2);
this.makeExtra(world, x + dir.offsetX * i - rot.offsetX * 2, y + 2, z + dir.offsetZ * i - rot.offsetZ * 2);
}
}
@Override
public void addInformation(ItemStack stack, EntityPlayer player, List list, boolean ext) {
this.addStandardInfo(stack, player, list, ext);
}
@Override
public void printHook(Pre event, World world, int x, int y, int z) {
int[] pos = this.findCore(world, x, y, z);
if(pos == null) return;
TileEntity te = world.getTileEntity(pos[0], pos[1], pos[2]);
if(!(te instanceof TileEntityMachineChemicalFactory)) return;
TileEntityMachineChemicalFactory chemfac = (TileEntityMachineChemicalFactory) te;
DirPos[] cool = chemfac.getCoolPos();
for(DirPos dirPos : cool) if(dirPos.compare(x + dirPos.getDir().offsetX, y, z + dirPos.getDir().offsetZ)) {
List<String> text = new ArrayList();
text.add(EnumChatFormatting.GREEN + "-> " + EnumChatFormatting.RESET + chemfac.water.getTankType().getLocalizedName());
text.add(EnumChatFormatting.RED + "<- " + EnumChatFormatting.RESET + chemfac.lps.getTankType().getLocalizedName());
ILookOverlay.printGeneric(event, I18nUtil.resolveKey(getUnlocalizedName() + ".name"), 0xffff00, 0x404000, text);
break;
}
}
}

View File

@ -116,7 +116,7 @@ public class MachineFan extends BlockContainer implements IToolable, ITooltipPro
double coeff = push;
if(!falloff) {
if(falloff) {
double dist = e.getDistance(xCoord + 0.5, yCoord + 0.5, zCoord + 0.5);
coeff *= 1.5 * (1 - dist / range / 2);
}

View File

@ -155,13 +155,13 @@ public class BlockCableGauge extends BlockContainer implements IBlockMultiPass,
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getTransfer(Context context, Arguments args) {
return new Object[] {deltaTick, deltaSecond};
return new Object[] {deltaTick, deltaLastSecond};
}
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getInfo(Context context, Arguments args) {
return new Object[] {deltaTick, deltaSecond, xCoord, yCoord, zCoord};
return new Object[] {deltaTick, deltaLastSecond, xCoord, yCoord, zCoord};
}
@Override
@ -175,7 +175,7 @@ public class BlockCableGauge extends BlockContainer implements IBlockMultiPass,
@Override
public String provideRORValue(String name) {
if((PREFIX_VALUE + "deltatick").equals(name)) return "" + deltaTick;
if((PREFIX_VALUE + "deltasecond").equals(name)) return "" + deltaSecond;
if((PREFIX_VALUE + "deltasecond").equals(name)) return "" + deltaLastSecond;
return null;
}
}

View File

@ -155,7 +155,7 @@ public class FluidDuctGauge extends FluidDuctBase implements IBlockMultiPass, IL
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getTransfer(Context context, Arguments args) {
return new Object[] {deltaTick, deltaSecond};
return new Object[] {deltaTick, deltaLastSecond};
}
@Callback(direct = true)
@ -167,7 +167,7 @@ public class FluidDuctGauge extends FluidDuctBase implements IBlockMultiPass, IL
@Callback(direct = true)
@Optional.Method(modid = "OpenComputers")
public Object[] getInfo(Context context, Arguments args) {
return new Object[] {deltaTick, deltaSecond, getType().getName(), xCoord, yCoord, zCoord};
return new Object[] {deltaTick, deltaLastSecond, getType().getName(), xCoord, yCoord, zCoord};
}
@Override
@ -181,7 +181,7 @@ public class FluidDuctGauge extends FluidDuctBase implements IBlockMultiPass, IL
@Override
public String provideRORValue(String name) {
if((PREFIX_VALUE + "deltatick").equals(name)) return "" + deltaTick;
if((PREFIX_VALUE + "deltasecond").equals(name)) return "" + deltaSecond;
if((PREFIX_VALUE + "deltasecond").equals(name)) return "" + deltaLastSecond;
return null;
}
}

View File

@ -94,7 +94,7 @@ public class BombConfig {
falloutDelayProp.comment = "How many ticks to wait for the next fallout chunk computation";
fDelay = falloutDelayProp.getInt();
chunkloading = CommonConfig.createConfigBool(config, CATEGORY_NUKE, "6.05_enableChunkLoading", "Allows all types of procedural explosions to keep the central chunk loaded.", true);
chunkloading = CommonConfig.createConfigBool(config, CATEGORY_NUKE, "6.05_enableChunkLoading", "Allows all types of procedural explosions to keep the central chunk loaded and to generate new chunks.", true);
explosionAlgorithm = CommonConfig.createConfigInt(config, CATEGORY_NUKE, "6.06_explosionAlgorithm", "Configures the algorithm of mk5 explosion. \n0 = Legacy, 1 = Threaded DDA, 2 = Threaded DDA with damage accumulation.", 2);
}
}

View File

@ -3,8 +3,8 @@ package com.hbm.explosion;
import com.hbm.config.BombConfig;
import com.hbm.interfaces.IExplosionRay;
import com.hbm.main.MainRegistry;
import com.hbm.util.ChunkKey;
import com.hbm.util.ConcurrentBitSet;
import com.hbm.util.SubChunkKey;
import com.hbm.util.SubChunkSnapshot;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
@ -16,16 +16,26 @@ import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import org.apache.logging.log4j.Level;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.DoubleAdder;
import static com.hbm.util.SubChunkSnapshot.getSnapshot;
/**
* Threaded DDA raytracer for mk5 explosion.
*
* @author mlbv
*/
public class ExplosionNukeRayParallelized implements IExplosionRay {
private static final int WORLD_HEIGHT = 256;
private static final int BITSET_SIZE = 16 * WORLD_HEIGHT * 16;
private static final int SUBCHUNK_PER_CHUNK = WORLD_HEIGHT >> 4;
private static final float NUKE_RESISTANCE_CUTOFF = 2_000_000F;
private static final float INITIAL_ENERGY_FACTOR = 0.3F; // Scales crater, no impact on performance
private static final double RESOLUTION_FACTOR = 1.0; // Scales ray density, no impact on crater radius
protected final World world;
private final double explosionX, explosionY, explosionZ;
@ -33,19 +43,19 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
private final int strength;
private final int radius;
private volatile List<Vec3> directions;
private final CompletableFuture<List<Vec3>> directionsFuture;
private final ConcurrentMap<ChunkCoordIntPair, ConcurrentBitSet> destructionMap;
private final ConcurrentMap<ChunkCoordIntPair, ChunkDamageAccumulator> accumulatedDamageMap;
private final ConcurrentMap<ChunkKey, SubChunkSnapshot> snapshots;
private final ConcurrentMap<ChunkCoordIntPair, ConcurrentMap<Integer, DoubleAdder>> damageMap;
private final ConcurrentMap<SubChunkKey, SubChunkSnapshot> snapshots;
private final ConcurrentMap<SubChunkKey, ConcurrentLinkedQueue<RayTask>> waitingRoom;
private final BlockingQueue<RayTask> rayQueue;
private final BlockingQueue<ChunkKey> cacheQueue;
private final ExecutorService pool;
private final CountDownLatch latch;
private final Thread latchWatcherThread;
private final List<ChunkCoordIntPair> orderedChunks;
private final BlockingQueue<SubChunkKey> highPriorityReactiveQueue; // cache queue for rays
private final Iterator<SubChunkKey> lowPriorityProactiveIterator;
private volatile List<Vec3> directions;
private volatile boolean collectFinished = false;
private volatile boolean consolidationFinished = false;
private volatile boolean destroyFinished = false;
@ -63,22 +73,30 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
this.strength = strength;
this.radius = radius;
int rayCount = Math.max(0, (int) (2.5 * Math.PI * strength * strength));
int rayCount = Math.max(0, (int) (2.5 * Math.PI * strength * strength * RESOLUTION_FACTOR));
this.latch = new CountDownLatch(rayCount);
this.destructionMap = new ConcurrentHashMap<>();
this.accumulatedDamageMap = new ConcurrentHashMap<>();
this.snapshots = new ConcurrentHashMap<>();
List<SubChunkKey> sortedSubChunks = getAllSubChunks();
this.lowPriorityProactiveIterator = sortedSubChunks.iterator();
this.highPriorityReactiveQueue = new LinkedBlockingQueue<>();
int initialChunkCapacity = (int) sortedSubChunks.stream().map(SubChunkKey::getPos).distinct().count();
this.destructionMap = new ConcurrentHashMap<>(initialChunkCapacity);
this.damageMap = new ConcurrentHashMap<>(initialChunkCapacity);
int subChunkCount = sortedSubChunks.size();
this.snapshots = new ConcurrentHashMap<>(subChunkCount);
this.waitingRoom = new ConcurrentHashMap<>(subChunkCount);
this.orderedChunks = new ArrayList<>();
this.rayQueue = new LinkedBlockingQueue<>();
this.cacheQueue = new LinkedBlockingQueue<>();
List<RayTask> initialRayTasks = new ArrayList<>(rayCount);
for (int i = 0; i < rayCount; i++) initialRayTasks.add(new RayTask(i));
this.rayQueue = new LinkedBlockingQueue<>(initialRayTasks);
int workers = Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
this.pool = Executors.newWorkStealingPool(workers);
this.directionsFuture = CompletableFuture.supplyAsync(() -> generateSphereRays(rayCount));
for (int i = 0; i < rayCount; i++) rayQueue.add(new RayTask(i));
for (int i = 0; i < workers; i++) pool.submit(new Worker());
this.latchWatcherThread = new Thread(() -> {
@ -88,11 +106,8 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
Thread.currentThread().interrupt();
} finally {
collectFinished = true;
if (BombConfig.explosionAlgorithm == 2) {
pool.submit(this::runConsolidation);
} else {
consolidationFinished = true;
}
if (BombConfig.explosionAlgorithm == 2) pool.submit(this::runConsolidation);
else consolidationFinished = true;
}
}, "ExplosionNuke-LatchWatcher-" + System.nanoTime());
this.latchWatcherThread.setDaemon(true);
@ -102,28 +117,70 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
private static float getNukeResistance(Block b) {
if (b.getMaterial().isLiquid()) return 0.1F;
if (b == Blocks.sandstone) return Blocks.stone.getExplosionResistance(null);
if (b == Blocks.obsidian) return Blocks.stone.getExplosionResistance(null) * 3;
if (b == Blocks.obsidian) return Blocks.stone.getExplosionResistance(null) * 3.0F;
return b.getExplosionResistance(null);
}
private List<SubChunkKey> getAllSubChunks() {
List<SubChunkKey> keys = new ArrayList<>();
int cr = (radius + 15) >> 4;
int minCX = (originX >> 4) - cr;
int maxCX = (originX >> 4) + cr;
int minCZ = (originZ >> 4) - cr;
int maxCZ = (originZ >> 4) + cr;
int minSubY = Math.max(0, (originY - radius) >> 4);
int maxSubY = Math.min(SUBCHUNK_PER_CHUNK - 1, (originY + radius) >> 4);
int originSubY = originY >> 4;
for (int cx = minCX; cx <= maxCX; cx++) {
for (int cz = minCZ; cz <= maxCZ; cz++) {
for (int subY = minSubY; subY <= maxSubY; subY++) {
int chunkCenterX = (cx << 4) + 8;
int chunkCenterY = (subY << 4) + 8;
int chunkCenterZ = (cz << 4) + 8;
double dx = chunkCenterX - explosionX;
double dy = chunkCenterY - explosionY;
double dz = chunkCenterZ - explosionZ;
if (dx * dx + dy * dy + dz * dz <= (radius + 14) * (radius + 14)) { // +14 for margin of error
keys.add(new SubChunkKey(cx, cz, subY));
}
}
}
}
keys.sort(Comparator.comparingInt(key -> {
int distCX = key.getPos().chunkXPos - (originX >> 4);
int distCZ = key.getPos().chunkZPos - (originZ >> 4);
int distSubY = key.getSubY() - originSubY;
return distCX * distCX + distCZ * distCZ + distSubY * distSubY;
}));
return keys;
}
@Override
public void cacheChunksTick(int timeBudgetMs) {
if (collectFinished || this.cacheQueue == null) return;
if (collectFinished) return;
final long deadline = System.nanoTime() + (timeBudgetMs * 1_000_000L);
while (System.nanoTime() < deadline) {
ChunkKey ck = cacheQueue.poll();
SubChunkKey ck = highPriorityReactiveQueue.poll();
if (ck == null) break;
snapshots.computeIfAbsent(ck, key -> {
SubChunkSnapshot snap = getSnapshot(this.world, key.pos, key.subY);
return snap == null ? SubChunkSnapshot.EMPTY : snap;
});
processCacheKey(ck);
}
while (System.nanoTime() < deadline && lowPriorityProactiveIterator.hasNext()) {
SubChunkKey ck = lowPriorityProactiveIterator.next();
processCacheKey(ck);
}
}
private void processCacheKey(SubChunkKey ck) {
if (snapshots.containsKey(ck)) return;
snapshots.put(ck, SubChunkSnapshot.getSnapshot(world, ck, BombConfig.chunkloading));
ConcurrentLinkedQueue<RayTask> waiters = waitingRoom.remove(ck);
if (waiters != null) rayQueue.addAll(waiters);
}
@Override
public void destructionTick(int timeBudgetMs) {
if (!collectFinished || !consolidationFinished || destroyFinished) return; // Added consolidationFinished check
if (!collectFinished || !consolidationFinished || destroyFinished) return;
final long deadline = System.nanoTime() + timeBudgetMs * 1_000_000L;
@ -187,9 +244,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
}
if (bs.isEmpty()) {
destructionMap.remove(cp);
for (int sy = 0; sy < (WORLD_HEIGHT >> 4); sy++) {
snapshots.remove(new ChunkKey(cp.chunkXPos, cp.chunkZPos, sy));
}
for (int subY = 0; subY < SUBCHUNK_PER_CHUNK; subY++) snapshots.remove(new SubChunkKey(cp, subY));
it.remove();
}
}
@ -212,41 +267,31 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
this.destroyFinished = true;
if (this.rayQueue != null) this.rayQueue.clear();
if (this.cacheQueue != null) this.cacheQueue.clear();
if (this.waitingRoom != null) this.waitingRoom.clear();
if (this.latch != null) {
while (this.latch.getCount() > 0) {
this.latch.countDown();
}
}
if (this.latchWatcherThread != null && this.latchWatcherThread.isAlive()) {
this.latchWatcherThread.interrupt();
}
if (this.latch != null) while (this.latch.getCount() > 0) this.latch.countDown();
if (this.latchWatcherThread != null && this.latchWatcherThread.isAlive()) this.latchWatcherThread.interrupt();
if (this.pool != null && !this.pool.isShutdown()) {
this.pool.shutdownNow();
try {
if (!this.pool.awaitTermination(100, TimeUnit.MILLISECONDS)) {
MainRegistry.logger.log(Level.ERROR, "ExplosionNukeRayParallelized thread pool did not terminate promptly on cancel.");
}
if (!this.pool.awaitTermination(100, TimeUnit.MILLISECONDS)) MainRegistry.logger.log(Level.ERROR, "ExplosionNukeRayParallelized thread pool did not terminate promptly on cancel.");
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
if (!this.pool.isShutdown()) {
this.pool.shutdownNow();
}
if (!this.pool.isShutdown()) this.pool.shutdownNow();
}
}
if (this.destructionMap != null) this.destructionMap.clear();
if (this.accumulatedDamageMap != null) this.accumulatedDamageMap.clear();
if (this.damageMap != null) this.damageMap.clear();
if (this.snapshots != null) this.snapshots.clear();
if (this.orderedChunks != null) this.orderedChunks.clear();
}
private List<Vec3> generateSphereRays(int count) {
List<Vec3> list = new ArrayList<>(count);
if (count <= 0) return list;
if (count == 0) return list;
if (count == 1) {
list.add(Vec3.createVectorHelper(1, 0, 0).normalize());
list.add(Vec3.createVectorHelper(1, 0, 0));
return list;
}
double phi = Math.PI * (3.0 - Math.sqrt(5.0));
@ -260,119 +305,66 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
}
private void runConsolidation() {
Iterator<Map.Entry<ChunkCoordIntPair, ChunkDamageAccumulator>> chunkEntryIterator = accumulatedDamageMap.entrySet().iterator();
while (chunkEntryIterator.hasNext()) {
Map.Entry<ChunkCoordIntPair, ChunkDamageAccumulator> entry = chunkEntryIterator.next();
ChunkCoordIntPair cp = entry.getKey();
ChunkDamageAccumulator accumulator = entry.getValue();
if (accumulator.isEmpty()) {
chunkEntryIterator.remove();
continue;
damageMap.forEach((cp, innerDamageMap) -> {
if (innerDamageMap.isEmpty()) {
damageMap.remove(cp);
return;
}
ConcurrentBitSet chunkDestructionBitSet = destructionMap.computeIfAbsent(cp, k -> new ConcurrentBitSet(BITSET_SIZE));
Iterator<Map.Entry<Integer, DoubleAdder>> damageEntryIterator = accumulator.entrySet().iterator();
while (damageEntryIterator.hasNext()) {
Map.Entry<Integer, DoubleAdder> damageEntry = damageEntryIterator.next();
int bitIndex = damageEntry.getKey();
float accumulatedDamage = (float) damageEntry.getValue().sum();
innerDamageMap.forEach((bitIndex, accumulatedDamageAdder) -> {
float accumulatedDamage = (float) accumulatedDamageAdder.sum();
if (accumulatedDamage <= 0.0f) {
damageEntryIterator.remove();
continue;
innerDamageMap.remove(bitIndex);
return;
}
int yGlobal = WORLD_HEIGHT - 1 - (bitIndex >>> 8);
int subY = yGlobal >> 4;
if (subY < 0) {
damageEntryIterator.remove();
continue;
innerDamageMap.remove(bitIndex);
return;
}
ChunkKey snapshotKey = new ChunkKey(cp.chunkXPos, cp.chunkZPos, subY);
SubChunkKey snapshotKey = new SubChunkKey(cp, subY);
SubChunkSnapshot snap = snapshots.get(snapshotKey);
Block originalBlock;
if (snap == null || snap == SubChunkSnapshot.EMPTY) {
damageEntryIterator.remove();
continue;
} else {
int xLocal = (bitIndex >>> 4) & 0xF;
int zLocal = bitIndex & 0xF;
originalBlock = snap.getBlock(xLocal, yGlobal & 0xF, zLocal);
if (originalBlock == Blocks.air) {
damageEntryIterator.remove();
continue;
}
innerDamageMap.remove(bitIndex);
return;
}
int xLocal = (bitIndex >>> 4) & 0xF;
int zLocal = bitIndex & 0xF;
Block originalBlock = snap.getBlock(xLocal, yGlobal & 0xF, zLocal);
if (originalBlock == Blocks.air) {
innerDamageMap.remove(bitIndex);
return;
}
float resistance = getNukeResistance(originalBlock);
if (accumulatedDamage >= resistance) {
chunkDestructionBitSet.set(bitIndex);
damageEntryIterator.remove();
}
}
if (accumulator.isEmpty()) {
chunkEntryIterator.remove();
}
}
accumulatedDamageMap.clear();
if (accumulatedDamage >= resistance * RESOLUTION_FACTOR) chunkDestructionBitSet.set(bitIndex);
innerDamageMap.remove(bitIndex);
});
if (innerDamageMap.isEmpty()) damageMap.remove(cp);
});
damageMap.clear();
consolidationFinished = true;
}
private static class ChunkDamageAccumulator {
// key = bitIndex, value = total accumulated damage
private final ConcurrentHashMap<Integer, DoubleAdder> damageMap = new ConcurrentHashMap<>();
public void addDamage(int bitIndex, float damageAmount) {
if (damageAmount <= 0) return;
DoubleAdder adder = damageMap.computeIfAbsent(bitIndex, k -> new DoubleAdder());
adder.add(damageAmount);
}
/*public float getDamage(int bitIndex) {
DoubleAdder adder = damageMap.get(bitIndex);
return adder == null ? 0f : (float) adder.sum();
}*/
/*public void clearDamage(int bitIndex) {
damageMap.remove(bitIndex);
}*/
public Set<Map.Entry<Integer, DoubleAdder>> entrySet() {
return damageMap.entrySet();
}
public boolean isEmpty() {
return damageMap.isEmpty();
}
}
private class Worker implements Runnable {
@Override
public void run() {
try {
while (true) {
if (collectFinished && rayQueue.isEmpty()) break;
while (!collectFinished && !Thread.currentThread().isInterrupted()) {
RayTask task = rayQueue.poll(100, TimeUnit.MILLISECONDS);
if (task == null) {
if (collectFinished && rayQueue.isEmpty()) break;
continue;
}
task.trace();
if (task != null) task.trace();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
private class RayTask {
private static final double RAY_DIRECTION_EPSILON = 1e-6;
private static final double PROCESSING_EPSILON = 1e-9;
private static final float MIN_EFFECTIVE_DIST_FOR_ENERGY_CALC = 0.01f;
final int dirIndex;
double px, py, pz;
int x, y, z;
@ -382,9 +374,8 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
boolean initialised = false;
double currentRayPosition;
private static final double RAY_DIRECTION_EPSILON = 1e-6;
private static final double PROCESSING_EPSILON = 1e-9;
private static final float MIN_EFFECTIVE_DIST_FOR_ENERGY_CALC = 0.01f;
private int lastCX = Integer.MIN_VALUE, lastCZ = Integer.MIN_VALUE, lastSubY = Integer.MIN_VALUE;
private SubChunkKey currentSubChunkKey = null;
RayTask(int dirIdx) {
this.dirIndex = dirIdx;
@ -393,9 +384,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
void init() {
if (directions == null) directions = directionsFuture.join();
Vec3 dir = directions.get(this.dirIndex);
// This scales the crater. Higher = bigger.
// Currently the crater is a little bit bigger than the original implementation
this.energy = strength * 0.3F;
this.energy = strength * INITIAL_ENERGY_FACTOR;
this.px = explosionX;
this.py = explosionY;
this.pz = explosionZ;
@ -411,20 +400,17 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
double absDirX = Math.abs(dirX);
this.stepX = (absDirX < RAY_DIRECTION_EPSILON) ? 0 : (dirX > 0 ? 1 : -1);
this.tDeltaX = (stepX == 0) ? Double.POSITIVE_INFINITY : 1.0 / absDirX;
this.tMaxX = (stepX == 0) ? Double.POSITIVE_INFINITY :
((stepX > 0 ? (this.x + 1 - this.px) : (this.px - this.x)) * this.tDeltaX);
this.tMaxX = (stepX == 0) ? Double.POSITIVE_INFINITY : ((stepX > 0 ? (this.x + 1 - this.px) : (this.px - this.x)) * this.tDeltaX);
double absDirY = Math.abs(dirY);
this.stepY = (absDirY < RAY_DIRECTION_EPSILON) ? 0 : (dirY > 0 ? 1 : -1);
this.tDeltaY = (stepY == 0) ? Double.POSITIVE_INFINITY : 1.0 / absDirY;
this.tMaxY = (stepY == 0) ? Double.POSITIVE_INFINITY :
((stepY > 0 ? (this.y + 1 - this.py) : (this.py - this.y)) * this.tDeltaY);
this.tMaxY = (stepY == 0) ? Double.POSITIVE_INFINITY : ((stepY > 0 ? (this.y + 1 - this.py) : (this.py - this.y)) * this.tDeltaY);
double absDirZ = Math.abs(dirZ);
this.stepZ = (absDirZ < RAY_DIRECTION_EPSILON) ? 0 : (dirZ > 0 ? 1 : -1);
this.tDeltaZ = (stepZ == 0) ? Double.POSITIVE_INFINITY : 1.0 / absDirZ;
this.tMaxZ = (stepZ == 0) ? Double.POSITIVE_INFINITY :
((stepZ > 0 ? (this.z + 1 - this.pz) : (this.pz - this.z)) * this.tDeltaZ);
this.tMaxZ = (stepZ == 0) ? Double.POSITIVE_INFINITY : ((stepZ > 0 ? (this.z + 1 - this.pz) : (this.pz - this.z)) * this.tDeltaZ);
this.initialised = true;
}
@ -437,15 +423,28 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
}
while (energy > 0) {
if (y < 0 || y >= WORLD_HEIGHT) break;
if (y < 0 || y >= WORLD_HEIGHT || Thread.currentThread().isInterrupted()) break;
if (currentRayPosition >= radius - PROCESSING_EPSILON) break;
ChunkKey ck = new ChunkKey(x >> 4, z >> 4, y >> 4);
SubChunkSnapshot snap = snapshots.get(ck);
int cx = x >> 4;
int cz = z >> 4;
int subY = y >> 4;
if (cx != lastCX || cz != lastCZ || subY != lastSubY) {
currentSubChunkKey = new SubChunkKey(cx, cz, subY);
lastCX = cx;
lastCZ = cz;
lastSubY = subY;
}
SubChunkSnapshot snap = snapshots.get(currentSubChunkKey);
if (snap == null) {
cacheQueue.offer(ck);
rayQueue.offer(this);
final boolean[] amFirst = {false};
ConcurrentLinkedQueue<RayTask> waiters = waitingRoom.computeIfAbsent(currentSubChunkKey, k -> {
amFirst[0] = true;
return new ConcurrentLinkedQueue<>();
});
if (amFirst[0]) highPriorityReactiveQueue.add(currentSubChunkKey);
waiters.add(this);
return;
}
double t_exit_voxel = Math.min(tMaxX, Math.min(tMaxY, tMaxZ));
@ -456,15 +455,13 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
if (this.currentRayPosition + segmentLenInVoxel > radius - PROCESSING_EPSILON) {
segmentLenForProcessing = Math.max(0.0, radius - this.currentRayPosition);
stopAfterThisSegment = true;
} else {
segmentLenForProcessing = segmentLenInVoxel;
}
} else segmentLenForProcessing = segmentLenInVoxel;
if (snap != SubChunkSnapshot.EMPTY && segmentLenForProcessing > PROCESSING_EPSILON) {
Block block = snap.getBlock(x & 0xF, y & 0xF, z & 0xF);
if (block != Blocks.air) {
float resistance = getNukeResistance(block);
if (resistance >= 2_000_000F) { // cutoff
if (resistance >= NUKE_RESISTANCE_CUTOFF) {
energy = 0;
} else {
double energyLossFactor = getEnergyLossFactor(resistance);
@ -472,26 +469,16 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
energy -= damageDealt;
if (damageDealt > 0) {
int bitIndex = ((WORLD_HEIGHT - 1 - y) << 8) | ((x & 0xF) << 4) | (z & 0xF);
ChunkCoordIntPair chunkPos = currentSubChunkKey.getPos();
if (BombConfig.explosionAlgorithm == 2) {
ChunkCoordIntPair chunkPos = ck.pos;
ChunkDamageAccumulator chunkAccumulator =
accumulatedDamageMap.computeIfAbsent(chunkPos, k -> new ChunkDamageAccumulator());
chunkAccumulator.addDamage(bitIndex, damageDealt);
} else {
if (energy > 0) {
ConcurrentBitSet bs = destructionMap.computeIfAbsent(
ck.pos,
posKey -> new ConcurrentBitSet(BITSET_SIZE)
);
bs.set(bitIndex);
}
}
damageMap.computeIfAbsent(chunkPos, cp -> new ConcurrentHashMap<>(256)).computeIfAbsent(bitIndex, k -> new DoubleAdder()).add(damageDealt);
} else if (energy > 0) destructionMap.computeIfAbsent(chunkPos, posKey -> new ConcurrentBitSet(BITSET_SIZE)).set(bitIndex);
}
}
}
}
this.currentRayPosition = t_exit_voxel;
if (energy <= 0 || stopAfterThisSegment || this.currentRayPosition >= radius - PROCESSING_EPSILON) break;
if (energy <= 0 || stopAfterThisSegment) break;
if (tMaxX < tMaxY) {
if (tMaxX < tMaxZ) {
@ -515,15 +502,7 @@ public class ExplosionNukeRayParallelized implements IExplosionRay {
}
private double getEnergyLossFactor(float resistance) {
double dxBlockToCenter = (this.x + 0.5) - explosionX;
double dyBlockToCenter = (this.y + 0.5) - explosionY;
double dzBlockToCenter = (this.z + 0.5) - explosionZ;
double distToBlockCenterSq = dxBlockToCenter * dxBlockToCenter +
dyBlockToCenter * dyBlockToCenter +
dzBlockToCenter * dzBlockToCenter;
double distToBlockCenter = Math.sqrt(distToBlockCenterSq);
double effectiveDist = Math.max(distToBlockCenter, MIN_EFFECTIVE_DIST_FOR_ENERGY_CALC);
double effectiveDist = Math.max(this.currentRayPosition, MIN_EFFECTIVE_DIST_FOR_ENERGY_CALC);
return (Math.pow(resistance + 1.0, 3.0 * (effectiveDist / radius)) - 1.0);
}
}

View File

@ -71,7 +71,8 @@ public class HbmKeybinds {
@SubscribeEvent
public void mouseEvent(MouseInputEvent event) {
HbmPlayerProps props = HbmPlayerProps.getData(MainRegistry.proxy.me());
EntityPlayer player = MainRegistry.proxy.me();
HbmPlayerProps props = HbmPlayerProps.getData(player);
for(EnumKeybind key : EnumKeybind.values()) {
boolean last = props.getKeyPressed(key);
@ -80,6 +81,7 @@ public class HbmKeybinds {
if(last != current) {
PacketDispatcher.wrapper.sendToServer(new KeybindPacket(key, current));
props.setKeyPressed(key, current);
onPressedClient(player, key, current);
}
}
}
@ -87,7 +89,8 @@ public class HbmKeybinds {
@SubscribeEvent
public void keyEvent(KeyInputEvent event) {
EntityPlayer player = MainRegistry.proxy.me();
if (calculatorKey.getIsKeyPressed()) { // handle the calculator client-side only
if(calculatorKey.getIsKeyPressed()) { // handle the calculator client-side only
player.closeScreen();
FMLCommonHandler.instance().showGuiScreen(new GUICalculator());
}

View File

@ -31,6 +31,12 @@ public class ContainerBase extends Container {
public boolean canInteractWith(EntityPlayer player) {
return tile.isUseableByPlayer(player);
}
/** Respects slot restrictions */
@Override
protected boolean mergeItemStack(ItemStack slotStack, int start, int end, boolean direction) {
return super.mergeItemStack(slotStack, start, end, direction); // overriding this with InventoryUtil.mergeItemStack breaks it but invoking it directly doesn't? wtf?
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index) {
@ -89,7 +95,10 @@ public class ContainerBase extends Container {
* @param from the slot index to start from
*/
public void addSlots(IInventory inv, int from, int x, int y, int rows, int cols) {
int slotSize = 18;
addSlots(inv, from, x, y, rows, cols, 18);
}
public void addSlots(IInventory inv, int from, int x, int y, int rows, int cols, int slotSize) {
for(int row = 0; row < rows; row++) {
for(int col = 0; col < cols; col++) {
this.addSlotToContainer(new SlotNonRetarded(inv, col + row * cols + from, x + col * slotSize, y + row * slotSize));
@ -98,14 +107,20 @@ public class ContainerBase extends Container {
}
public void addOutputSlots(EntityPlayer player, IInventory inv, int from, int x, int y, int rows, int cols) {
int slotSize = 18;
addOutputSlots(player, inv, from, x, y, rows, cols, 18);
}
public void addOutputSlots(EntityPlayer player, IInventory inv, int from, int x, int y, int rows, int cols, int slotSize) {
for(int row = 0; row < rows; row++) for(int col = 0; col < cols; col++) {
this.addSlotToContainer(new SlotCraftingOutput(player, inv, col + row * cols + from, x + col * slotSize, y + row * slotSize));
}
}
public void addTakeOnlySlots(IInventory inv, int from, int x, int y, int rows, int cols) {
int slotSize = 18;
addTakeOnlySlots(inv, from, x, y, rows, cols, 18);
}
public void addTakeOnlySlots(IInventory inv, int from, int x, int y, int rows, int cols, int slotSize) {
for(int row = 0; row < rows; row++) for(int col = 0; col < cols; col++) {
this.addSlotToContainer(new SlotTakeOnly(inv, col + row * cols + from, x + col * slotSize, y + row * slotSize));
}

View File

@ -24,7 +24,7 @@ public class ContainerCrateBase extends ContainerBase {
}
for(int i = 0; i < 9; i++) {
this.addSlotToContainer(new SlotNonRetarded(invPlayer, i, playerInvX + i * 18, playerHotbarY));
this.addSlotToContainer(new SlotPlayerCrate(invPlayer, i, playerInvX + i * 18, playerHotbarY));
}
}
@ -67,5 +67,11 @@ public class ContainerCrateBase extends ContainerBase {
return false;
return super.canTakeStack(player);
}
@Override
public boolean isItemValid(ItemStack item) {
if(ItemStack.areItemStacksEqual(getStack(), item)) return false;
return super.isItemValid(item);
}
}
}

View File

@ -0,0 +1,77 @@
package com.hbm.inventory.container;
import com.hbm.inventory.SlotCraftingOutput;
import com.hbm.inventory.SlotNonRetarded;
import com.hbm.items.ModItems;
import com.hbm.items.machine.ItemMachineUpgrade;
import com.hbm.util.InventoryUtil;
import api.hbm.energymk2.IBatteryItem;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.IInventory;
import net.minecraft.inventory.Slot;
import net.minecraft.item.ItemStack;
public class ContainerMachineChemicalFactory extends ContainerBase {
public ContainerMachineChemicalFactory(InventoryPlayer invPlayer, IInventory chemicalPlant) {
super(invPlayer, chemicalPlant);
// Battery
this.addSlotToContainer(new SlotNonRetarded(chemicalPlant, 0, 224, 88));
// Upgrades
this.addSlots(chemicalPlant, 1, 206, 125, 3, 1);
for(int i = 0; i < 4; i++) {
// Template
this.addSlots(chemicalPlant, 4 + i * 7, 93, 20 + i * 22, 1, 1, 16);
// Solid Input
this.addSlots(chemicalPlant, 5 + i * 7, 10, 20 + i * 22, 1, 3, 16);
// Solid Output
this.addOutputSlots(invPlayer.player, chemicalPlant, 8 + i * 7, 139, 20 + i * 22, 1, 3, 16);
}
this.playerInv(invPlayer, 26, 134);
}
@Override
public ItemStack transferStackInSlot(EntityPlayer player, int index) {
ItemStack slotOriginal = null;
Slot slot = (Slot) this.inventorySlots.get(index);
if(slot != null && slot.getHasStack()) {
ItemStack slotStack = slot.getStack();
slotOriginal = slotStack.copy();
if(index <= tile.getSizeInventory() - 1) {
SlotCraftingOutput.checkAchievements(player, slotStack);
if(!this.mergeItemStack(slotStack, tile.getSizeInventory(), this.inventorySlots.size(), true)) {
return null;
}
} else {
if(slotOriginal.getItem() instanceof IBatteryItem || slotOriginal.getItem() == ModItems.battery_creative) {
if(!this.mergeItemStack(slotStack, 0, 1, false)) return null;
} else if(slotOriginal.getItem() instanceof ItemMachineUpgrade) {
if(!this.mergeItemStack(slotStack, 1, 4, false)) return null;
} else {
if(!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 5, 8, false) &&
!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 12, 15, false) &&
!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 19, 22, false) &&
!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 26, 29, false)) return null;
}
}
if(slotStack.stackSize == 0) {
slot.putStack(null);
} else {
slot.onSlotChanged();
}
slot.onPickupFromSlot(player, slotStack);
}
return slotOriginal;
}
}

View File

@ -5,6 +5,7 @@ import com.hbm.inventory.SlotNonRetarded;
import com.hbm.items.ModItems;
import com.hbm.items.machine.ItemChemistryTemplate;
import com.hbm.items.machine.ItemMachineUpgrade;
import com.hbm.util.InventoryUtil;
import api.hbm.energymk2.IBatteryItem;
import net.minecraft.entity.player.EntityPlayer;
@ -61,7 +62,7 @@ public class ContainerMachineChemicalPlant extends ContainerBase {
} else if(slotOriginal.getItem() instanceof ItemMachineUpgrade) {
if(!this.mergeItemStack(slotStack, 2, 4, false)) return null;
} else {
if(!this.mergeItemStack(slotStack, 4, 7, false)) return null;
if(!InventoryUtil.mergeItemStack(this.inventorySlots, slotStack, 4, 7, false)) return null;
}
}

View File

@ -65,6 +65,12 @@ public class FluidTank implements Cloneable {
this.setFill(0);
}
public void resetTank() {
this.type = Fluids.NONE;
this.fluid = 0;
this.pressure = 0;
}
/** Changes type and pressure based on a fluid stack, useful for changing tank types based on recipes */
public FluidTank conform(FluidStack stack) {
this.setTankType(stack.type);

View File

@ -0,0 +1,138 @@
package com.hbm.inventory.gui;
import org.lwjgl.opengl.GL11;
import com.hbm.inventory.container.ContainerMachineChemicalFactory;
import com.hbm.inventory.recipes.ChemicalPlantRecipes;
import com.hbm.inventory.recipes.loader.GenericRecipe;
import com.hbm.lib.RefStrings;
import com.hbm.tileentity.machine.TileEntityMachineChemicalFactory;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.OpenGlHelper;
import net.minecraft.client.resources.I18n;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Slot;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.util.ResourceLocation;
public class GUIMachineChemicalFactory extends GuiInfoContainer {
private static ResourceLocation texture = new ResourceLocation(RefStrings.MODID + ":textures/gui/processing/gui_chemical_factory.png");
private TileEntityMachineChemicalFactory chemplant;
public GUIMachineChemicalFactory(InventoryPlayer invPlayer, TileEntityMachineChemicalFactory tedf) {
super(new ContainerMachineChemicalFactory(invPlayer, tedf));
chemplant = tedf;
this.xSize = 248;
this.ySize = 216;
}
@Override
public void drawScreen(int mouseX, int mouseY, float f) {
super.drawScreen(mouseX, mouseY, f);
for(int i = 0; i < 3; i++) for(int j = 0; j < 4; j++) {
chemplant.inputTanks[i + j * 3].renderTankInfo(this, mouseX, mouseY, guiLeft + 60 + i * 5, guiTop + 20 + j * 22, 3, 16);
chemplant.outputTanks[i + j * 3].renderTankInfo(this, mouseX, mouseY, guiLeft + 189 + i * 5, guiTop + 20 + j * 22, 3, 16);
}
chemplant.water.renderTankInfo(this, mouseX, mouseY, guiLeft + 224, guiTop + 125, 7, 52);
chemplant.lps.renderTankInfo(this, mouseX, mouseY, guiLeft + 233, guiTop + 125, 7, 52);
this.drawElectricityInfo(this, mouseX, mouseY, guiLeft + 224, guiTop + 18, 16, 68, chemplant.power, chemplant.maxPower);
for(int i = 0; i < 4; i++) if(guiLeft + 74 <= mouseX && guiLeft + 74 + 18 > mouseX && guiTop + 19 + i * 22 < mouseY && guiTop + 19 + i * 22 + 18 >= mouseY) {
if(this.chemplant.chemplantModule[i].recipe != null && ChemicalPlantRecipes.INSTANCE.recipeNameMap.containsKey(this.chemplant.chemplantModule[i].recipe)) {
GenericRecipe recipe = (GenericRecipe) ChemicalPlantRecipes.INSTANCE.recipeNameMap.get(this.chemplant.chemplantModule[i].recipe);
this.func_146283_a(recipe.print(), mouseX, mouseY);
} else {
this.drawCreativeTabHoveringText(EnumChatFormatting.YELLOW + "Click to set recipe", mouseX, mouseY);
}
}
}
@Override
protected void mouseClicked(int x, int y, int button) {
super.mouseClicked(x, y, button);
for(int i = 0; i < 4; i++) if(this.checkClick(x, y, 74, 19 + i * 22, 18, 18)) GUIScreenRecipeSelector.openSelector(ChemicalPlantRecipes.INSTANCE, chemplant, chemplant.chemplantModule[i].recipe, i, this);
}
@Override
protected void drawGuiContainerForegroundLayer(int i, int j) {
String name = this.chemplant.hasCustomInventoryName() ? this.chemplant.getInventoryName() : I18n.format(this.chemplant.getInventoryName());
this.fontRendererObj.drawString(name, 106 - this.fontRendererObj.getStringWidth(name) / 2, 6, 4210752);
this.fontRendererObj.drawString(I18n.format("container.inventory"), 26, this.ySize - 96 + 2, 4210752);
}
@Override
protected void drawGuiContainerBackgroundLayer(float p_146976_1_, int p_146976_2_, int p_146976_3_) {
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
drawTexturedModalRect(guiLeft, guiTop, 0, 0, 248, 116);
drawTexturedModalRect(guiLeft + 18, guiTop + 116, 18, 116, 230, 100);
int p = (int) (chemplant.power * 68 / chemplant.maxPower);
drawTexturedModalRect(guiLeft + 224, guiTop + 86 - p, 0, 184 - p, 16, p);
for(int i = 0; i < 4; i++) if(chemplant.chemplantModule[i].progress > 0) {
int j = (int) Math.ceil(22 * chemplant.chemplantModule[i].progress);
drawTexturedModalRect(guiLeft + 113, guiTop + 29 + i * 22, 0, 216, j, 6);
}
for(int g = 0; g < 4; g++) {
GenericRecipe recipe = ChemicalPlantRecipes.INSTANCE.recipeNameMap.get(chemplant.chemplantModule[g].recipe);
/// LEFT LED
if(chemplant.didProcess[g]) {
drawTexturedModalRect(guiLeft + 113, guiTop + 21 + g * 22, 4, 222, 4, 4);
} else if(recipe != null) {
drawTexturedModalRect(guiLeft + 113, guiTop + 21 + g * 22, 0, 222, 4, 4);
}
/// RIGHT LED
if(chemplant.didProcess[g]) {
drawTexturedModalRect(guiLeft + 121, guiTop + 21 + g * 22, 4, 222, 4, 4);
} else if(recipe != null && chemplant.power >= recipe.power && chemplant.canCool()) {
drawTexturedModalRect(guiLeft + 121, guiTop + 21 + g * 22, 0, 222, 4, 4);
}
}
for(int g = 0; g < 4; g++) { // not a great way of doing it but at least we eliminate state leak bullshit
GenericRecipe recipe = ChemicalPlantRecipes.INSTANCE.recipeNameMap.get(chemplant.chemplantModule[g].recipe);
this.renderItem(recipe != null ? recipe.getIcon() : TEMPLATE_FOLDER, 75, 20 + g * 22);
if(recipe != null && recipe.inputItem != null) {
for(int i = 0; i < recipe.inputItem.length; i++) {
Slot slot = (Slot) this.inventorySlots.inventorySlots.get(chemplant.chemplantModule[g].inputSlots[i]);
if(!slot.getHasStack()) this.renderItem(recipe.inputItem[i].extractForCyclingDisplay(20), slot.xDisplayPosition, slot.yDisplayPosition, 10F);
}
Minecraft.getMinecraft().getTextureManager().bindTexture(texture);
OpenGlHelper.glBlendFunc(770, 771, 1, 0);
GL11.glColor4f(1F, 1F, 1F, 0.5F);
GL11.glEnable(GL11.GL_BLEND);
this.zLevel = 300F;
for(int i = 0; i < recipe.inputItem.length; i++) {
Slot slot = (Slot) this.inventorySlots.inventorySlots.get(chemplant.chemplantModule[g].inputSlots[i]);
if(!slot.getHasStack()) drawTexturedModalRect(guiLeft + slot.xDisplayPosition, guiTop + slot.yDisplayPosition, slot.xDisplayPosition, slot.yDisplayPosition, 16, 16);
}
this.zLevel = 0F;
GL11.glColor4f(1F, 1F, 1F, 1F);
GL11.glDisable(GL11.GL_BLEND);
}
}
for(int i = 0; i < 3; i++) for(int j = 0; j < 4; j++) {
chemplant.inputTanks[i + j * 3].renderTank(guiLeft + 60 + i * 5, guiTop + 36 + j * 22, this.zLevel, 3, 16);
chemplant.outputTanks[i + j * 3].renderTank(guiLeft + 189 + i * 5, guiTop + 36 + j * 22, this.zLevel, 3, 16);
}
chemplant.water.renderTank(guiLeft + 224, guiTop + 177, this.zLevel, 7, 52);
chemplant.lps.renderTank(guiLeft + 233, guiTop + 177, this.zLevel, 7, 52);
}
}

View File

@ -80,6 +80,21 @@ public class GUIMachineChemicalPlant extends GuiInfoContainer {
}
GenericRecipe recipe = ChemicalPlantRecipes.INSTANCE.recipeNameMap.get(chemplant.chemplantModule.recipe);
/// LEFT LED
if(chemplant.didProcess) {
drawTexturedModalRect(guiLeft + 51, guiTop + 121, 195, 0, 3, 6);
} else if(recipe != null) {
drawTexturedModalRect(guiLeft + 51, guiTop + 121, 192, 0, 3, 6);
}
/// RIGHT LED
if(chemplant.didProcess) {
drawTexturedModalRect(guiLeft + 56, guiTop + 121, 195, 0, 3, 6);
} else if(recipe != null && chemplant.power >= recipe.power) {
drawTexturedModalRect(guiLeft + 56, guiTop + 121, 192, 0, 3, 6);
}
this.renderItem(recipe != null ? recipe.getIcon() : TEMPLATE_FOLDER, 8, 126);
if(recipe != null && recipe.inputItem != null) {

View File

@ -276,11 +276,6 @@ public class GUIScreenRecipeSelector extends GuiScreen {
else
this.selection = NULL_SELECTION;
NBTTagCompound data = new NBTTagCompound();
data.setInteger("index", this.index);
data.setString("selection", this.selection);
TileEntity te = (TileEntity) tile;
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, te.xCoord, te.yCoord, te.zCoord));
click();
return;
}
@ -289,11 +284,6 @@ public class GUIScreenRecipeSelector extends GuiScreen {
if(guiLeft + 151 <= x && guiLeft + 151 + 18 > x && guiTop + 71 < y && guiTop + 71 + 18 >= y) {
if(!NULL_SELECTION.equals(this.selection)) {
this.selection = this.NULL_SELECTION;
NBTTagCompound data = new NBTTagCompound();
data.setInteger("index", this.index);
data.setString("selection", this.selection);
TileEntity te = (TileEntity) tile;
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, te.xCoord, te.yCoord, te.zCoord));
click();
return;
}
@ -304,6 +294,17 @@ public class GUIScreenRecipeSelector extends GuiScreen {
}
}
@Override
public void onGuiClosed() {
Keyboard.enableRepeatEvents(false);
NBTTagCompound data = new NBTTagCompound();
data.setInteger("index", this.index);
data.setString("selection", this.selection);
TileEntity te = (TileEntity) tile;
PacketDispatcher.wrapper.sendToServer(new NBTControlPacket(data, te.xCoord, te.yCoord, te.zCoord));
}
@Override
protected void keyTyped(char typedChar, int keyCode) {
@ -321,8 +322,6 @@ public class GUIScreenRecipeSelector extends GuiScreen {
FMLCommonHandler.instance().showGuiScreen(previousScreen);
}
}
@Override public void onGuiClosed() { Keyboard.enableRepeatEvents(false); }
@Override public boolean doesGuiPauseGame() { return false; }
public void click() { mc.getSoundHandler().playSound(PositionedSoundRecord.func_147674_a(new ResourceLocation("gui.button.press"), 1.0F)); }

View File

@ -139,7 +139,6 @@ public class AssemblerRecipes extends SerializableRecipe {
makeRecipe(new ComparableStack(ModBlocks.machine_coker, 1), new AStack[] {!exp ? new OreDictStack(STEEL.plateWelded(), 3) : new OreDictStack(STEEL.heavyComp(), 2), new OreDictStack(IRON.ingot(), 16), new OreDictStack(CU.plate528(), 8), new OreDictStack(RUBBER.ingot(), 4), new ComparableStack(ModItems.tank_steel, 2), new ComparableStack(ModBlocks.steel_grate, 4) },200);
makeRecipe(new ComparableStack(ModBlocks.machine_refinery, 1), new AStack[] {!exp ? new OreDictStack(STEEL.plateWelded(), 3) : new OreDictStack(STEEL.heavyComp(), 1), new OreDictStack(CU.plate528(), 16), new OreDictStack(STEEL.shell(), 6), new OreDictStack(STEEL.pipe(), 12), new ComparableStack(ModItems.plate_polymer, 8), new ComparableStack(ModItems.circuit, 3, EnumCircuitType.ANALOG) },350);
makeRecipe(new ComparableStack(ModBlocks.machine_epress, 1), new AStack[] {new OreDictStack(STEEL.plate(), 8), new OreDictStack(ANY_RUBBER.ingot(), 4), new ComparableStack(ModItems.part_generic, 2, EnumPartType.PISTON_HYDRAULIC.ordinal()), new ComparableStack(ModItems.circuit, 1, EnumCircuitType.BASIC) }, 100);
makeRecipe(new ComparableStack(ModBlocks.machine_chemplant, 1), new AStack[] {new OreDictStack(STEEL.ingot(), 12), new OreDictStack(CU.plate528(), 6), new ComparableStack(ModItems.tank_steel, 4), new ComparableStack(ModItems.coil_tungsten, 3), new ComparableStack(ModItems.circuit, 1, EnumCircuitType.ANALOG), new ComparableStack(ModItems.plate_polymer, 8), },200);
makeRecipe(new ComparableStack(ModBlocks.machine_chemical_plant, 1), new AStack[] {new OreDictStack(STEEL.ingot(), 8), new OreDictStack(CU.pipe(), 2), new ComparableStack(ModItems.plate_polymer, 16), new ComparableStack(ModItems.motor, 2), new ComparableStack(ModItems.coil_tungsten, 2), new ComparableStack(ModItems.circuit, 1, EnumCircuitType.ANALOG) }, 200);
makeRecipe(new ComparableStack(ModBlocks.machine_crystallizer, 1), new AStack[] {new OreDictStack(STEEL.plateWelded(), 2), new OreDictStack(TI.shell(), 3), new OreDictStack(DESH.ingot(), 4), new ComparableStack(ModItems.motor, 1), new ComparableStack(ModItems.circuit, 2, EnumCircuitType.BASIC), },200);
makeRecipe(new ComparableStack(ModBlocks.machine_fluidtank, 1), new AStack[] {new OreDictStack(STEEL.ingot(), 2), new OreDictStack(STEEL.plate528(), 6), new OreDictStack(STEEL.shell(), 4), new OreDictStack(ANY_TAR.any(), 4), },150);
@ -865,6 +864,17 @@ public class AssemblerRecipes extends SerializableRecipe {
new ComparableStack(ModItems.circuit, 16, EnumCircuitType.BASIC)
}, 400);
makeRecipe(new ComparableStack(ModBlocks.machine_chemical_factory, 1), new AStack[] {
new OreDictStack(DURA.ingot(), 16),
new OreDictStack(ANY_RESISTANTALLOY.ingot(), 8),
new OreDictStack(RUBBER.ingot(), 16),
new OreDictStack(STEEL.shell(), 12),
new OreDictStack(CU.pipe(), 8),
new ComparableStack(ModItems.motor_desh, 4),
new ComparableStack(ModItems.coil_tungsten, 16),
new ComparableStack(ModItems.circuit, 16, EnumCircuitType.BASIC)
}, 400);
makeRecipe(new ComparableStack(ModItems.missile_shuttle, 1), new AStack[] {
new ComparableStack(ModItems.missile_generic, 2),
new ComparableStack(ModItems.missile_strong, 1),

View File

@ -79,7 +79,7 @@ public class MixerRecipes extends SerializableRecipe {
register(Fluids.SYNGAS, new MixerRecipe(1_000, 50).setStack1(new FluidStack(Fluids.COALOIL, 500)).setStack2(new FluidStack(Fluids.STEAM, 500)));
register(Fluids.OXYHYDROGEN,
new MixerRecipe(1_000, 50).setStack1(new FluidStack(Fluids.HYDROGEN, 500)),
new MixerRecipe(1_000, 50).setStack1(new FluidStack(Fluids.HYDROGEN, 500)).setStack2(new FluidStack(Fluids.AIR, 2_000)),
new MixerRecipe(1_000, 50).setStack1(new FluidStack(Fluids.HYDROGEN, 500)).setStack2(new FluidStack(Fluids.OXYGEN, 500)));
register(Fluids.PETROIL_LEADED, new MixerRecipe(12_000, 40).setStack1(new FluidStack(Fluids.PETROIL, 10_000)).setSolid(new ComparableStack(ModItems.fuel_additive, 1, 0)));

View File

@ -134,7 +134,7 @@ public class ItemBlowtorch extends Item implements IFillableItem {
if(b instanceof IToolable) {
if(this == ModItems.blowtorch) {
if(this.getFill(stack, Fluids.GAS) < 1000) return false;
if(this.getFill(stack, Fluids.GAS) < 250) return false;
}
if(this == ModItems.acetylene_torch) {

View File

@ -49,7 +49,7 @@ import net.minecraftforge.common.util.ForgeDirection;
public class XFactoryEnergy {
public static final ResourceLocation scope_luna = new ResourceLocation(RefStrings.MODID, "textures/misc/scope_luna.png");
public static final ResourceLocation scope_luna = new ResourceLocation(RefStrings.MODID, "textures/misc/scope_amat.png");
public static BulletConfig energy_tesla;
public static BulletConfig energy_tesla_overcharge;
@ -166,9 +166,9 @@ public class XFactoryEnergy {
energy_las_overcharge = new BulletConfig().setItem(EnumAmmo.CAPACITOR_OVERCHARGE).setCasing(new ItemStack(ModItems.ingot_polymer, 2), 4).setupDamageClass(DamageClass.LASER).setBeam().setSpread(0.0F).setLife(5).setRenderRotations(false).setDoesPenetrate(true).setOnBeamImpact(BulletConfig.LAMBDA_STANDARD_BEAM_HIT);
energy_las_ir = new BulletConfig().setItem(EnumAmmo.CAPACITOR_IR).setCasing(new ItemStack(ModItems.ingot_polymer, 2), 4).setupDamageClass(DamageClass.FIRE).setBeam().setSpread(0.0F).setLife(5).setRenderRotations(false).setOnBeamImpact(LAMBDA_IR_HIT);
energy_emerald = energy_las.clone().setArmorPiercing(0.5F).setThresholdNegation(5F);
energy_emerald_overcharge = energy_las_overcharge.clone().setArmorPiercing(0.5F).setThresholdNegation(5F);
energy_emerald_ir = energy_las_ir.clone().setArmorPiercing(0.5F).setThresholdNegation(5F);
energy_emerald = energy_las.clone().setArmorPiercing(0.5F).setThresholdNegation(10F);
energy_emerald_overcharge = energy_las_overcharge.clone().setArmorPiercing(0.5F).setThresholdNegation(15F);
energy_emerald_ir = energy_las_ir.clone().setArmorPiercing(0.5F).setThresholdNegation(10F);
ModItems.gun_tesla_cannon = new ItemGunBaseNT(WeaponQuality.A_SIDE, new GunConfig()
.dura(1_000).draw(10).inspect(33).crosshair(Crosshair.CIRCLE)
@ -194,7 +194,7 @@ public class XFactoryEnergy {
ModItems.gun_laser_pistol_pew_pew = new ItemGunBaseNT(WeaponQuality.B_SIDE, new GunConfig()
.dura(500).draw(10).inspect(26).crosshair(Crosshair.CIRCLE)
.rec(new Receiver(0)
.dmg(20F).rounds(5).delay(10).spread(0.25F).spreadHipfire(1F).reload(45).jam(37).sound("hbm:weapon.fire.laserPistol", 1.0F, 0.8F)
.dmg(30F).rounds(5).delay(10).spread(0.25F).spreadHipfire(1F).reload(45).jam(37).sound("hbm:weapon.fire.laserPistol", 1.0F, 0.8F)
.mag(new MagazineFullReload(0, 10).addConfigs(energy_las, energy_las_overcharge, energy_las_ir))
.offset(0.75, -0.0625 * 1.5, -0.1875)
.setupStandardFire().recoil(LAMBDA_RECOIL_ENERGY))

View File

@ -91,6 +91,7 @@ import com.hbm.util.fauxpointtwelve.BlockPos;
import com.hbm.util.i18n.I18nClient;
import com.hbm.util.i18n.ITranslate;
import com.hbm.wiaj.cannery.Jars;
import cpw.mods.fml.client.registry.ClientRegistry;
import cpw.mods.fml.client.registry.RenderingRegistry;
import cpw.mods.fml.common.FMLCommonHandler;
@ -270,6 +271,7 @@ public class ClientProxy extends ServerProxy {
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemplant.class, new RenderChemplant());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemicalPlant.class, new RenderChemicalPlant());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemfac.class, new RenderChemfac());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineChemicalFactory.class, new RenderChemicalFactory());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineFluidTank.class, new RenderFluidTank());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineBAT9000.class, new RenderBAT9000());
ClientRegistry.bindTileEntitySpecialRenderer(TileEntityMachineOrbus.class, new RenderOrbus());

View File

@ -15,7 +15,6 @@ import com.hbm.handler.HTTPHandler;
import com.hbm.handler.HazmatRegistry;
import com.hbm.handler.HbmKeybinds;
import com.hbm.handler.ImpactWorldHandler;
import com.hbm.handler.HbmKeybinds.EnumKeybind;
import com.hbm.hazard.HazardSystem;
import com.hbm.interfaces.IHoldableWeapon;
import com.hbm.interfaces.IItemHUD;
@ -36,7 +35,6 @@ import com.hbm.lib.Library;
import com.hbm.lib.RefStrings;
import com.hbm.packet.PacketDispatcher;
import com.hbm.packet.toserver.AuxButtonPacket;
import com.hbm.packet.toserver.KeybindPacket;
import com.hbm.render.anim.HbmAnimations;
import com.hbm.render.anim.HbmAnimations.Animation;
import com.hbm.render.block.ct.CTStitchReceiver;
@ -1081,7 +1079,8 @@ public class ModEventHandlerClient {
}
}
if(event.phase == Phase.START) {
// ???
/*if(event.phase == Phase.START) {
Minecraft mc = Minecraft.getMinecraft();
@ -1097,7 +1096,7 @@ public class ModEventHandlerClient {
}
}
}
}
}*/
}
@SideOnly(Side.CLIENT)

View File

@ -150,6 +150,7 @@ public class ResourceManager {
public static final IModelCustom chemplant_fluidcap = AdvancedModelLoader.loadModel(new ResourceLocation(RefStrings.MODID, "models/chemplant_new_fluidcap.hmf"));
public static final IModelCustom chemical_plant = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/chemical_plant.obj"));
public static final IModelCustom chemfac = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/chemfac.obj"));
public static final IModelCustom chemical_factory = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/chemical_factory.obj"));
//Mixer
public static final IModelCustom mixer = new HFRWavefrontObject(new ResourceLocation(RefStrings.MODID, "models/machines/mixer.obj"));
@ -583,6 +584,7 @@ public class ResourceManager {
public static final ResourceLocation chemical_plant_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/chemical_plant.png");
public static final ResourceLocation chemical_plant_fluid_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/chemical_plant_fluid.png");
public static final ResourceLocation chemfac_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/chemfac.png");
public static final ResourceLocation chemical_factory_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/chemical_factory.png");
//Mixer
public static final ResourceLocation mixer_tex = new ResourceLocation(RefStrings.MODID, "textures/models/machines/mixer.png");

View File

@ -29,7 +29,7 @@ public class ModuleMachineChemplant {
public FluidTank[] outputTanks = new FluidTank[3];
// running vars
public String recipe = "null";
public float progress;
public double progress;
// return signals
public boolean didProcess = false;
public boolean markDirty = false;
@ -43,14 +43,15 @@ public class ModuleMachineChemplant {
/** Chances tank type and pressure based on recipe */
public void setupTanks(GenericRecipe recipe) {
if(recipe == null) return;
if(recipe.inputFluid != null) for(int i = 0; i < Math.min(inputTanks.length, recipe.inputFluid.length); i++) inputTanks[i].conform(recipe.inputFluid[i]);
if(recipe.outputFluid != null) for(int i = 0; i < Math.min(outputTanks.length, recipe.outputFluid.length); i++) outputTanks[i].conform(recipe.outputFluid[i]);
for(int i = 0; i < 3; i++) if(recipe.inputFluid != null && recipe.inputFluid.length > i) inputTanks[i].conform(recipe.inputFluid[i]); else inputTanks[i].resetTank();
for(int i = 0; i < 3; i++) if(recipe.outputFluid != null && recipe.outputFluid.length > i) outputTanks[i].conform(recipe.outputFluid[i]); else outputTanks[i].resetTank();
}
/** Expects the tanks to be set up correctly beforehand */
public boolean canProcess(GenericRecipe recipe) {
public boolean canProcess(GenericRecipe recipe, double speed, double power) {
if(recipe == null) return false;
if(battery.getPower() < recipe.power) return false;
if(power != 1 && battery.getPower() < recipe.power * power) return false; // only check with floating point numbers if mult is not 1
if(power == 1 && battery.getPower() < recipe.power) return false;
if(recipe.inputItem != null) {
for(int i = 0; i < Math.min(recipe.inputItem.length, inputSlots.length); i++) {
@ -87,14 +88,13 @@ public class ModuleMachineChemplant {
return true;
}
public void process(GenericRecipe recipe) {
public void process(GenericRecipe recipe, double speed, double power) {
this.battery.setPower(this.battery.getPower() - recipe.power);
float step = Math.min(1F / recipe.duration, 1F); // can't do more than one recipe per tick, might look into that later
this.battery.setPower(this.battery.getPower() - (power == 1 ? recipe.power : (long) (recipe.power * power)));
double step = Math.min(speed / recipe.duration, 1D); // can't do more than one recipe per tick, might look into that later
this.progress += step;
if(this.progress >= 1F) {
this.progress -= 1F;
if(this.progress >= 1D) {
if(recipe.inputItem != null) {
for(int i = 0; i < Math.min(recipe.inputItem.length, inputSlots.length); i++) {
@ -127,18 +127,23 @@ public class ModuleMachineChemplant {
}
this.markDirty = true;
if(this.canProcess(recipe, speed, power))
this.progress -= 1D;
else
this.progress = 0D;
}
}
public void update() {
public void update(double speed, double power, boolean extraCondition) {
GenericRecipe recipe = ChemicalPlantRecipes.INSTANCE.recipeNameMap.get(this.recipe);
this.setupTanks(recipe);
this.didProcess = false;
this.markDirty = false;
if(this.canProcess(recipe)) {
this.process(recipe);
if(extraCondition && this.canProcess(recipe, speed, power)) {
this.process(recipe, speed, power);
this.didProcess = true;
} else {
this.progress = 0F;
@ -164,22 +169,22 @@ public class ModuleMachineChemplant {
public ModuleMachineChemplant fluidOutput(FluidTank a, FluidTank b, FluidTank c) { outputTanks[0] = a; outputTanks[1] = b; outputTanks[2] = c; return this; }
public void serialize(ByteBuf buf) {
buf.writeFloat(progress);
buf.writeDouble(progress);
ByteBufUtils.writeUTF8String(buf, recipe);
}
public void deserialize(ByteBuf buf) {
this.progress = buf.readFloat();
this.progress = buf.readDouble();
this.recipe = ByteBufUtils.readUTF8String(buf);
}
public void readFromNBT(NBTTagCompound nbt) {
this.progress = nbt.getFloat("progress");
this.recipe = nbt.getString("recipe");
this.progress = nbt.getDouble("progress" + index);
this.recipe = nbt.getString("recipe" + index);
}
public void writeToNBT(NBTTagCompound nbt) {
nbt.setFloat("progress", progress);
nbt.setString("recipe", recipe);
nbt.setDouble("progress" + index, progress);
nbt.setString("recipe" + index, recipe);
}
}

View File

@ -12,12 +12,15 @@ import net.minecraft.world.World;
@SideOnly(Side.CLIENT)
public class ParticleFlamethrower extends EntityFXRotating {
public int type;
public ParticleFlamethrower(World world, double x, double y, double z, int type) {
super(world, x, y, z);
particleIcon = ModEventHandlerClient.particleBase;
this.particleMaxAge = 20 + rand.nextInt(10);
this.particleScale = 0.5F;
this.type = type;
this.motionX = world.rand.nextGaussian() * 0.02;
this.motionZ = world.rand.nextGaussian() * 0.02;
@ -31,6 +34,9 @@ public class ParticleFlamethrower extends EntityFXRotating {
this.particleRed = color.getRed() / 255F;
this.particleGreen = color.getGreen() / 255F;
this.particleBlue = color.getBlue() / 255F;
if(type == FlameCreator.META_OXY) this.particleRed = this.particleGreen = this.particleBlue = 1F;
if(type == FlameCreator.META_BLACK) this.particleRed = this.particleGreen = this.particleBlue = 1F;
}
@Override
@ -60,11 +66,21 @@ public class ParticleFlamethrower extends EntityFXRotating {
public void renderParticle(Tessellator tess, float interp, float sX, float sY, float sZ, float dX, float dZ) {
double ageScaled = (double) this.particleAge / (double) this.particleMaxAge;
this.particleAlpha = (float) Math.pow(1 - Math.min(ageScaled, 1), 0.5);
float add = 0.75F - (float) ageScaled;
tess.setColorRGBA_F(this.particleRed + add, this.particleGreen + add, this.particleBlue + add, this.particleAlpha * 0.5F);
if(type == FlameCreator.META_OXY) {
this.particleAlpha = (float) (1 - ageScaled);
float add = (float) ageScaled * 1.25F - 0.25F;
tess.setColorRGBA_F(this.particleRed - add, this.particleGreen - add * 0.75F, this.particleBlue, this.particleAlpha);
} else if(type == FlameCreator.META_BLACK) {
this.particleAlpha = (float) (1 - ageScaled);
float add = (float) ageScaled * 4F - 1F;
tess.setColorRGBA_F(this.particleRed - add * 0.75F, this.particleGreen - add, this.particleBlue - add * 0.5F, this.particleAlpha);
} else {
this.particleAlpha = (float) Math.pow(1 - Math.min(ageScaled, 1), 0.5);
float add = 0.75F - (float) ageScaled;
tess.setColorRGBA_F(this.particleRed + add, this.particleGreen + add, this.particleBlue + add, this.particleAlpha * 0.5F);
}
tess.setNormal(0.0F, 1.0F, 0.0F);
tess.setBrightness(240);

View File

@ -18,6 +18,8 @@ public class FlameCreator implements IParticleCreator {
public static int META_FIRE = 0;
public static int META_BALEFIRE = 1;
public static int META_DIGAMMA = 2;
public static int META_OXY = 3;
public static int META_BLACK = 4;
public static void composeEffect(World world, double x, double y, double z, int meta) {
NBTTagCompound data = new NBTTagCompound();

View File

@ -0,0 +1,83 @@
package com.hbm.render.tileentity;
import org.lwjgl.opengl.GL11;
import com.hbm.blocks.BlockDummyable;
import com.hbm.blocks.ModBlocks;
import com.hbm.main.ResourceManager;
import com.hbm.render.item.ItemRenderBase;
import com.hbm.tileentity.machine.TileEntityMachineChemicalFactory;
import net.minecraft.client.renderer.tileentity.TileEntitySpecialRenderer;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.tileentity.TileEntity;
import net.minecraftforge.client.IItemRenderer;
public class RenderChemicalFactory extends TileEntitySpecialRenderer implements IItemRendererProvider {
@Override
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float interp) {
GL11.glPushMatrix();
GL11.glTranslated(x + 0.5, y, z + 0.5);
GL11.glRotated(90, 0, 1, 0);
GL11.glShadeModel(GL11.GL_SMOOTH);
switch(tileEntity.getBlockMetadata() - BlockDummyable.offset) {
case 2: GL11.glRotatef(0, 0F, 1F, 0F); break;
case 4: GL11.glRotatef(90, 0F, 1F, 0F); break;
case 3: GL11.glRotatef(180, 0F, 1F, 0F); break;
case 5: GL11.glRotatef(270, 0F, 1F, 0F); break;
}
TileEntityMachineChemicalFactory chemplant = (TileEntityMachineChemicalFactory) tileEntity;
float anim = chemplant.prevAnim + (chemplant.anim - chemplant.prevAnim) * interp;
bindTexture(ResourceManager.chemical_factory_tex);
ResourceManager.chemical_factory.renderPart("Base");
if(chemplant.frame) ResourceManager.chemical_factory.renderPart("Frame");
GL11.glPushMatrix();
GL11.glTranslated(1, 0, 0);
GL11.glRotated(-anim * 45 % 360D, 0, 1, 0);
GL11.glTranslated(-1, 0, 0);
ResourceManager.chemical_factory.renderPart("Fan1");
GL11.glPopMatrix();
GL11.glPushMatrix();
GL11.glTranslated(-1, 0, 0);
GL11.glRotated(-anim * 45 % 360D, 0, 1, 0);
GL11.glTranslated(1, 0, 0);
ResourceManager.chemical_factory.renderPart("Fan2");
GL11.glPopMatrix();
GL11.glShadeModel(GL11.GL_FLAT);
GL11.glPopMatrix();
}
@Override
public Item getItemForRenderer() {
return Item.getItemFromBlock(ModBlocks.machine_chemical_factory);
}
@Override
public IItemRenderer getRenderer() {
return new ItemRenderBase() {
public void renderInventory() {
GL11.glTranslated(0, -1.5, 0);
GL11.glScaled(3, 3, 3);
}
public void renderCommonWithStack(ItemStack item) {
GL11.glScaled(0.75, 0.75, 0.75);
GL11.glShadeModel(GL11.GL_SMOOTH);
bindTexture(ResourceManager.chemical_factory_tex);
ResourceManager.chemical_factory.renderPart("Base");
ResourceManager.chemical_factory.renderPart("Frame");
ResourceManager.chemical_factory.renderPart("Fan1");
ResourceManager.chemical_factory.renderPart("Fan2");
GL11.glShadeModel(GL11.GL_FLAT);
}};
}
}

View File

@ -35,11 +35,8 @@ public class RendererObjTester extends TileEntitySpecialRenderer {
public void renderTileEntityAt(TileEntity tileEntity, double x, double y, double z, float f) {
GL11.glPushMatrix();
GL11.glTranslated(x + 0.5, y + 1, z + 0.5);
GL11.glRotated(15, 0, 0, 1);
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glRotated(System.currentTimeMillis() / 5D % 360D, 0, -1, 0);
if(world == null) {
world = new WorldInAJar(5, 3, 5);
for(int i = 0; i < 25; i++) world.setBlock(i / 5, 1, i % 5, Blocks.brick_block, 0);
@ -55,6 +52,8 @@ public class RendererObjTester extends TileEntitySpecialRenderer {
RenderHelper.disableStandardItemLighting();
GL11.glPushMatrix();
GL11.glRotated(15, 0, 0, 1);
GL11.glRotated(System.currentTimeMillis() / 5D % 360D, 0, -1, 0);
GL11.glTranslated(-2.5, 0, -2.5);
Minecraft.getMinecraft().getTextureManager().bindTexture(TextureMap.locationBlocksTexture);
GL11.glShadeModel(GL11.GL_SMOOTH);
@ -73,6 +72,10 @@ public class RendererObjTester extends TileEntitySpecialRenderer {
GL11.glPopMatrix();
RenderHelper.enableStandardItemLighting();
GL11.glRotated(15, 0, 0, 1);
GL11.glRotated(System.currentTimeMillis() / 5D % 360D, 0, -1, 0);
GL11.glTranslated(0, 2.1, 0.5);
this.bindTexture(extra);

View File

@ -25,6 +25,7 @@ public interface IUpgradeInfoProvider {
public static final String KEY_CONSUMPTION = "upgrade.consumption";
public static final String KEY_COOLANT_CONSUMPTION = "upgrade.coolantConsumption";
public static final String KEY_DELAY = "upgrade.delay";
public static final String KEY_SPEED = "upgrade.speed";
public static final String KEY_EFFICIENCY = "upgrade.efficiency";
public static final String KEY_PRODUCTIVITY = "upgrade.productivity";
public static final String KEY_FORTUNE = "upgrade.fortune";

View File

@ -75,15 +75,18 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
return this;
}
//fewer messy recursive operations
public TileEntity getTile() {
/** Returns the actual tile entity that represents the core. Only for internal use. */
protected TileEntity getTile() {
if(tile == null || tile.isInvalid()) {
tile = this.getTE();
}
return tile;
}
/** Returns the core tile entity, or a delegate object. */
protected Object getCoreObject() {
return getTile();
}
@Override
public void setPower(long i) {
@ -91,8 +94,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!power)
return;
if(getTile() instanceof IEnergyReceiverMK2) {
((IEnergyReceiverMK2)getTile()).setPower(i);
if(getCoreObject() instanceof IEnergyReceiverMK2) {
((IEnergyReceiverMK2)getCoreObject()).setPower(i);
}
}
@ -102,8 +105,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!power)
return 0;
if(getTile() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getTile()).getPower();
if(getCoreObject() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getCoreObject()).getPower();
}
return 0;
@ -115,8 +118,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!power)
return 0;
if(getTile() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getTile()).getMaxPower();
if(getCoreObject() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getCoreObject()).getMaxPower();
}
return 0;
@ -128,8 +131,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!this.power)
return power;
if(getTile() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getTile()).transferPower(power);
if(getCoreObject() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getCoreObject()).transferPower(power);
}
return power;
@ -141,8 +144,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!power)
return false;
if(getTile() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getTile()).canConnect(dir);
if(getCoreObject() instanceof IEnergyReceiverMK2) {
return ((IEnergyReceiverMK2)getCoreObject()).canConnect(dir);
}
return true;
@ -154,8 +157,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
public FluidTank[] getAllTanks() {
if(!fluid) return EMPTY_TANKS;
if(getTile() instanceof IFluidReceiverMK2) {
return ((IFluidReceiverMK2)getTile()).getAllTanks();
if(getCoreObject() instanceof IFluidReceiverMK2) {
return ((IFluidReceiverMK2)getCoreObject()).getAllTanks();
}
return EMPTY_TANKS;
@ -165,8 +168,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
public long transferFluid(FluidType type, int pressure, long amount) {
if(!fluid) return amount;
if(getTile() instanceof IFluidReceiverMK2) {
return ((IFluidReceiverMK2)getTile()).transferFluid(type, pressure, amount);
if(getCoreObject() instanceof IFluidReceiverMK2) {
return ((IFluidReceiverMK2)getCoreObject()).transferFluid(type, pressure, amount);
}
return amount;
@ -176,8 +179,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
public long getDemand(FluidType type, int pressure) {
if(!fluid) return 0;
if(getTile() instanceof IFluidReceiverMK2) {
return ((IFluidReceiverMK2)getTile()).getDemand(type, pressure);
if(getCoreObject() instanceof IFluidReceiverMK2) {
return ((IFluidReceiverMK2)getCoreObject()).getDemand(type, pressure);
}
return 0;
@ -189,8 +192,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!this.fluid)
return false;
if(getTile() instanceof IFluidConnectorMK2) {
return ((IFluidConnectorMK2) getTile()).canConnect(type, dir);
if(getCoreObject() instanceof IFluidConnectorMK2) {
return ((IFluidConnectorMK2) getCoreObject()).canConnect(type, dir);
}
return true;
}
@ -201,8 +204,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return 0;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).getSizeInventory();
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).getSizeInventory();
}
return 0;
@ -214,8 +217,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return null;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).getStackInSlot(slot);
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).getStackInSlot(slot);
}
return null;
@ -224,8 +227,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
@Override
public ItemStack decrStackSize(int i, int j) {
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).decrStackSize(i, j);
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).decrStackSize(i, j);
}
return null;
@ -237,8 +240,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return null;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).getStackInSlotOnClosing(slot);
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).getStackInSlotOnClosing(slot);
}
return null;
@ -250,8 +253,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return;
if(getTile() instanceof ISidedInventory) {
((ISidedInventory)getTile()).setInventorySlotContents(slot, stack);
if(getCoreObject() instanceof ISidedInventory) {
((ISidedInventory)getCoreObject()).setInventorySlotContents(slot, stack);
}
}
@ -261,8 +264,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return null;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).getInventoryName();
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).getInventoryName();
}
return null;
@ -274,8 +277,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return false;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).hasCustomInventoryName();
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).hasCustomInventoryName();
}
return false;
@ -287,8 +290,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return 0;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).getInventoryStackLimit();
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).getInventoryStackLimit();
}
return 0;
@ -300,8 +303,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return false;
if(getTile() instanceof ISidedInventory) {
return ((ISidedInventory)getTile()).isUseableByPlayer(player);
if(getCoreObject() instanceof ISidedInventory) {
return ((ISidedInventory)getCoreObject()).isUseableByPlayer(player);
}
return false;
@ -313,8 +316,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return;
if(getTile() instanceof ISidedInventory) {
((ISidedInventory)getTile()).openInventory();
if(getCoreObject() instanceof ISidedInventory) {
((ISidedInventory)getCoreObject()).openInventory();
}
}
@ -324,8 +327,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return;
if(getTile() instanceof ISidedInventory) {
((ISidedInventory)getTile()).closeInventory();
if(getCoreObject() instanceof ISidedInventory) {
((ISidedInventory)getCoreObject()).closeInventory();
}
}
@ -335,11 +338,11 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return false;
if(getTile() instanceof ISidedInventory) {
if(getCoreObject() instanceof ISidedInventory) {
if(getTile() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getTile()).isItemValidForSlot(xCoord, yCoord, zCoord, slot, stack);
if(getCoreObject() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getCoreObject()).isItemValidForSlot(xCoord, yCoord, zCoord, slot, stack);
return ((ISidedInventory)getTile()).isItemValidForSlot(slot, stack);
return ((ISidedInventory)getCoreObject()).isItemValidForSlot(slot, stack);
}
return false;
@ -351,11 +354,11 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return new int[0];
if(getTile() instanceof ISidedInventory) {
if(getCoreObject() instanceof ISidedInventory) {
if(getTile() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getTile()).getAccessibleSlotsFromSide(xCoord, yCoord, zCoord, side);
if(getCoreObject() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getCoreObject()).getAccessibleSlotsFromSide(xCoord, yCoord, zCoord, side);
return ((ISidedInventory)getTile()).getAccessibleSlotsFromSide(side);
return ((ISidedInventory)getCoreObject()).getAccessibleSlotsFromSide(side);
}
return new int[0];
@ -367,11 +370,11 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return false;
if(getTile() instanceof ISidedInventory) {
if(getCoreObject() instanceof ISidedInventory) {
if(getTile() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getTile()).canInsertItem(xCoord, yCoord, zCoord, i, stack, j);
if(getCoreObject() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getCoreObject()).canInsertItem(xCoord, yCoord, zCoord, i, stack, j);
return ((ISidedInventory)getTile()).canInsertItem(i, stack, j);
return ((ISidedInventory)getCoreObject()).canInsertItem(i, stack, j);
}
return false;
@ -383,11 +386,11 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!inventory)
return false;
if(getTile() instanceof ISidedInventory) {
if(getCoreObject() instanceof ISidedInventory) {
if(getTile() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getTile()).canExtractItem(xCoord, yCoord, zCoord, i, stack, j);
if(getCoreObject() instanceof IConditionalInvAccess) return ((IConditionalInvAccess) getCoreObject()).canExtractItem(xCoord, yCoord, zCoord, i, stack, j);
return ((ISidedInventory)getTile()).canExtractItem(i, stack, j);
return ((ISidedInventory)getCoreObject()).canExtractItem(i, stack, j);
}
return false;
@ -426,8 +429,8 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!this.heat)
return 0;
if(getTile() instanceof IHeatSource) {
return ((IHeatSource)getTile()).getHeatStored();
if(getCoreObject() instanceof IHeatSource) {
return ((IHeatSource)getCoreObject()).getHeatStored();
}
return 0;
@ -439,39 +442,39 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
if(!this.heat)
return;
if(getTile() instanceof IHeatSource) {
((IHeatSource)getTile()).useUpHeat(heat);
if(getCoreObject() instanceof IHeatSource) {
((IHeatSource)getCoreObject()).useUpHeat(heat);
}
}
@Override
public boolean canAcceptPartialPour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, Mats.MaterialStack stack) {
if(this.moltenMetal && getTile() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getTile()).canAcceptPartialPour(world, x, y, z, dX, dY, dZ, side, stack);
if(this.moltenMetal && getCoreObject() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getCoreObject()).canAcceptPartialPour(world, x, y, z, dX, dY, dZ, side, stack);
}
return false;
}
@Override
public Mats.MaterialStack pour(World world, int x, int y, int z, double dX, double dY, double dZ, ForgeDirection side, Mats.MaterialStack stack) {
if(this.moltenMetal && getTile() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getTile()).pour(world, x, y, z, dX, dY, dZ, side, stack);
if(this.moltenMetal && getCoreObject() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getCoreObject()).pour(world, x, y, z, dX, dY, dZ, side, stack);
}
return null;
}
@Override
public boolean canAcceptPartialFlow(World world, int x, int y, int z, ForgeDirection side, Mats.MaterialStack stack) {
if(this.moltenMetal && getTile() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getTile()).canAcceptPartialFlow(world, x, y, z, side, stack);
if(this.moltenMetal && getCoreObject() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getCoreObject()).canAcceptPartialFlow(world, x, y, z, side, stack);
}
return false;
}
@Override
public Mats.MaterialStack flow(World world, int x, int y, int z, ForgeDirection side, Mats.MaterialStack stack) {
if(this.moltenMetal && getTile() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getTile()).flow(world, x, y, z, side, stack);
if(this.moltenMetal && getCoreObject() instanceof ICrucibleAcceptor){
return ((ICrucibleAcceptor)getCoreObject()).flow(world, x, y, z, side, stack);
}
return null;
}
@ -481,9 +484,9 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
public String getComponentName() {
if(this.worldObj == null) // OC is going too fast, grab from NBT!
return componentName;
if(this.getTile() instanceof OCComponent) {
if(this.getCoreObject() instanceof OCComponent) {
if (componentName == null || componentName.equals(OCComponent.super.getComponentName())) {
componentName = ((OCComponent) this.getTile()).getComponentName();
componentName = ((OCComponent) this.getCoreObject()).getComponentName();
}
return componentName;
}
@ -493,44 +496,44 @@ public class TileEntityProxyCombo extends TileEntityProxyBase implements IEnergy
@Override
@Optional.Method(modid = "OpenComputers")
public boolean canConnectNode(ForgeDirection side) {
if(this.getTile() instanceof OCComponent)
if(this.getCoreObject() instanceof OCComponent)
return (this.getBlockMetadata() >= 6 && this.getBlockMetadata() <= 11)
&& (power || fluid) &&
((OCComponent) this.getTile()).canConnectNode(side);
((OCComponent) this.getCoreObject()).canConnectNode(side);
return OCComponent.super.canConnectNode(null);
}
@Override
@Optional.Method(modid = "OpenComputers")
public String[] methods() {
if(this.getTile() instanceof OCComponent)
return ((OCComponent) this.getTile()).methods();
if(this.getCoreObject() instanceof OCComponent)
return ((OCComponent) this.getCoreObject()).methods();
return OCComponent.super.methods();
}
@Override
@Optional.Method(modid = "OpenComputers")
public Object[] invoke(String method, Context context, Arguments args) throws Exception {
if(this.getTile() instanceof OCComponent)
return ((OCComponent) this.getTile()).invoke(method, context, args);
if(this.getCoreObject() instanceof OCComponent)
return ((OCComponent) this.getCoreObject()).invoke(method, context, args);
return OCComponent.super.invoke(null, null, null);
}
@Override
public String[] getFunctionInfo() {
if(getTile() instanceof IRORInfo) return ((IRORInfo) getTile()).getFunctionInfo();
if(getCoreObject() instanceof IRORInfo) return ((IRORInfo) getCoreObject()).getFunctionInfo();
return new String[0];
}
@Override
public String provideRORValue(String name) {
if(getTile() instanceof IRORValueProvider) return ((IRORValueProvider) getTile()).provideRORValue(name);
if(getCoreObject() instanceof IRORValueProvider) return ((IRORValueProvider) getCoreObject()).provideRORValue(name);
return null;
}
@Override
public String runRORFunction(String name, String[] params) {
if(getTile() instanceof IRORInteractive) return ((IRORInteractive) getTile()).runRORFunction(name, params);
if(getCoreObject() instanceof IRORInteractive) return ((IRORInteractive) getCoreObject()).runRORFunction(name, params);
return null;
}
}

View File

@ -0,0 +1,24 @@
package com.hbm.tileentity;
public class TileEntityProxyDyn extends TileEntityProxyCombo {
@Override
public Object getCoreObject() {
Object o = super.getCoreObject();
if(o instanceof IProxyDelegateProvider) {
Object delegate = ((IProxyDelegateProvider) o).getDelegateForPosition(xCoord, yCoord, zCoord);
if(delegate != null) return delegate;
}
return o;
}
/** Based on the position of the proxy, produces a delegate instead of returning the core tile entity. God this fucking sucks. */
public static interface IProxyDelegateProvider {
/** Returns the delegate based on the proxy's position. Retunring NULL skips the delegate and reverts back to original core behavior */
public Object getDelegateForPosition(int x, int y, int z);
}
}

View File

@ -222,6 +222,7 @@ public class TileMappings {
put(TileEntityProxyInventory.class, "tileentity_proxy_inventory");
put(TileEntityProxyEnergy.class, "tileentity_proxy_power");
put(TileEntityProxyCombo.class, "tileentity_proxy_combo");
put(TileEntityProxyDyn.class, "tileentity_proxy_dyn");
put(TileEntityProxyConductor.class, "tileentity_proxy_conductor");
put(TileEntityBedrockOre.class, "tileentity_bedrock_ore");
@ -342,6 +343,7 @@ public class TileMappings {
put(TileEntityMachineChemplant.class, "tileentity_chemical_plant");
put(TileEntityMachineChemicalPlant.class, "tileentity_chemicalplant");
put(TileEntityMachineChemfac.class, "tileentity_chemfac");
put(TileEntityMachineChemicalFactory.class, "tileentity_chemicalfactory");
put(TileEntityMachineOilWell.class, "tileentity_derrick");
put(TileEntityMachinePumpjack.class, "tileentity_machine_pumpjack");

View File

@ -556,7 +556,6 @@ public class TileEntityHadron extends TileEntityMachineBase implements IEnergyRe
for(int c = z - dZ * 2; c <= z + dZ * 2;c++) {
Block block = worldObj.getBlock(a, b, c);
int meta = worldObj.getBlockMetadata(a, b, c);
/** ignore the center for now */
if(a == x && b == y && c == z) {

View File

@ -33,6 +33,7 @@ import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
@Deprecated
public class TileEntityMachineChemfac extends TileEntityMachineChemplantBase implements IUpgradeInfoProvider, IFluidCopiable {
float rotSpeed;

View File

@ -0,0 +1,433 @@
package com.hbm.tileentity.machine;
import java.util.HashMap;
import java.util.List;
import com.hbm.blocks.ModBlocks;
import com.hbm.interfaces.IControlReceiver;
import com.hbm.inventory.UpgradeManagerNT;
import com.hbm.inventory.container.ContainerMachineChemicalFactory;
import com.hbm.inventory.fluid.Fluids;
import com.hbm.inventory.fluid.tank.FluidTank;
import com.hbm.inventory.gui.GUIMachineChemicalFactory;
import com.hbm.items.machine.ItemMachineUpgrade;
import com.hbm.items.machine.ItemMachineUpgrade.UpgradeType;
import com.hbm.lib.Library;
import com.hbm.main.MainRegistry;
import com.hbm.module.ModuleMachineChemplant;
import com.hbm.sound.AudioWrapper;
import com.hbm.tileentity.IGUIProvider;
import com.hbm.tileentity.IUpgradeInfoProvider;
import com.hbm.tileentity.TileEntityMachineBase;
import com.hbm.tileentity.TileEntityProxyDyn.IProxyDelegateProvider;
import com.hbm.util.BobMathUtil;
import com.hbm.util.fauxpointtwelve.DirPos;
import com.hbm.util.i18n.I18nUtil;
import api.hbm.energymk2.IEnergyReceiverMK2;
import api.hbm.fluidmk2.IFluidStandardTransceiverMK2;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
import io.netty.buffer.ByteBuf;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.AxisAlignedBB;
import net.minecraft.util.EnumChatFormatting;
import net.minecraft.world.World;
import net.minecraftforge.common.util.ForgeDirection;
public class TileEntityMachineChemicalFactory extends TileEntityMachineBase implements IEnergyReceiverMK2, IFluidStandardTransceiverMK2, IUpgradeInfoProvider, IControlReceiver, IGUIProvider, IProxyDelegateProvider {
public FluidTank[] allTanks;
public FluidTank[] inputTanks;
public FluidTank[] outputTanks;
public FluidTank water;
public FluidTank lps;
public long power;
public long maxPower = 10_000_000;
public boolean[] didProcess = new boolean[4];
public boolean frame = false;
public int anim;
public int prevAnim;
private AudioWrapper audio;
public ModuleMachineChemplant[] chemplantModule;
public UpgradeManagerNT upgradeManager = new UpgradeManagerNT(this);
protected DelegateChemicalFactoy delegate = new DelegateChemicalFactoy();
public TileEntityMachineChemicalFactory() {
super(32);
this.inputTanks = new FluidTank[12];
this.outputTanks = new FluidTank[12];
for(int i = 0; i < 12; i++) {
this.inputTanks[i] = new FluidTank(Fluids.NONE, 24_000);
this.outputTanks[i] = new FluidTank(Fluids.NONE, 24_000);
}
this.water = new FluidTank(Fluids.WATER, 4_000);
this.lps = new FluidTank(Fluids.SPENTSTEAM, 4_000);
this.allTanks = new FluidTank[this.inputTanks.length + this.outputTanks.length + 2];
for(int i = 0; i < inputTanks.length; i++) this.allTanks[i] = this.inputTanks[i];
for(int i = 0; i < outputTanks.length; i++) this.allTanks[i + this.inputTanks.length] = this.outputTanks[i];
this.allTanks[this.allTanks.length - 2] = this.water;
this.allTanks[this.allTanks.length - 1] = this.lps;
this.chemplantModule = new ModuleMachineChemplant[4];
for(int i = 0; i < 4; i++) this.chemplantModule[i] = new ModuleMachineChemplant(i, this, slots)
.itemInput(5 + i * 7, 6 + i * 7, 7 + i * 7)
.itemOutput(8 + i * 7, 9 + i * 7, 10 + i * 7)
.fluidInput(inputTanks[0 + i * 3], inputTanks[1 + i * 3], inputTanks[2 + i * 3])
.fluidOutput(outputTanks[0 + i * 3], outputTanks[1 + i * 3], outputTanks[2 + i * 3]);
}
@Override
public boolean canExtractItem(int i, ItemStack itemStack, int j) {
if(i >= 8 && i <= 10) return true;
if(i >= 15 && i <= 17) return true;
if(i >= 22 && i <= 24) return true;
if(i >= 29 && i <= 31) return true;
return false;
}
@Override
public boolean isItemValidForSlot(int slot, ItemStack stack) {
if(slot == 0) return true; // battery
if(slot >= 1 && slot <= 3 && stack.getItem() instanceof ItemMachineUpgrade) return true; // upgrades
for(int i = 0; i < 4; i++) if(this.chemplantModule[i].isItemValid(slot, stack)) return true; // recipe input crap
return false;
}
@Override
public int[] getAccessibleSlotsFromSide(int side) {
return new int[] {
5, 6, 7, 8, 9, 10,
12, 13, 14, 15, 16, 17,
19, 20, 21, 22, 23, 24,
26, 27, 28, 29, 30, 31
};
}
@Override
public String getName() {
return "container.machineChemicalFactory";
}
@Override
public void updateEntity() {
if(maxPower <= 0) this.maxPower = 10_000_000;
if(!worldObj.isRemote) {
this.power = Library.chargeTEFromItems(slots, 0, power, maxPower);
upgradeManager.checkSlots(slots, 1, 3);
inputTanks[0].loadTank(10, 13, slots);
inputTanks[1].loadTank(11, 14, slots);
inputTanks[2].loadTank(12, 15, slots);
outputTanks[0].unloadTank(16, 19, slots);
outputTanks[1].unloadTank(17, 20, slots);
outputTanks[2].unloadTank(18, 21, slots);
for(DirPos pos : getConPos()) {
this.trySubscribe(worldObj, pos);
for(FluidTank tank : inputTanks) if(tank.getTankType() != Fluids.NONE) this.trySubscribe(tank.getTankType(), worldObj, pos);
for(FluidTank tank : outputTanks) if(tank.getFill() > 0) this.tryProvide(tank, worldObj, pos);
}
for(DirPos pos : getCoolPos()) {
delegate.trySubscribe(worldObj, pos);
delegate.trySubscribe(water.getTankType(), worldObj, pos);
delegate.tryProvide(lps, worldObj, pos);
}
double speed = 1D;
double pow = 1D;
speed += Math.min(upgradeManager.getLevel(UpgradeType.SPEED), 3) / 3D;
speed += Math.min(upgradeManager.getLevel(UpgradeType.OVERDRIVE), 3);
pow -= Math.min(upgradeManager.getLevel(UpgradeType.POWER), 3) * 0.25D;
pow += Math.min(upgradeManager.getLevel(UpgradeType.SPEED), 3) * 1D;
pow += Math.min(upgradeManager.getLevel(UpgradeType.OVERDRIVE), 3) * 10D / 3D;
boolean markDirty = false;
for(int i = 0; i < 4; i++) {
this.chemplantModule[i].update(speed * 2D, pow * 2D, canCool());
this.didProcess[i] = this.chemplantModule[i].didProcess;
markDirty |= this.chemplantModule[i].markDirty;
if(this.chemplantModule[i].didProcess) {
this.water.setFill(this.water.getFill() - 100);
this.lps.setFill(this.lps.getFill() + 100);
}
}
for(FluidTank in : inputTanks) if(in.getTankType() != Fluids.NONE) for(FluidTank out : outputTanks) { // up to 144 iterations, but most of them are NOP anyway
if(out.getTankType() == Fluids.NONE) continue;
if(out.getTankType() != in.getTankType()) continue;
int toMove = BobMathUtil.min(in.getMaxFill() - in.getFill(), out.getFill(), 50);
if(toMove > 0) {
in.setFill(in.getFill() + toMove);
out.setFill(out.getFill() - toMove);
}
}
if(markDirty) this.markDirty();
this.networkPackNT(100);
} else {
this.prevAnim = this.anim;
boolean didSomething = didProcess[0] || didProcess[1] || didProcess[2] || didProcess[3];
if(didSomething) this.anim++;
if(worldObj.getTotalWorldTime() % 20 == 0) {
frame = !worldObj.getBlock(xCoord, yCoord + 3, zCoord).isAir(worldObj, xCoord, yCoord + 3, zCoord);
}
if(didSomething && MainRegistry.proxy.me().getDistance(xCoord , yCoord, zCoord) < 50) {
if(audio == null) {
audio = createAudioLoop();
audio.startSound();
} else if(!audio.isPlaying()) {
audio = rebootAudio(audio);
}
audio.keepAlive();
audio.updateVolume(this.getVolume(1F));
} else {
if(audio != null) {
audio.stopSound();
audio = null;
}
}
}
}
@Override public AudioWrapper createAudioLoop() {
return MainRegistry.proxy.getLoopedSound("hbm:block.chemicalPlant", xCoord, yCoord, zCoord, 1F, 15F, 1.0F, 20);
}
@Override public void onChunkUnload() {
if(audio != null) { audio.stopSound(); audio = null; }
}
@Override public void invalidate() {
super.invalidate();
if(audio != null) { audio.stopSound(); audio = null; }
}
public boolean canCool() {
return water.getFill() >= 100 && lps.getFill() <= lps.getMaxFill() - 100;
}
public DirPos[] getConPos() {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
return new DirPos[] {
new DirPos(xCoord + 3, yCoord, zCoord - 2, Library.POS_X),
new DirPos(xCoord + 3, yCoord, zCoord + 0, Library.POS_X),
new DirPos(xCoord + 3, yCoord, zCoord + 2, Library.POS_X),
new DirPos(xCoord - 3, yCoord, zCoord - 2, Library.NEG_X),
new DirPos(xCoord - 3, yCoord, zCoord + 0, Library.NEG_X),
new DirPos(xCoord - 3, yCoord, zCoord + 2, Library.NEG_X),
new DirPos(xCoord - 2, yCoord, zCoord + 3, Library.POS_Z),
new DirPos(xCoord + 0, yCoord, zCoord + 3, Library.POS_Z),
new DirPos(xCoord + 2, yCoord, zCoord + 3, Library.POS_Z),
new DirPos(xCoord - 2, yCoord, zCoord - 3, Library.NEG_Z),
new DirPos(xCoord + 0, yCoord, zCoord - 3, Library.NEG_Z),
new DirPos(xCoord + 2, yCoord, zCoord - 3, Library.NEG_Z),
new DirPos(xCoord + dir.offsetX * 2 + rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 2 + rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord + dir.offsetX * 1 + rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 1 + rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord + dir.offsetX * 0 + rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 0 + rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord - dir.offsetX * 1 + rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 1 + rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord - dir.offsetX * 2 + rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 2 + rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord + dir.offsetX * 2 - rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 2 - rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord + dir.offsetX * 1 - rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 1 - rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord + dir.offsetX * 0 - rot.offsetX * 2, yCoord + 3, zCoord + dir.offsetZ * 0 - rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord - dir.offsetX * 1 - rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 1 - rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord - dir.offsetX * 2 - rot.offsetX * 2, yCoord + 3, zCoord - dir.offsetZ * 2 - rot.offsetZ * 2, Library.POS_Y),
new DirPos(xCoord + dir.offsetX + rot.offsetX * 3, yCoord, zCoord + dir.offsetZ + rot.offsetZ * 3, rot),
new DirPos(xCoord - dir.offsetX + rot.offsetX * 3, yCoord, zCoord - dir.offsetZ + rot.offsetZ * 3, rot),
new DirPos(xCoord + dir.offsetX - rot.offsetX * 3, yCoord, zCoord + dir.offsetZ - rot.offsetZ * 3, rot.getOpposite()),
new DirPos(xCoord - dir.offsetX - rot.offsetX * 3, yCoord, zCoord - dir.offsetZ - rot.offsetZ * 3, rot.getOpposite()),
};
}
public DirPos[] getCoolPos() {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
return new DirPos[] {
new DirPos(xCoord + rot.offsetX + dir.offsetX * 3, yCoord, zCoord + rot.offsetZ + dir.offsetZ * 3, dir),
new DirPos(xCoord - rot.offsetX + dir.offsetX * 3, yCoord, zCoord - rot.offsetZ + dir.offsetZ * 3, dir),
new DirPos(xCoord + rot.offsetX - dir.offsetX * 3, yCoord, zCoord + rot.offsetZ - dir.offsetZ * 3, dir.getOpposite()),
new DirPos(xCoord - rot.offsetX - dir.offsetX * 3, yCoord, zCoord - rot.offsetZ - dir.offsetZ * 3, dir.getOpposite()),
};
}
@Override
public void serialize(ByteBuf buf) {
super.serialize(buf);
for(FluidTank tank : inputTanks) tank.serialize(buf);
for(FluidTank tank : outputTanks) tank.serialize(buf);
water.serialize(buf);
lps.serialize(buf);
buf.writeLong(power);
buf.writeLong(maxPower);
for(boolean b : didProcess) buf.writeBoolean(b);
for(int i = 0; i < 4; i++) this.chemplantModule[i].serialize(buf);
}
@Override
public void deserialize(ByteBuf buf) {
super.deserialize(buf);
for(FluidTank tank : inputTanks) tank.deserialize(buf);
for(FluidTank tank : outputTanks) tank.deserialize(buf);
water.deserialize(buf);
lps.deserialize(buf);
this.power = buf.readLong();
this.maxPower = buf.readLong();
for(int i = 0; i < 4; i++) this.didProcess[i] = buf.readBoolean();
for(int i = 0; i < 4; i++) this.chemplantModule[i].deserialize(buf);
}
@Override
public void readFromNBT(NBTTagCompound nbt) {
super.readFromNBT(nbt);
for(int i = 0; i < inputTanks.length; i++) this.inputTanks[i].readFromNBT(nbt, "i" + i);
for(int i = 0; i < outputTanks.length; i++) this.outputTanks[i].readFromNBT(nbt, "i" + i);
this.power = nbt.getLong("power");
this.maxPower = nbt.getLong("maxPower");
for(int i = 0; i < 4; i++) this.chemplantModule[i].readFromNBT(nbt);
}
@Override
public void writeToNBT(NBTTagCompound nbt) {
super.writeToNBT(nbt);
for(int i = 0; i < inputTanks.length; i++) this.inputTanks[i].writeToNBT(nbt, "i" + i);
for(int i = 0; i < outputTanks.length; i++) this.outputTanks[i].writeToNBT(nbt, "i" + i);
nbt.setLong("power", power);
nbt.setLong("maxPower", maxPower);
for(int i = 0; i < 4; i++) this.chemplantModule[i].writeToNBT(nbt);
}
@Override public long getPower() { return power; }
@Override public void setPower(long power) { this.power = power; }
@Override public long getMaxPower() { return maxPower; }
@Override public FluidTank[] getReceivingTanks() { return inputTanks; }
@Override public FluidTank[] getSendingTanks() { return outputTanks; }
@Override public FluidTank[] getAllTanks() { return allTanks; }
@Override public Container provideContainer(int ID, EntityPlayer player, World world, int x, int y, int z) { return new ContainerMachineChemicalFactory(player.inventory, this); }
@Override @SideOnly(Side.CLIENT) public Object provideGUI(int ID, EntityPlayer player, World world, int x, int y, int z) { return new GUIMachineChemicalFactory(player.inventory, this); }
@Override public boolean hasPermission(EntityPlayer player) { return this.isUseableByPlayer(player); }
@Override
public void receiveControl(NBTTagCompound data) {
if(data.hasKey("index") && data.hasKey("selection")) {
int index = data.getInteger("index");
String selection = data.getString("selection");
if(index >= 0 && index < 4) {
this.chemplantModule[index].recipe = selection;
this.markChanged();
}
}
}
AxisAlignedBB bb = null;
@Override
public AxisAlignedBB getRenderBoundingBox() {
if(bb == null) bb = AxisAlignedBB.getBoundingBox(xCoord - 2, yCoord, zCoord - 2, xCoord + 3, yCoord + 3, zCoord + 3);
return bb;
}
@Override
@SideOnly(Side.CLIENT)
public double getMaxRenderDistanceSquared() {
return 65536.0D;
}
@Override
public boolean canProvideInfo(UpgradeType type, int level, boolean extendedInfo) {
return type == UpgradeType.SPEED || type == UpgradeType.POWER || type == UpgradeType.OVERDRIVE;
}
@Override
public void provideInfo(UpgradeType type, int level, List<String> info, boolean extendedInfo) {
info.add(IUpgradeInfoProvider.getStandardLabel(ModBlocks.machine_chemical_plant));
if(type == UpgradeType.SPEED) {
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_SPEED, "+" + (level * 100 / 3) + "%"));
info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(KEY_CONSUMPTION, "+" + (level * 50) + "%"));
}
if(type == UpgradeType.POWER) {
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_CONSUMPTION, "-" + (level * 25) + "%"));
}
if(type == UpgradeType.OVERDRIVE) {
info.add((BobMathUtil.getBlink() ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GRAY) + "YES");
}
}
@Override
public HashMap<UpgradeType, Integer> getValidUpgrades() {
HashMap<UpgradeType, Integer> upgrades = new HashMap<>();
upgrades.put(UpgradeType.SPEED, 3);
upgrades.put(UpgradeType.POWER, 3);
upgrades.put(UpgradeType.OVERDRIVE, 3);
return upgrades;
}
public DirPos[] coolantLine; // we could make the same fucking array 50,000 times per tick, or we just make it once
@Override // all the delegating shit so the proxies on the coolant lines only access coolant (and power and inventory) but not the recipe fluids
public Object getDelegateForPosition(int x, int y, int z) {
ForgeDirection dir = ForgeDirection.getOrientation(this.getBlockMetadata() - 10);
ForgeDirection rot = dir.getRotation(ForgeDirection.UP);
if(coolantLine == null) coolantLine = new DirPos[] {
new DirPos(xCoord + rot.offsetX + dir.offsetX * 2, yCoord, zCoord + rot.offsetZ + dir.offsetZ * 2, dir),
new DirPos(xCoord - rot.offsetX + dir.offsetX * 2, yCoord, zCoord - rot.offsetZ + dir.offsetZ * 2, dir),
new DirPos(xCoord + rot.offsetX - dir.offsetX * 2, yCoord, zCoord + rot.offsetZ - dir.offsetZ * 2, dir.getOpposite()),
new DirPos(xCoord - rot.offsetX - dir.offsetX * 2, yCoord, zCoord - rot.offsetZ - dir.offsetZ * 2, dir.getOpposite()),
};
for(DirPos pos : coolantLine) if(pos.compare(x, y, z)) return this.delegate; // this actually fucking works
return null;
}
public class DelegateChemicalFactoy implements IEnergyReceiverMK2, IFluidStandardTransceiverMK2 {
@Override public long getPower() { return TileEntityMachineChemicalFactory.this.getPower(); }
@Override public void setPower(long power) { TileEntityMachineChemicalFactory.this.setPower(power); }
@Override public long getMaxPower() { return TileEntityMachineChemicalFactory.this.getMaxPower(); }
@Override public boolean isLoaded() { return TileEntityMachineChemicalFactory.this.isLoaded(); }
@Override public FluidTank[] getReceivingTanks() { return new FluidTank[] {TileEntityMachineChemicalFactory.this.water}; }
@Override public FluidTank[] getSendingTanks() { return new FluidTank[] {TileEntityMachineChemicalFactory.this.lps}; }
@Override public FluidTank[] getAllTanks() { return TileEntityMachineChemicalFactory.this.getAllTanks(); }
}
}

View File

@ -13,7 +13,9 @@ import com.hbm.inventory.gui.GUIMachineChemicalPlant;
import com.hbm.items.machine.ItemMachineUpgrade;
import com.hbm.items.machine.ItemMachineUpgrade.UpgradeType;
import com.hbm.lib.Library;
import com.hbm.main.MainRegistry;
import com.hbm.module.ModuleMachineChemplant;
import com.hbm.sound.AudioWrapper;
import com.hbm.tileentity.IGUIProvider;
import com.hbm.tileentity.IUpgradeInfoProvider;
import com.hbm.tileentity.TileEntityMachineBase;
@ -46,6 +48,7 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
public boolean frame = false;
public int anim;
public int prevAnim;
private AudioWrapper audio;
public ModuleMachineChemplant chemplantModule;
public UpgradeManagerNT upgradeManager = new UpgradeManagerNT(this);
@ -75,6 +78,8 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
@Override
public void updateEntity() {
if(maxPower <= 0) this.maxPower = 1_000_000;
if(!worldObj.isRemote) {
this.power = Library.chargeTEFromItems(slots, 0, power, maxPower);
@ -93,8 +98,18 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
for(FluidTank tank : inputTanks) if(tank.getTankType() != Fluids.NONE) this.trySubscribe(tank.getTankType(), worldObj, pos);
for(FluidTank tank : outputTanks) if(tank.getFill() > 0) this.tryProvide(tank, worldObj, pos);
}
double speed = 1D;
double pow = 1D;
speed += Math.min(upgradeManager.getLevel(UpgradeType.SPEED), 3) / 3D;
speed += Math.min(upgradeManager.getLevel(UpgradeType.OVERDRIVE), 3);
pow -= Math.min(upgradeManager.getLevel(UpgradeType.POWER), 3) * 0.25D;
pow += Math.min(upgradeManager.getLevel(UpgradeType.SPEED), 3) * 1D;
pow += Math.min(upgradeManager.getLevel(UpgradeType.OVERDRIVE), 3) * 10D / 3D;
this.chemplantModule.update();
this.chemplantModule.update(speed, pow, true);
this.didProcess = this.chemplantModule.didProcess;
if(this.chemplantModule.markDirty) this.markDirty();
@ -108,8 +123,38 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
if(worldObj.getTotalWorldTime() % 20 == 0) {
frame = !worldObj.getBlock(xCoord, yCoord + 3, zCoord).isAir(worldObj, xCoord, yCoord + 3, zCoord);
}
if(this.didProcess && MainRegistry.proxy.me().getDistance(xCoord , yCoord, zCoord) < 50) {
if(audio == null) {
audio = createAudioLoop();
audio.startSound();
} else if(!audio.isPlaying()) {
audio = rebootAudio(audio);
}
audio.keepAlive();
audio.updateVolume(this.getVolume(1F));
} else {
if(audio != null) {
audio.stopSound();
audio = null;
}
}
}
}
@Override public AudioWrapper createAudioLoop() {
return MainRegistry.proxy.getLoopedSound("hbm:block.chemicalPlant", xCoord, yCoord, zCoord, 1F, 15F, 1.0F, 20);
}
@Override public void onChunkUnload() {
if(audio != null) { audio.stopSound(); audio = null; }
}
@Override public void invalidate() {
super.invalidate();
if(audio != null) { audio.stopSound(); audio = null; }
}
public DirPos[] getConPos() {
return new DirPos[] {
@ -158,7 +203,9 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
this.inputTanks[i].readFromNBT(nbt, "i" + i);
this.outputTanks[i].readFromNBT(nbt, "o" + i);
}
this.power = nbt.getLong("power");
this.maxPower = nbt.getLong("maxPower");
this.chemplantModule.readFromNBT(nbt);
}
@ -170,7 +217,9 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
this.inputTanks[i].writeToNBT(nbt, "i" + i);
this.outputTanks[i].writeToNBT(nbt, "o" + i);
}
nbt.setLong("power", power);
nbt.setLong("maxPower", maxPower);
this.chemplantModule.writeToNBT(nbt);
}
@ -184,6 +233,16 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
return false;
}
@Override
public boolean canExtractItem(int i, ItemStack itemStack, int j) {
return i >= 7 && i <= 9;
}
@Override
public int[] getAccessibleSlotsFromSide(int side) {
return new int[] {4, 5, 6, 7, 8, 9};
}
@Override public long getPower() { return power; }
@Override public void setPower(long power) { this.power = power; }
@Override public long getMaxPower() { return maxPower; }
@ -202,8 +261,10 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
if(data.hasKey("index") && data.hasKey("selection")) {
int index = data.getInteger("index");
String selection = data.getString("selection");
if(index == 0) this.chemplantModule.recipe = selection;
this.markChanged();
if(index == 0) {
this.chemplantModule.recipe = selection;
this.markChanged();
}
}
}
@ -223,19 +284,18 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
@Override
public boolean canProvideInfo(UpgradeType type, int level, boolean extendedInfo) {
return false; //return type == UpgradeType.SPEED || type == UpgradeType.POWER || type == UpgradeType.OVERDRIVE;
return type == UpgradeType.SPEED || type == UpgradeType.POWER || type == UpgradeType.OVERDRIVE;
}
@Override
public void provideInfo(UpgradeType type, int level, List<String> info, boolean extendedInfo) {
info.add(IUpgradeInfoProvider.getStandardLabel(ModBlocks.machine_chemical_plant));
if(type == UpgradeType.SPEED) {
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_DELAY, "-" + (level * 25) + "%"));
info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(KEY_CONSUMPTION, "+" + (level * 300) + "%"));
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_SPEED, "+" + (level * 100 / 3) + "%"));
info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(KEY_CONSUMPTION, "+" + (level * 50) + "%"));
}
if(type == UpgradeType.POWER) {
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_CONSUMPTION, "-" + (level * 30) + "%"));
info.add(EnumChatFormatting.RED + I18nUtil.resolveKey(KEY_DELAY, "+" + (level * 5) + "%"));
info.add(EnumChatFormatting.GREEN + I18nUtil.resolveKey(KEY_CONSUMPTION, "-" + (level * 25) + "%"));
}
if(type == UpgradeType.OVERDRIVE) {
info.add((BobMathUtil.getBlink() ? EnumChatFormatting.RED : EnumChatFormatting.DARK_GRAY) + "YES");
@ -247,7 +307,7 @@ public class TileEntityMachineChemicalPlant extends TileEntityMachineBase implem
HashMap<UpgradeType, Integer> upgrades = new HashMap<>();
upgrades.put(UpgradeType.SPEED, 3);
upgrades.put(UpgradeType.POWER, 3);
upgrades.put(UpgradeType.OVERDRIVE, 6);
upgrades.put(UpgradeType.OVERDRIVE, 3);
return upgrades;
}
}

View File

@ -74,7 +74,7 @@ public class TileEntityMachineTurbineGas extends TileEntityMachineBase implement
fuelMaxCons.put(Fluids.GAS, 50D); // natgas doesn't burn well so it burns faster to compensate
fuelMaxCons.put(Fluids.SYNGAS, 10D); // syngas just fucks
fuelMaxCons.put(Fluids.OXYHYDROGEN, 100D); // oxyhydrogen is terrible so it needs to burn a ton for the bare minimum
fuelMaxCons.put(Fluids.REFORMGAS, 5D); // fuck it we ball
fuelMaxCons.put(Fluids.REFORMGAS, 5D); // fuck it we ball
// default to 5 if not in list
}
@ -166,17 +166,18 @@ public class TileEntityMachineTurbineGas extends TileEntityMachineBase implement
if(audio == null) { //if there is no sound playing, start it
audio = MainRegistry.proxy.getLoopedSound("hbm:block.turbinegasRunning", xCoord, yCoord, zCoord, getVolume(1.0F), 20F, 2.0F);
audio = MainRegistry.proxy.getLoopedSound("hbm:block.turbinegasRunning", xCoord, yCoord, zCoord, getVolume(1.0F), 20F, 2.0F, 20);
audio.startSound();
} else if(!audio.isPlaying()) {
audio.stopSound();
audio = MainRegistry.proxy.getLoopedSound("hbm:block.turbinegasRunning", xCoord, yCoord, zCoord, getVolume(1.0F), 20F, 2.0F);
audio = MainRegistry.proxy.getLoopedSound("hbm:block.turbinegasRunning", xCoord, yCoord, zCoord, getVolume(1.0F), 20F, 2.0F, 20);
audio.startSound();
}
audio.updatePitch((float) (0.55 + 0.1 * rpm / 10)); //dynamic pitch update based on rpm
audio.updateVolume(getVolume(2F)); //yeah i need this
audio.keepAlive();
} else {

View File

@ -1,32 +0,0 @@
package com.hbm.util;
import net.minecraft.world.ChunkCoordIntPair;
import java.util.Objects;
/**
* Unique identifier for sub-chunks.
* @Author mlbv
*/
public class ChunkKey {
public final ChunkCoordIntPair pos;
public final int subY;
public ChunkKey(int cx, int cz, int sy) {
this.pos = new ChunkCoordIntPair(cx, cz);
this.subY = sy;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof ChunkKey)) return false;
ChunkKey k = (ChunkKey) o;
return subY == k.subY && pos.equals(k.pos);
}
@Override
public int hashCode() {
return Objects.hash(pos.chunkXPos, pos.chunkZPos, subY);
}
}

View File

@ -218,7 +218,7 @@ public class DamageResistanceHandler {
registerSet(ModItems.dns_helmet, ModItems.dns_plate, ModItems.dns_legs, ModItems.dns_boots, new ResistanceStats()
.addCategory(CATEGORY_EXPLOSION, 100F, 0.99F)
.addCategory(CATEGORY_FIRE, 0F, 1F)
.setOther(100F, 1F));
.setOther(1000F, 1F));
registerSet(ModItems.taurun_helmet, ModItems.taurun_plate, ModItems.taurun_legs, ModItems.taurun_boots, new ResistanceStats()
.addCategory(CATEGORY_PROJECTILE, 2F, 0.15F)
.addCategory(CATEGORY_FIRE, 0F, 0.25F)

View File

@ -3,7 +3,6 @@ package com.hbm.util;
import com.google.common.collect.Sets;
import com.hbm.config.GeneralConfig;
import com.hbm.main.MainRegistry;
import com.hbm.main.ModEventHandler;
import cpw.mods.fml.relauncher.ReflectionHelper;
import java.lang.reflect.Field;
@ -147,7 +146,7 @@ public class ShadyUtil {
System.out.println("TEST SECTION START");
Class toLoad = Class.forName(decode(offset(testCase, -2)));
Field toRead = ReflectionHelper.findField(toLoad, decode(offset(testValue, -2)));
if(new Random().nextInt(4) == 0) ModEventHandler.reference = toRead;
//ModEventHandler.reference = toRead;
System.out.println("TEST SECTION END");
}
} catch(Throwable e) { }

View File

@ -0,0 +1,63 @@
package com.hbm.util;
import net.minecraft.world.ChunkCoordIntPair;
/**
* Unique identifier for sub-chunks.
* @author mlbv
*/
public class SubChunkKey {
private int chunkXPos;
private int chunkZPos;
private int subY;
private int hash;
public SubChunkKey(int cx, int cz, int sy) {
this.update(cx, cz, sy);
}
public SubChunkKey(ChunkCoordIntPair pos, int sy) {
this.update(pos.chunkXPos, pos.chunkZPos, sy);
}
public SubChunkKey update(int cx, int cz, int sy) {
this.chunkXPos = cx;
this.chunkZPos = cz;
this.subY = sy;
int result = subY;
result = 31 * result + cx;
result = 31 * result + cz;
this.hash = result;
return this;
}
@Override
public final int hashCode() {
return this.hash;
}
@Override
public final boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof SubChunkKey)) return false;
SubChunkKey k = (SubChunkKey) o;
return this.subY == k.subY && this.chunkXPos == k.chunkXPos && this.chunkZPos == k.chunkZPos;
}
public int getSubY() {
return subY;
}
public int getChunkXPos() {
return chunkXPos;
}
public int getChunkZPos() {
return chunkZPos;
}
public ChunkCoordIntPair getPos() {
return new ChunkCoordIntPair(this.chunkXPos, this.chunkZPos);
}
}

View File

@ -2,7 +2,6 @@ package com.hbm.util;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.world.ChunkCoordIntPair;
import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
@ -14,7 +13,7 @@ import java.util.Map;
/**
* A snapshot of a 16×16×16 sub-chunk.
* @Author mlbv
* @author mlbv
*/
public class SubChunkSnapshot {
/**
@ -29,42 +28,25 @@ public class SubChunkSnapshot {
this.data = d;
}
/**
* Creates a SubChunkSnapshot from a loaded chunk.
*
* @param world
* The World instance from which to retrieve the chunk.
* @param cpos
* The ChunkCoordIntPair identifying the chunk coordinates (x, z).
* @param subY
* The vertical sub-chunk index (015) within the chunk.
* @return
* A SubChunkSnapshot containing the palette and block data for the sub-chunk,
* or SubChunkSnapshot.EMPTY if the region is unloaded or contains only air.
*/
public static SubChunkSnapshot getSnapshot(World world, ChunkCoordIntPair cpos, int subY) {
if (!world.getChunkProvider().chunkExists(cpos.chunkXPos, cpos.chunkZPos)) {
return SubChunkSnapshot.EMPTY;
}
return getOrLoadSnapshot(world, cpos, subY);
}
/**
* Creates a SubChunkSnapshot.
*
* @param world
* The World instance from which to retrieve the chunk.
* @param cpos
* The ChunkCoordIntPair identifying the chunk coordinates (x, z).
* @param subY
* The vertical sub-chunk index (015) within the chunk.
* @param key
* The SubChunkKey identifying the sub-chunk.
* @param allowGeneration
* Whether to generate chunks. If false, attempting to retrieve a snapshot of a chunk that does not exist will return {@link SubChunkSnapshot#EMPTY}.
* @return
* A SubChunkSnapshot containing the palette and block data for the sub-chunk,
* or SubChunkSnapshot.EMPTY if the region contains only air.
* or {@link SubChunkSnapshot#EMPTY} if the region contains only air.
*/
public static SubChunkSnapshot getOrLoadSnapshot(World world, ChunkCoordIntPair cpos, int subY){
Chunk chunk = world.getChunkFromChunkCoords(cpos.chunkXPos, cpos.chunkZPos);
ExtendedBlockStorage ebs = chunk.getBlockStorageArray()[subY];
public static SubChunkSnapshot getSnapshot(World world, SubChunkKey key, boolean allowGeneration){
if (!world.getChunkProvider().chunkExists(key.getChunkXPos(), key.getChunkZPos()) && !allowGeneration) {
return SubChunkSnapshot.EMPTY;
}
Chunk chunk = world.getChunkProvider().provideChunk(key.getChunkXPos(), key.getChunkZPos());
ExtendedBlockStorage ebs = chunk.getBlockStorageArray()[key.getSubY()];
if (ebs == null || ebs.isEmpty()) return SubChunkSnapshot.EMPTY;
short[] data = new short[16 * 16 * 16];

View File

@ -372,6 +372,7 @@ container.machineAmmoPress=Munitionspresse
container.machineArcWelder=Lichtbogenschweißer
container.machineArcFurnaceLarge=Lichtbogenofen
container.machineBoiler=Ölwärmer
container.machineChemicalFactory=Chemiefabrik
container.machineChemicalPlant=Chemiewerk
container.machineCMB=CMB-Stahl Hochofen
container.machineCoal=Verbrennungsgenerator
@ -4357,9 +4358,10 @@ tile.machine_boiler_off.name=Alter Boiler
tile.machine_catalytic_cracker.name=Katalytischer Cracking-Turm
tile.machine_catalytic_reformer.name=Katalytischer Reformer
tile.machine_centrifuge.name=Zentrifuge
tile.machine_chemfac.name=Chemiefabrik
tile.machine_chemical_plant.name=Chemiewerk 2: Electric Boogaloo
tile.machine_chemplant.name=Chemiewerk
tile.machine_chemfac.name=Chemiefabrik (Legacy)
tile.machine_chemical_factory.name=Chemiefabrik
tile.machine_chemical_plant.name=Chemiewerk
tile.machine_chemplant.name=Chemiewerk (Legacy)
tile.machine_chungus.name=Leviathan-Dampfturbine
tile.machine_chungus.desc=Effizienz: 85%%
tile.machine_coal_off.name=Verbrennungsgenerator

View File

@ -774,6 +774,7 @@ container.machineAmmoPress=Ammo Press
container.machineArcWelder=Arc Welder
container.machineArcFurnaceLarge=Arc Furnace
container.machineBoiler=Oil Heater
container.machineChemicalFactory=Chemical Factory
container.machineChemicalPlant=Chemical Plant
container.machineCMB=CMB Steel Furnace
container.machineCoal=Combustion Generator
@ -5489,9 +5490,11 @@ tile.machine_boiler_off.name=Old Boiler
tile.machine_catalytic_cracker.name=Catalytic Cracking Tower
tile.machine_catalytic_reformer.name=Catalytic Reformer
tile.machine_centrifuge.name=Centrifuge
tile.machine_chemfac.name=Chemical Factory
tile.machine_chemical_plant.name=Chemical Plant 2: Electric Boogaloo
tile.machine_chemplant.name=Chemical Plant
tile.machine_chemfac.name=Chemical Factory (Legacy)
tile.machine_chemical_factory.name=Chemical Factory
tile.machine_chemical_factory.desc=Quadruple chemical plant.$Recipes process twice as fast,$but needs twice as much power.$Needs to be cooled with water,$produces low-pressure steam.
tile.machine_chemical_plant.name=Chemical Plant
tile.machine_chemplant.name=Chemical Plant (Legacy)
tile.machine_chungus.name=Leviathan Steam Turbine
tile.machine_chungus.desc=Efficiency: 85%%
tile.machine_coal_off.name=Combustion Generator
@ -6172,6 +6175,7 @@ upgrade.fortune=Fortune %s
upgrade.overheatChance=Overheat chance %s
upgrade.productivity=Productivity %s
upgrade.range=Range %s
upgrade.speed=Process speed %s
upgrade.gui.title=§lAcceptable Upgrades:§r
upgrade.gui.afterburner= * §dAfterburner§r: Stacks to level %s

File diff suppressed because it is too large Load Diff

View File

@ -67,6 +67,7 @@
"block.pyroOperate": {"category": "block", "sounds": [{"name": "block/pyroOperate", "stream": false}]},
"block.motor": {"category": "block", "sounds": [{"name": "block/motor", "stream": false}]},
"block.engine": {"category": "block", "sounds": [{"name": "block/engine", "stream": false}]},
"block.chemicalPlant": {"category": "block", "sounds": [{"name": "block/chemicalPlant", "stream": false}]},
"door.TransitionSealOpen": {"category": "block", "sounds": [{"name": "block/door/transition_seal_open", "stream": true}]},
"door.wghStart": {"category": "block", "sounds": [{"name": "block/door/wgh_start", "stream": true}]},

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

After

Width:  |  Height:  |  Size: 312 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 430 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB