Skip to content

Commit f81e7b2

Browse files
authored
Reworked World Accelerator (#188)
* Reworked World Accelerator Discussion: - Support CoFH explicitly? (In Gregification or in CEu itself?) - EU/t is high rn, it needs (8 * tier) EU/t per operation (but blocks are affected all at once with one energy extract) - Liquids are able to be accelerated, most tick accelerators do this, Torcherino does not. - RNG for block random updates are set as a constant (1/100), change with tiers? * Config option to accelerate GT machines or not * tier / 100 chance to tick a Block - Removed fixme's * energyPerTick is halved when in Non TE mode
1 parent df4c08b commit f81e7b2

2 files changed

Lines changed: 70 additions & 52 deletions

File tree

src/main/java/gregtech/common/ConfigHolder.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,10 @@ public static class GT5U {
237237
@Config.Comment("Enable World Accelerators, which accelerate ticks. Default: true")
238238
@Config.RequiresMcRestart
239239
public boolean enableWorldAccelerators = true;
240+
241+
@Config.Comment("Allow GT machines to be affected by World Accelerators. Default: false")
242+
@Config.RequiresMcRestart
243+
public boolean accelerateGTMachines = false;
240244
}
241245

242246
public static class GT6 {

src/main/java/gregtech/common/metatileentities/electric/MetaTileEntityWorldAccelerator.java

Lines changed: 66 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@
1111
import gregtech.api.metatileentity.MetaTileEntity;
1212
import gregtech.api.metatileentity.MetaTileEntityHolder;
1313
import gregtech.api.metatileentity.TieredMetaTileEntity;
14-
import gregtech.api.pipenet.tile.TileEntityPipeBase;
1514
import gregtech.api.render.Textures;
15+
import gregtech.common.ConfigHolder;
16+
import net.minecraft.block.Block;
1617
import net.minecraft.block.state.IBlockState;
1718
import net.minecraft.client.resources.I18n;
1819
import net.minecraft.entity.player.EntityPlayer;
@@ -27,38 +28,47 @@
2728
import net.minecraft.util.math.BlockPos;
2829
import net.minecraft.util.text.TextComponentTranslation;
2930
import net.minecraft.world.World;
30-
import net.minecraft.world.WorldServer;
3131
import net.minecraftforge.common.capabilities.Capability;
3232
import net.minecraftforge.fml.common.FMLCommonHandler;
3333

3434
import javax.annotation.Nullable;
3535
import java.util.List;
36-
import java.util.stream.IntStream;
36+
import java.util.function.Supplier;
3737

3838
import static gregtech.api.capability.GregtechDataCodes.IS_WORKING;
3939
import static gregtech.api.capability.GregtechDataCodes.SYNC_TILE_MODE;
4040

4141
public class MetaTileEntityWorldAccelerator extends TieredMetaTileEntity implements IControllable {
4242

43-
private static Class<?> clazz;
43+
private static Class<?> cofhTileClass;
4444

45-
static {
46-
try {
47-
clazz = Class.forName("cofh.core.block.TileCore");
48-
} catch (Exception ignored) {}
45+
private static boolean considerTile(TileEntity tile) {
46+
if (!ConfigHolder.U.GT5u.accelerateGTMachines && tile instanceof MetaTileEntityHolder) {
47+
return false;
48+
}
49+
if (cofhTileClass == null) {
50+
try {
51+
cofhTileClass = Class.forName("cofh.thermalexpansion.block.device.TileDeviceBase");
52+
} catch (Exception ignored) {}
53+
}
54+
return cofhTileClass == null || !cofhTileClass.isInstance(tile);
4955
}
5056

5157
private final long energyPerTick;
58+
private final int speed;
59+
5260
private boolean tileMode = false;
5361
private boolean isActive = false;
5462
private boolean isPaused = false;
5563
private int lastTick;
64+
private Supplier<Iterable<BlockPos.MutableBlockPos>> range;
5665

5766
public MetaTileEntityWorldAccelerator(ResourceLocation metaTileEntityId, int tier) {
5867
super(metaTileEntityId, tier);
5968
//consume 8 amps
6069
this.energyPerTick = GTValues.V[tier] * getMaxInputOutputAmperage();
6170
this.lastTick = 0;
71+
this.speed = (int) Math.pow(2, tier);
6272
initializeInventory();
6373
}
6474

@@ -73,83 +83,88 @@ public void addInformation(ItemStack stack, @Nullable World player, List<String>
7383
tooltip.add(I18n.format("gregtech.universal.tooltip.amperage_in", getMaxInputOutputAmperage()));
7484
tooltip.add(I18n.format("gregtech.universal.tooltip.energy_storage_capacity", energyContainer.getEnergyCapacity()));
7585
tooltip.add(I18n.format("gregtech.machine.world_accelerator.description"));
76-
tooltip.add(I18n.format("gregtech.machine.world_accelerator.area", getArea(), getArea()));
86+
int area = getTier() * 2;
87+
tooltip.add(I18n.format("gregtech.machine.world_accelerator.area", area, area));
7788
}
7889

7990
@Override
8091
protected long getMaxInputOutputAmperage() {
8192
return 8L;
8293
}
8394

84-
// TODO This could use a re-write
8595
@Override
8696
public void update() {
8797
super.update();
88-
if (!getWorld().isRemote && lastTick != FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter()) {
89-
lastTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter();
98+
if (!getWorld().isRemote) {
9099
if (isPaused) {
91-
if (isActive)
100+
if (isActive) {
92101
setActive(false);
102+
}
93103
return;
94104
}
95105
if (energyContainer.getEnergyStored() < energyPerTick) {
96-
if (isActive)
106+
if (isActive) {
97107
setActive(false);
108+
}
98109
return;
99110
}
100-
if (!isActive)
111+
if (!isActive) {
101112
setActive(true);
102-
energyContainer.removeEnergy(energyPerTick);
103-
WorldServer world = (WorldServer) this.getWorld();
104-
BlockPos worldAcceleratorPos = getPos();
105-
if (isTEMode()) {
106-
BlockPos[] neighbours = new BlockPos[]{worldAcceleratorPos.down(), worldAcceleratorPos.up(), worldAcceleratorPos.north(), worldAcceleratorPos.south(), worldAcceleratorPos.east(), worldAcceleratorPos.west()};
107-
for (BlockPos neighbour : neighbours) {
108-
TileEntity targetTE = world.getTileEntity(neighbour);
109-
if (targetTE == null || targetTE instanceof TileEntityPipeBase || targetTE instanceof MetaTileEntityHolder) {
110-
continue;
111-
}
112-
boolean horror = false;
113-
if (clazz != null && targetTE instanceof ITickable) {
114-
horror = clazz.isInstance(targetTE);
113+
}
114+
int currentTick = FMLCommonHandler.instance().getMinecraftServerInstance().getTickCounter();
115+
if (currentTick != lastTick) { // Prevent other tick accelerators from accelerating us
116+
World world = getWorld();
117+
BlockPos currentPos = getPos();
118+
lastTick = currentTick;
119+
if (isTEMode()) {
120+
energyContainer.removeEnergy(energyPerTick);
121+
for (EnumFacing neighbourFace : EnumFacing.VALUES) {
122+
TileEntity neighbourTile = world.getTileEntity(currentPos.offset(neighbourFace));
123+
if (neighbourTile instanceof ITickable && !neighbourTile.isInvalid() && considerTile(neighbourTile)) {
124+
ITickable neighbourTickTile = (ITickable) neighbourTile;
125+
for (int i = 0; i < speed; i++) {
126+
neighbourTickTile.update();
127+
}
128+
}
115129
}
116-
if (targetTE instanceof ITickable && (!horror || !world.isRemote)) {
117-
IntStream.range(0, (int) Math.pow(2, getTier())).forEach(value -> ((ITickable) targetTE).update());
130+
} else {
131+
energyContainer.removeEnergy(energyPerTick / 2);
132+
if (range == null) {
133+
int area = getTier() * 2;
134+
range = () -> BlockPos.getAllInBoxMutable(currentPos.add(-area, -area, -area), currentPos.add(area, area, area));
118135
}
119-
}
120-
} else {
121-
BlockPos upperConner = worldAcceleratorPos.north(getTier()).east(getTier());
122-
for (int x = 0; x < getArea(); x++) {
123-
BlockPos row = upperConner.south(x);
124-
for (int y = 0; y < getArea(); y++) {
125-
BlockPos cell = row.west(y);
126-
127-
IBlockState targetBlock = world.getBlockState(cell);
128-
IntStream.range(0, (int) Math.pow(2, getTier())).forEach(value -> {
129-
if (GTValues.RNG.nextInt(100) == 0) {
130-
if (targetBlock.getBlock().getTickRandomly()) {
131-
targetBlock.getBlock().randomTick(world, cell, targetBlock, world.rand);
136+
for (BlockPos.MutableBlockPos pos : range.get()) {
137+
if (pos.getY() > 256 || pos.getY() < 0) { // Early termination
138+
continue;
139+
}
140+
if (world.isBlockLoaded(pos)) {
141+
for (int i = 0; i < speed; i++) {
142+
if (GTValues.RNG.nextInt(getTier() / 100) == 0) {
143+
// Rongmario:
144+
// randomTick instead of updateTick since some modders can mistake where to put their code.
145+
// Fresh IBlockState before every randomTick, this could easily change after every randomTick call
146+
IBlockState state = world.getBlockState(pos);
147+
Block block = state.getBlock();
148+
if (block.getTickRandomly()) {
149+
block.randomTick(world, pos.toImmutable(), state, world.rand);
150+
}
132151
}
133152
}
134-
});
153+
}
135154
}
136155
}
137156
}
138157
}
139-
140-
}
141-
142-
public int getArea() {
143-
return (getTier() * 2) + 1;
144158
}
145159

146160
@Override
147161
public void renderMetaTileEntity(CCRenderState renderState, Matrix4 translation, IVertexOperation[] pipeline) {
148162
super.renderMetaTileEntity(renderState, translation, pipeline);
149-
if (isTEMode())
163+
if (isTEMode()) {
150164
Textures.WORLD_ACCELERATOR_TE_OVERLAY.render(renderState, translation, pipeline, getFrontFacing(), isActive);
151-
else
165+
} else {
152166
Textures.WORLD_ACCELERATOR_OVERLAY.render(renderState, translation, pipeline, getFrontFacing(), isActive);
167+
}
153168
}
154169

155170
@Override
@@ -179,7 +194,6 @@ public boolean onScrewdriverClick(EntityPlayer playerIn, EnumHand hand, EnumFaci
179194
public void setTEMode(boolean inverted) {
180195
tileMode = inverted;
181196
if (!getWorld().isRemote) {
182-
reinitializeEnergyContainer();
183197
writeCustomData(SYNC_TILE_MODE, b -> b.writeBoolean(tileMode));
184198
getHolder().notifyBlockUpdate();
185199
markDirty();

0 commit comments

Comments
 (0)