Integrated tile entity initialisation
This commit is contained in:
parent
9d8e6ea7fe
commit
1b7eda2ce8
3 changed files with 190 additions and 3 deletions
162
src/api/java/lem/warpdrive/TileEntity_initialisation.puml
Normal file
162
src/api/java/lem/warpdrive/TileEntity_initialisation.puml
Normal file
|
@ -0,0 +1,162 @@
|
|||
@startuml
|
||||
actor "Forge or\na Mod" as anyMod
|
||||
participant Forge #cyan
|
||||
participant World #cyan
|
||||
participant Chunk #cyan
|
||||
participant Entity #cyan
|
||||
participant TileEntity #cyan
|
||||
'participant WarpDrive
|
||||
|
||||
anyMod -> World: addTileEntity(tileEntity)
|
||||
activate World
|
||||
World -[#blue]> TileEntity: setWorld
|
||||
World <-[#blue]- TileEntity
|
||||
alt processingLoadedTiles
|
||||
World -[#blue]> World: addedTileEntityList.add()
|
||||
else
|
||||
World -[#blue]> World: loadedTileEntityList.add()
|
||||
alt instanceof ITickable
|
||||
World -[#blue]> World: tickableTileEntities.add()
|
||||
end
|
||||
World -[#blue]> TileEntity: onLoad
|
||||
World <-[#blue]- TileEntity
|
||||
alt isRemote
|
||||
World -[#blue]> World: notifyBlockUpdate
|
||||
end
|
||||
end
|
||||
anyMod <-- World
|
||||
deactivate World
|
||||
|
||||
anyMod -> World: addTileEntities(tileEntities)
|
||||
activate World
|
||||
alt processingLoadedTiles
|
||||
loop tileEntities with no world set
|
||||
World -[#blue]> TileEntity: setWorld
|
||||
World <-[#blue]- TileEntity
|
||||
end
|
||||
World -[#blue]> World: addedTileEntityList.addAll
|
||||
else
|
||||
loop tileEntities
|
||||
World -[#blue]> World: <b>addTileEntity(tileEntity)
|
||||
end
|
||||
end
|
||||
anyMod <-- World
|
||||
deactivate World
|
||||
|
||||
anyMod -> World: setTileEntity(pos, tileEntity)
|
||||
activate World
|
||||
alt processingLoadedTiles
|
||||
World -[#blue]> TileEntity: setPos
|
||||
World <-[#blue]- TileEntity
|
||||
World -[#blue]> TileEntity: setWorld
|
||||
World <-[#blue]- TileEntity
|
||||
loop addedTileEntityList with same position
|
||||
World -[#blue]> TileEntity: invalidate
|
||||
World <-[#blue]- TileEntity
|
||||
World -[#blue]> World: remove
|
||||
end
|
||||
World -[#blue]> World: addedTileEntityList.add
|
||||
else
|
||||
World -[#blue]> Chunk: <b>addTileEntity(pos, tileEntity)
|
||||
activate Chunk
|
||||
alt tileEntity.world == null
|
||||
Chunk -[#blue]> TileEntity: setWorld(...)
|
||||
Chunk <-[#blue]- TileEntity
|
||||
end
|
||||
Chunk -[#blue]> TileEntity: setPos(...)
|
||||
Chunk <-[#blue]- TileEntity
|
||||
|
||||
alt block.hasTileEntity(blockState)
|
||||
alt tileEntities.contains(tileEntity)
|
||||
Chunk -[#blue]> TileEntity: invalidate()
|
||||
Chunk <-[#blue]- TileEntity
|
||||
end
|
||||
Chunk -[#blue]> TileEntity: validate()
|
||||
Chunk <-[#blue]- TileEntity
|
||||
Chunk -[#blue]> Chunk: tileEntities.put
|
||||
end
|
||||
World <-[#blue]- Chunk
|
||||
deactivate Chunk
|
||||
end
|
||||
anyMod <-- World
|
||||
deactivate World
|
||||
|
||||
anyMod -> Chunk: addTileEntity(tileEntity)
|
||||
activate Chunk
|
||||
Chunk -[#blue]> Chunk: addTileEntity(getPos, tileEntity)
|
||||
alt loaded
|
||||
Chunk -[#blue]> World: <b>addTileEntity(tileEntity)
|
||||
Chunk <-[#blue]- World
|
||||
end
|
||||
anyMod <-- Chunk
|
||||
deactivate Chunk
|
||||
|
||||
Forge -[#blue]> World: updateEntities()
|
||||
activate World
|
||||
|
||||
loop weather entities, not blocked
|
||||
World -[#blue]> Entity: ticksExisted++
|
||||
World -[#blue]> Entity: onUpdate()
|
||||
World <-[#blue]- Entity
|
||||
alt entity.isDead
|
||||
World -[#blue]> World: remove
|
||||
end
|
||||
end
|
||||
|
||||
World -[#blue]> World: <I>remove unloaded entities
|
||||
World -[#blue]> World: tickPlayers()
|
||||
loop entities
|
||||
World -[#blue]> World: <I>dismount dead riders
|
||||
World -[#blue]> World: updateEntity(entity)
|
||||
activate World
|
||||
World -[#blue]> World: updateEntityWithOptionalForce()
|
||||
activate World
|
||||
...canEntityUpdate(entity)...
|
||||
World -> Entity: updateRidden() or onUpdate()
|
||||
World <-- Entity
|
||||
...update holding chunk, etc....
|
||||
World <-- World
|
||||
deactivate World
|
||||
World <-- World
|
||||
deactivate World
|
||||
|
||||
World -[#blue]> World: <I>remove dead entity
|
||||
end
|
||||
|
||||
World -[#blue]> World: processingLoadedTiles = true
|
||||
loop tileEntitiesToBeRemoved
|
||||
World -[#blue]> TileEntity: onChunkUnload()
|
||||
World <-[#blue]- TileEntity
|
||||
end
|
||||
loop tickableTileEntities
|
||||
alt ! tileEntity.isInvalid()
|
||||
World -[#blue]> TileEntity: update()
|
||||
World <-[#blue]- TileEntity
|
||||
end
|
||||
alt tileEntity.isInvalid()
|
||||
World -[#blue]> World: loadedTileEntityList.remove
|
||||
alt isBlockLoaded, ...
|
||||
World -[#blue]> Chunk: removeTileEntity(pos)
|
||||
World <-[#blue]- Chunk
|
||||
end
|
||||
end
|
||||
end
|
||||
World -[#blue]> World: processingLoadedTiles = false
|
||||
loop addedTileEntityList
|
||||
alt ! tileEntity.isInvalid()
|
||||
alt ! loadedTileEntityList.contains(tileEntity)
|
||||
World -[#blue]> World: <b>addTileEntity(tileEntity)
|
||||
end
|
||||
alt isBlockLoaded
|
||||
World -[#blue]> Chunk: <b>addTileEntity(pos, tileEntity)
|
||||
World <-[#blue]- Chunk
|
||||
World -[#blue]> World: notifyBlockUpdate(...)
|
||||
end
|
||||
end
|
||||
end
|
||||
World -[#blue]> Chunk: addedTileEntityList.clear
|
||||
|
||||
Forge <-[#blue]- World
|
||||
deactivate World
|
||||
|
||||
@enduml
|
|
@ -45,6 +45,7 @@ public abstract class TileEntityAbstractBase extends TileEntity implements IBloc
|
|||
// (none)
|
||||
|
||||
// computed properties
|
||||
private boolean isConstructed = false;
|
||||
private boolean isFirstTick = true;
|
||||
private boolean isDirty = false;
|
||||
|
||||
|
@ -57,6 +58,16 @@ public abstract class TileEntityAbstractBase extends TileEntity implements IBloc
|
|||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
assert hasWorld() && pos != BlockPos.ORIGIN;
|
||||
if (!isConstructed) {
|
||||
onConstructed();
|
||||
}
|
||||
}
|
||||
|
||||
protected void onConstructed() {
|
||||
// warning: we can't use Block.CreateNewTileEntity() as world loading calls the TileEntity constructor directly
|
||||
// warning: we can't use setPos(), setWorld() or validate() as getBlockType() will cause a stack overflow
|
||||
// warning: we can't use onLoad() to trigger this method as onLoad() isn't always called, see https://github.com/MinecraftForge/MinecraftForge/issues/5061
|
||||
|
||||
// immediately retrieve tier, we need it to connect energy conduits and save the world before the first tick
|
||||
final Block block = getBlockType();
|
||||
|
@ -67,10 +78,13 @@ public abstract class TileEntityAbstractBase extends TileEntity implements IBloc
|
|||
this, Commons.format(world, pos), block));
|
||||
enumTier = EnumTier.BASIC;
|
||||
}
|
||||
|
||||
isConstructed = true;
|
||||
}
|
||||
|
||||
protected void onFirstUpdateTick() {
|
||||
// No operation
|
||||
assert isConstructed;
|
||||
assert enumTier != null;
|
||||
}
|
||||
|
||||
|
@ -93,6 +107,9 @@ public abstract class TileEntityAbstractBase extends TileEntity implements IBloc
|
|||
@Override
|
||||
public void onBlockUpdateDetected() {
|
||||
assert Commons.isSafeThread();
|
||||
if (!isConstructed) {
|
||||
onConstructed();
|
||||
}
|
||||
}
|
||||
|
||||
protected <T extends Comparable<T>, V extends T> void updateBlockState(final IBlockState blockState_in, final IProperty<T> property, final V value) {
|
||||
|
|
|
@ -67,8 +67,8 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
public void onConstructed() {
|
||||
super.onConstructed();
|
||||
|
||||
energyStored_max = WarpDriveConfig.ENAN_REACTOR_MAX_ENERGY_STORED_BY_TIER[enumTier.getIndex()];
|
||||
generation_offset = WarpDriveConfig.ENAN_REACTOR_GENERATION_MIN_RF_BY_TIER[enumTier.getIndex()];
|
||||
|
@ -538,7 +538,7 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
|
|||
|
||||
@Override
|
||||
public int energy_getMaxStorage() {
|
||||
return (int) convertRFtoInternal_floor(WarpDriveConfig.ENAN_REACTOR_MAX_ENERGY_STORED_BY_TIER[enumTier.getIndex()]);
|
||||
return (int) convertRFtoInternal_floor(energyStored_max);
|
||||
}
|
||||
|
||||
// Forge overrides
|
||||
|
@ -565,7 +565,15 @@ public class TileEntityEnanReactorCore extends TileEntityEnanReactorController {
|
|||
public void readFromNBT(final NBTTagCompound tagCompound) {
|
||||
super.readFromNBT(tagCompound);
|
||||
|
||||
// skip empty NBT on placement to use defaults values
|
||||
if (!tagCompound.hasKey("outputMode")) {
|
||||
return;
|
||||
}
|
||||
|
||||
enumReactorOutputMode = EnumReactorOutputMode.byName(tagCompound.getString("outputMode"));
|
||||
if (enumReactorOutputMode == null) {
|
||||
enumReactorOutputMode = EnumReactorOutputMode.OFF;
|
||||
}
|
||||
outputThreshold = tagCompound.getInteger("outputThreshold");
|
||||
instabilityTarget = tagCompound.getDouble("instabilityTarget");
|
||||
stabilizerEnergy = tagCompound.getInteger("stabilizerEnergy");
|
||||
|
|
Loading…
Add table
Reference in a new issue