1111import gregtech .api .metatileentity .MetaTileEntity ;
1212import gregtech .api .metatileentity .MetaTileEntityHolder ;
1313import gregtech .api .metatileentity .TieredMetaTileEntity ;
14- import gregtech .api .pipenet .tile .TileEntityPipeBase ;
1514import gregtech .api .render .Textures ;
15+ import gregtech .common .ConfigHolder ;
16+ import net .minecraft .block .Block ;
1617import net .minecraft .block .state .IBlockState ;
1718import net .minecraft .client .resources .I18n ;
1819import net .minecraft .entity .player .EntityPlayer ;
2728import net .minecraft .util .math .BlockPos ;
2829import net .minecraft .util .text .TextComponentTranslation ;
2930import net .minecraft .world .World ;
30- import net .minecraft .world .WorldServer ;
3131import net .minecraftforge .common .capabilities .Capability ;
3232import net .minecraftforge .fml .common .FMLCommonHandler ;
3333
3434import javax .annotation .Nullable ;
3535import java .util .List ;
36- import java .util .stream . IntStream ;
36+ import java .util .function . Supplier ;
3737
3838import static gregtech .api .capability .GregtechDataCodes .IS_WORKING ;
3939import static gregtech .api .capability .GregtechDataCodes .SYNC_TILE_MODE ;
4040
4141public 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