mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-29 08:27:03 +01:00
Merge pull request #1613 from reidbhuntley/schematics-crash
Various bugfixes regarding schematics
This commit is contained in:
commit
aea44aa3fb
19 changed files with 323 additions and 95 deletions
|
@ -409,19 +409,19 @@ a3a11524cd3515fc01d905767b4b7ea782adaf03 assets/create/blockstates/yellow_seat.j
|
||||||
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
b7181bcd8182b2f17088e5aa881f374c9c65470c assets/create/blockstates/zinc_ore.json
|
||||||
a6d814f94926d88764c38862cc4ece9c367e023b assets/create/lang/en_ud.json
|
a6d814f94926d88764c38862cc4ece9c367e023b assets/create/lang/en_ud.json
|
||||||
d1838140c8383ee4537db90eb8f657d0c268fe91 assets/create/lang/en_us.json
|
d1838140c8383ee4537db90eb8f657d0c268fe91 assets/create/lang/en_us.json
|
||||||
9d6f26ca7b59d3707ce996e513358cc9b873cad1 assets/create/lang/unfinished/de_de.json
|
4fcda300efe5a2ad8695b5ae3f24a54ea109a954 assets/create/lang/unfinished/de_de.json
|
||||||
7fafb7565349aa52f4ccb829d4886a179eb547dc assets/create/lang/unfinished/es_es.json
|
6a1dde57b2224d4b0287ebc705d6a75d329b5e1f assets/create/lang/unfinished/es_es.json
|
||||||
822b912d290d40c5f02011393af44bf37684f9b4 assets/create/lang/unfinished/es_mx.json
|
93ee0e30a56b405a9e766d353c36276e36a84b5c assets/create/lang/unfinished/es_mx.json
|
||||||
502d761465a0de7aeb15acec4147b8ec8bee92cf assets/create/lang/unfinished/fr_fr.json
|
49a691320c73e09f921cd0ea97398126231e99fa assets/create/lang/unfinished/fr_fr.json
|
||||||
dac15c17578fb37bbdb874cee5a0a078110b7481 assets/create/lang/unfinished/it_it.json
|
cf14b3828b6c11013f606f277d88fb63245bb2a8 assets/create/lang/unfinished/it_it.json
|
||||||
fd270c9c8bc46d4df21aa04ecc7bf059011e4b3e assets/create/lang/unfinished/ja_jp.json
|
73c1c1489833cbcb28bb1ce90541c8c8bdf329c0 assets/create/lang/unfinished/ja_jp.json
|
||||||
a5b002e047a2f509a8d35b9e638627f970b4810e assets/create/lang/unfinished/ko_kr.json
|
924303b9bcf56aedbbfc46108655f71324308e12 assets/create/lang/unfinished/ko_kr.json
|
||||||
50f65aaba8c4fec5404ab1fc40f74b4970a55edd assets/create/lang/unfinished/nl_nl.json
|
079aea6843e756efbfca0976983be1957863717c assets/create/lang/unfinished/nl_nl.json
|
||||||
ff61e567f15ded6ba127522af03860232069cdd2 assets/create/lang/unfinished/pl_pl.json
|
b7bab15167400ee48a9728f81446e572c494fd8d assets/create/lang/unfinished/pl_pl.json
|
||||||
a7a28fb3896bc38e00f746e650433160f5b53c90 assets/create/lang/unfinished/pt_br.json
|
07e84cc3eee3faa1ab3d26e0c85c7f09c8573368 assets/create/lang/unfinished/pt_br.json
|
||||||
ffa1901b392719634403048419d29b268704bd10 assets/create/lang/unfinished/ru_ru.json
|
6ffb0cf20d712aee23a42a9ec440dd7dc92293d6 assets/create/lang/unfinished/ru_ru.json
|
||||||
38b843c5232167876b3678328b47ec95f30cf69f assets/create/lang/unfinished/zh_cn.json
|
0ae98a18e59f478da41d8c5d832737b65f6a8c8a assets/create/lang/unfinished/zh_cn.json
|
||||||
b806d1e6fe9ebee27f417a3c4d6c818124ee4cde assets/create/lang/unfinished/zh_tw.json
|
4c96e5a76e72368a59190b7588d389fdd2cc75e1 assets/create/lang/unfinished/zh_tw.json
|
||||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.json
|
||||||
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
3066db1bf03cffa1a9c7fbacf47ae586632f4eb3 assets/create/models/block/acacia_window_pane_noside_alt.json
|
||||||
|
@ -2726,7 +2726,7 @@ cecaac07bd275bb1ae9e302f0bf44b581e74105d data/create/loot_tables/blocks/rope_pul
|
||||||
aa6af37356d65105efab2503ffe75f778cfe873b data/create/loot_tables/blocks/rotation_speed_controller.json
|
aa6af37356d65105efab2503ffe75f778cfe873b data/create/loot_tables/blocks/rotation_speed_controller.json
|
||||||
30de11bec82606fead9d6bff7bba0232e97f1039 data/create/loot_tables/blocks/sail_frame.json
|
30de11bec82606fead9d6bff7bba0232e97f1039 data/create/loot_tables/blocks/sail_frame.json
|
||||||
069701cb804b6522c18624a0d4f3f949ff8b0281 data/create/loot_tables/blocks/schematic_table.json
|
069701cb804b6522c18624a0d4f3f949ff8b0281 data/create/loot_tables/blocks/schematic_table.json
|
||||||
c4a89145334addfd0dd1fedf7fa75ba07a7d3490 data/create/loot_tables/blocks/schematicannon.json
|
a2b172dc749176d4df34729007019605fc6dd150 data/create/loot_tables/blocks/schematicannon.json
|
||||||
af1bbbb8236b4ab05a6a8edc6db960bc758cbdf3 data/create/loot_tables/blocks/scoria.json
|
af1bbbb8236b4ab05a6a8edc6db960bc758cbdf3 data/create/loot_tables/blocks/scoria.json
|
||||||
bb670ac5dd2fa4c743bc268cd0547926eb6cdb68 data/create/loot_tables/blocks/scoria_bricks.json
|
bb670ac5dd2fa4c743bc268cd0547926eb6cdb68 data/create/loot_tables/blocks/scoria_bricks.json
|
||||||
a7217ea301a282d0ef52f2d8c06dd8683398408d data/create/loot_tables/blocks/scoria_bricks_slab.json
|
a7217ea301a282d0ef52f2d8c06dd8683398408d data/create/loot_tables/blocks/scoria_bricks_slab.json
|
||||||
|
|
|
@ -6,6 +6,19 @@
|
||||||
"entries": [
|
"entries": [
|
||||||
{
|
{
|
||||||
"type": "minecraft:item",
|
"type": "minecraft:item",
|
||||||
|
"functions": [
|
||||||
|
{
|
||||||
|
"function": "minecraft:copy_nbt",
|
||||||
|
"source": "block_entity",
|
||||||
|
"ops": [
|
||||||
|
{
|
||||||
|
"source": "Options",
|
||||||
|
"target": "BlockEntityTag.Options",
|
||||||
|
"op": "replace"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"name": "create:schematicannon"
|
"name": "create:schematicannon"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
|
|
@ -215,6 +215,16 @@ public class AllBlocks {
|
||||||
REGISTRATE.block("schematicannon", SchematicannonBlock::new)
|
REGISTRATE.block("schematicannon", SchematicannonBlock::new)
|
||||||
.initialProperties(() -> Blocks.DISPENSER)
|
.initialProperties(() -> Blocks.DISPENSER)
|
||||||
.blockstate((ctx, prov) -> prov.simpleBlock(ctx.getEntry(), AssetLookup.partialBaseModel(ctx, prov)))
|
.blockstate((ctx, prov) -> prov.simpleBlock(ctx.getEntry(), AssetLookup.partialBaseModel(ctx, prov)))
|
||||||
|
.loot((lt, block) -> {
|
||||||
|
Builder builder = LootTable.builder();
|
||||||
|
IBuilder survivesExplosion = SurvivesExplosion.builder();
|
||||||
|
lt.registerLootTable(block, builder.addLootPool(LootPool.builder()
|
||||||
|
.acceptCondition(survivesExplosion)
|
||||||
|
.rolls(ConstantRange.of(1))
|
||||||
|
.addEntry(ItemLootEntry.builder(AllBlocks.SCHEMATICANNON.get().asItem())
|
||||||
|
.acceptFunction(CopyNbt.func_215881_a(CopyNbt.Source.BLOCK_ENTITY)
|
||||||
|
.func_216056_a("Options", "BlockEntityTag.Options")))));
|
||||||
|
})
|
||||||
.item()
|
.item()
|
||||||
.transform(customItemModel())
|
.transform(customItemModel())
|
||||||
.register();
|
.register();
|
||||||
|
|
|
@ -54,6 +54,7 @@ import net.minecraft.util.ActionResultType;
|
||||||
import net.minecraft.util.Direction;
|
import net.minecraft.util.Direction;
|
||||||
import net.minecraft.util.Direction.Axis;
|
import net.minecraft.util.Direction.Axis;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Mirror;
|
||||||
import net.minecraft.util.Rotation;
|
import net.minecraft.util.Rotation;
|
||||||
import net.minecraft.util.SoundCategory;
|
import net.minecraft.util.SoundCategory;
|
||||||
import net.minecraft.util.SoundEvents;
|
import net.minecraft.util.SoundEvents;
|
||||||
|
@ -492,29 +493,55 @@ public class CartAssemblerBlock extends AbstractRailBlock
|
||||||
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||||
World world = context.getWorld();
|
World world = context.getWorld();
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
BlockPos pos = context.getPos();
|
BlockPos pos = context.getPos();
|
||||||
BlockState newState = state.with(RAIL_SHAPE,
|
world.setBlockState(pos, rotate(state, Rotation.CLOCKWISE_90), 3);
|
||||||
state.get(RAIL_SHAPE) == RailShape.NORTH_SOUTH ? RailShape.EAST_WEST : RailShape.NORTH_SOUTH);
|
|
||||||
if (state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL
|
|
||||||
|| state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS) {
|
|
||||||
newState = newState.with(RAIL_TYPE, AllBlocks.CONTROLLER_RAIL.get()
|
|
||||||
.rotate(AllBlocks.CONTROLLER_RAIL.getDefaultState()
|
|
||||||
.with(ControllerRailBlock.SHAPE, state.get(RAIL_SHAPE))
|
|
||||||
.with(ControllerRailBlock.BACKWARDS,
|
|
||||||
state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS),
|
|
||||||
Rotation.CLOCKWISE_90)
|
|
||||||
.get(ControllerRailBlock.BACKWARDS) ? CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS
|
|
||||||
: CartAssembleRailType.CONTROLLER_RAIL);
|
|
||||||
}
|
|
||||||
context.getWorld()
|
|
||||||
.setBlockState(pos, newState, 3);
|
|
||||||
world.notifyNeighborsOfStateChange(pos.down(), this);
|
world.notifyNeighborsOfStateChange(pos.down(), this);
|
||||||
return ActionResultType.SUCCESS;
|
return ActionResultType.SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState rotate(BlockState state, Rotation rotation) {
|
||||||
|
if (rotation == Rotation.NONE)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
boolean is_controller_rail_backwards = state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS;
|
||||||
|
boolean is_controller_rail = state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL || is_controller_rail_backwards;
|
||||||
|
BlockState base = AllBlocks.CONTROLLER_RAIL.getDefaultState()
|
||||||
|
.with(ControllerRailBlock.SHAPE, state.get(RAIL_SHAPE))
|
||||||
|
.with(ControllerRailBlock.BACKWARDS, is_controller_rail_backwards)
|
||||||
|
.rotate(rotation);
|
||||||
|
if (is_controller_rail) {
|
||||||
|
state = state.with(RAIL_TYPE,
|
||||||
|
base.get(ControllerRailBlock.BACKWARDS) ? CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS :
|
||||||
|
CartAssembleRailType.CONTROLLER_RAIL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return state.with(RAIL_SHAPE, base.get(ControllerRailBlock.SHAPE));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BlockState mirror(BlockState state, Mirror mirror) {
|
||||||
|
if (mirror == Mirror.NONE)
|
||||||
|
return state;
|
||||||
|
|
||||||
|
boolean is_controller_rail_backwards = state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS;
|
||||||
|
boolean is_controller_rail = state.get(RAIL_TYPE) == CartAssembleRailType.CONTROLLER_RAIL || is_controller_rail_backwards;
|
||||||
|
BlockState base = AllBlocks.CONTROLLER_RAIL.getDefaultState()
|
||||||
|
.with(ControllerRailBlock.SHAPE, state.get(RAIL_SHAPE))
|
||||||
|
.with(ControllerRailBlock.BACKWARDS, is_controller_rail_backwards)
|
||||||
|
.mirror(mirror);
|
||||||
|
if (is_controller_rail) {
|
||||||
|
state = state.with(RAIL_TYPE,
|
||||||
|
base.get(ControllerRailBlock.BACKWARDS) ? CartAssembleRailType.CONTROLLER_RAIL_BACKWARDS :
|
||||||
|
CartAssembleRailType.CONTROLLER_RAIL
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return state.with(RAIL_SHAPE, base.get(ControllerRailBlock.SHAPE));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,20 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
|
||||||
return onWrenched;
|
return onWrenched;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBlockAdded(BlockState state, World worldIn, BlockPos pos, BlockState oldState, boolean isMoving) {
|
||||||
|
super.onBlockAdded(state, worldIn, pos, oldState, isMoving);
|
||||||
|
|
||||||
|
if (!worldIn.isRemote() && oldState.getBlock().is(AllBlocks.GANTRY_SHAFT.get())) {
|
||||||
|
Part oldPart = oldState.get(PART), part = state.get(PART);
|
||||||
|
if ((oldPart != Part.MIDDLE && part == Part.MIDDLE) || (oldPart == Part.SINGLE && part != Part.SINGLE)) {
|
||||||
|
TileEntity te = worldIn.getTileEntity(pos);
|
||||||
|
if (te instanceof GantryShaftTileEntity)
|
||||||
|
((GantryShaftTileEntity) te).checkAttachedCarriageBlocks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block p_220069_4_, BlockPos p_220069_5_,
|
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block p_220069_4_, BlockPos p_220069_5_,
|
||||||
boolean p_220069_6_) {
|
boolean p_220069_6_) {
|
||||||
|
@ -260,7 +274,7 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
|
||||||
return super.areStatesKineticallyEquivalent(oldState, newState)
|
return super.areStatesKineticallyEquivalent(oldState, newState)
|
||||||
&& oldState.get(POWERED) == newState.get(POWERED);
|
&& oldState.get(POWERED) == newState.get(POWERED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public float getParticleTargetRadius() {
|
public float getParticleTargetRadius() {
|
||||||
return .35f;
|
return .35f;
|
||||||
|
@ -270,7 +284,7 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
|
||||||
public float getParticleInitialRadius() {
|
public float getParticleInitialRadius() {
|
||||||
return .25f;
|
return .25f;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -19,15 +19,12 @@ public class GantryShaftTileEntity extends KineticTileEntity {
|
||||||
super(typeIn);
|
super(typeIn);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void checkAttachedCarriageBlocks() {
|
||||||
public void onSpeedChanged(float previousSpeed) {
|
|
||||||
super.onSpeedChanged(previousSpeed);
|
|
||||||
|
|
||||||
if (!canAssembleOn())
|
if (!canAssembleOn())
|
||||||
return;
|
return;
|
||||||
for (Direction d : Iterate.directions) {
|
for (Direction d : Iterate.directions) {
|
||||||
if (d.getAxis() == getBlockState().get(GantryShaftBlock.FACING)
|
if (d.getAxis() == getBlockState().get(GantryShaftBlock.FACING)
|
||||||
.getAxis())
|
.getAxis())
|
||||||
continue;
|
continue;
|
||||||
BlockPos offset = pos.offset(d);
|
BlockPos offset = pos.offset(d);
|
||||||
BlockState pinionState = world.getBlockState(offset);
|
BlockState pinionState = world.getBlockState(offset);
|
||||||
|
@ -39,7 +36,12 @@ public class GantryShaftTileEntity extends KineticTileEntity {
|
||||||
if (tileEntity instanceof GantryCarriageTileEntity)
|
if (tileEntity instanceof GantryCarriageTileEntity)
|
||||||
((GantryCarriageTileEntity) tileEntity).queueAssembly();
|
((GantryCarriageTileEntity) tileEntity).queueAssembly();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSpeedChanged(float previousSpeed) {
|
||||||
|
super.onSpeedChanged(previousSpeed);
|
||||||
|
checkAttachedCarriageBlocks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,7 +101,7 @@ public class GantryShaftTileEntity extends KineticTileEntity {
|
||||||
return 0;
|
return 0;
|
||||||
return MathHelper.clamp(-getSpeed() / 512f, -.49f, .49f);
|
return MathHelper.clamp(-getSpeed() / 512f, -.49f, .49f);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isNoisy() {
|
protected boolean isNoisy() {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -122,14 +122,14 @@ public class ArmTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
if (world.isRemote)
|
if (world.isRemote)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (phase == Phase.MOVE_TO_INPUT)
|
if (phase == Phase.MOVE_TO_INPUT)
|
||||||
collectItem();
|
collectItem();
|
||||||
else if (phase == Phase.MOVE_TO_OUTPUT)
|
else if (phase == Phase.MOVE_TO_OUTPUT)
|
||||||
depositItem();
|
depositItem();
|
||||||
else if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
else if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
||||||
searchForItem();
|
searchForItem();
|
||||||
|
|
||||||
if (targetReached)
|
if (targetReached)
|
||||||
lazyTick();
|
lazyTick();
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
||||||
return;
|
return;
|
||||||
if (chasedPointProgress < .5f)
|
if (chasedPointProgress < .5f)
|
||||||
return;
|
return;
|
||||||
if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
||||||
checkForMusic();
|
checkForMusic();
|
||||||
if (phase == Phase.SEARCH_OUTPUTS)
|
if (phase == Phase.SEARCH_OUTPUTS)
|
||||||
searchForDestination();
|
searchForDestination();
|
||||||
|
@ -175,7 +175,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean tickMovementProgress() {
|
private boolean tickMovementProgress() {
|
||||||
boolean targetReachedPreviously = chasedPointProgress >= 1;
|
boolean targetReachedPreviously = chasedPointProgress >= 1;
|
||||||
chasedPointProgress += Math.min(256, Math.abs(getSpeed())) / 1024f;
|
chasedPointProgress += Math.min(256, Math.abs(getSpeed())) / 1024f;
|
||||||
if (chasedPointProgress > 1)
|
if (chasedPointProgress > 1)
|
||||||
chasedPointProgress = 1;
|
chasedPointProgress = 1;
|
||||||
|
@ -349,7 +349,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
||||||
chasedPointIndex = -1;
|
chasedPointIndex = -1;
|
||||||
sendData();
|
sendData();
|
||||||
markDirty();
|
markDirty();
|
||||||
|
|
||||||
if (!prevHeld.isItemEqual(heldItem))
|
if (!prevHeld.isItemEqual(heldItem))
|
||||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f,
|
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f,
|
||||||
.5f + Create.random.nextFloat() * .25f);
|
.5f + Create.random.nextFloat() * .25f);
|
||||||
|
@ -416,23 +416,26 @@ public class ArmTileEntity extends KineticTileEntity {
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeInteractionPoints(CompoundNBT compound) {
|
||||||
|
if (updateInteractionPoints) {
|
||||||
|
compound.put("InteractionPoints", interactionPointTag);
|
||||||
|
} else {
|
||||||
|
ListNBT pointsNBT = new ListNBT();
|
||||||
|
inputs.stream()
|
||||||
|
.map(aip -> aip.serialize(pos))
|
||||||
|
.forEach(pointsNBT::add);
|
||||||
|
outputs.stream()
|
||||||
|
.map(aip -> aip.serialize(pos))
|
||||||
|
.forEach(pointsNBT::add);
|
||||||
|
compound.put("InteractionPoints", pointsNBT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundNBT compound, boolean clientPacket) {
|
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||||
super.write(compound, clientPacket);
|
super.write(compound, clientPacket);
|
||||||
|
|
||||||
if (updateInteractionPoints) {
|
writeInteractionPoints(compound);
|
||||||
compound.put("InteractionPoints", interactionPointTag);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
ListNBT pointsNBT = new ListNBT();
|
|
||||||
inputs.stream()
|
|
||||||
.map(aip -> aip.serialize(pos))
|
|
||||||
.forEach(pointsNBT::add);
|
|
||||||
outputs.stream()
|
|
||||||
.map(aip -> aip.serialize(pos))
|
|
||||||
.forEach(pointsNBT::add);
|
|
||||||
compound.put("InteractionPoints", pointsNBT);
|
|
||||||
}
|
|
||||||
|
|
||||||
NBTHelper.writeEnum(compound, "Phase", phase);
|
NBTHelper.writeEnum(compound, "Phase", phase);
|
||||||
compound.putBoolean("Powered", redstoneLocked);
|
compound.putBoolean("Powered", redstoneLocked);
|
||||||
|
@ -441,6 +444,13 @@ public class ArmTileEntity extends KineticTileEntity {
|
||||||
compound.putFloat("MovementProgress", chasedPointProgress);
|
compound.putFloat("MovementProgress", chasedPointProgress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeSafe(CompoundNBT compound, boolean clientPacket) {
|
||||||
|
super.writeSafe(compound, clientPacket);
|
||||||
|
|
||||||
|
writeInteractionPoints(compound);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
||||||
int previousIndex = chasedPointIndex;
|
int previousIndex = chasedPointIndex;
|
||||||
|
|
|
@ -28,10 +28,15 @@ import com.simibubi.create.foundation.item.ItemHelper.ExtractionCountMode;
|
||||||
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
import com.simibubi.create.foundation.render.backend.instancing.IInstanceRendered;
|
||||||
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
import com.simibubi.create.foundation.tileEntity.SmartTileEntity;
|
||||||
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
import com.simibubi.create.foundation.tileEntity.TileEntityBehaviour;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
import com.simibubi.create.foundation.tileEntity.behaviour.filtering.FilteringBehaviour;
|
||||||
import com.simibubi.create.foundation.utility.BlockHelper;
|
import com.simibubi.create.foundation.utility.BlockHelper;
|
||||||
|
import com.simibubi.create.foundation.utility.IPartialSafeNBT;
|
||||||
import com.simibubi.create.foundation.utility.Iterate;
|
import com.simibubi.create.foundation.utility.Iterate;
|
||||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||||
|
|
||||||
|
import net.minecraft.block.AbstractRailBlock;
|
||||||
|
import net.minecraft.block.Block;
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.block.Blocks;
|
import net.minecraft.block.Blocks;
|
||||||
import net.minecraft.block.PistonHeadBlock;
|
import net.minecraft.block.PistonHeadBlock;
|
||||||
|
@ -79,6 +84,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
STOPPED, PAUSED, RUNNING;
|
STOPPED, PAUSED, RUNNING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum PrintStage {
|
||||||
|
BLOCKS, DEFERRED_BLOCKS, ENTITIES
|
||||||
|
}
|
||||||
|
|
||||||
// Inventory
|
// Inventory
|
||||||
public SchematicannonInventory inventory;
|
public SchematicannonInventory inventory;
|
||||||
|
|
||||||
|
@ -99,12 +108,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
private int skipsLeft;
|
private int skipsLeft;
|
||||||
private boolean blockSkipped;
|
private boolean blockSkipped;
|
||||||
private int printingEntityIndex;
|
private int printingEntityIndex;
|
||||||
|
private PrintStage printStage;
|
||||||
|
|
||||||
public BlockPos target;
|
public BlockPos target;
|
||||||
public BlockPos previousTarget;
|
public BlockPos previousTarget;
|
||||||
public LinkedHashSet<LazyOptional<IItemHandler>> attachedInventories;
|
public LinkedHashSet<LazyOptional<IItemHandler>> attachedInventories;
|
||||||
public List<LaunchedItem> flyingBlocks;
|
public List<LaunchedItem> flyingBlocks;
|
||||||
public MaterialChecklist checklist;
|
public MaterialChecklist checklist;
|
||||||
|
public List<BlockPos> deferredBlocks;
|
||||||
|
|
||||||
// Gui information
|
// Gui information
|
||||||
public float fuelLevel;
|
public float fuelLevel;
|
||||||
|
@ -142,7 +153,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
inventory = new SchematicannonInventory(this);
|
inventory = new SchematicannonInventory(this);
|
||||||
statusMsg = "idle";
|
statusMsg = "idle";
|
||||||
state = State.STOPPED;
|
state = State.STOPPED;
|
||||||
printingEntityIndex = -1;
|
printingEntityIndex = 0;
|
||||||
|
printStage = PrintStage.BLOCKS;
|
||||||
|
deferredBlocks = new LinkedList<>();
|
||||||
replaceMode = 2;
|
replaceMode = 2;
|
||||||
checklist = new MaterialChecklist();
|
checklist = new MaterialChecklist();
|
||||||
}
|
}
|
||||||
|
@ -198,8 +211,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
replaceTileEntities = options.getBoolean("ReplaceTileEntities");
|
replaceTileEntities = options.getBoolean("ReplaceTileEntities");
|
||||||
|
|
||||||
// Printer & Flying Blocks
|
// Printer & Flying Blocks
|
||||||
|
if (compound.contains("PrintStage"))
|
||||||
|
printStage = PrintStage.valueOf(compound.getString("PrintStage"));
|
||||||
if (compound.contains("Target"))
|
if (compound.contains("Target"))
|
||||||
target = NBTUtil.readBlockPos(compound.getCompound("Target"));
|
target = NBTUtil.readBlockPos(compound.getCompound("Target"));
|
||||||
|
if (compound.contains("DeferredBlocks"))
|
||||||
|
compound.getList("DeferredBlocks", 10).stream()
|
||||||
|
.map(p -> NBTUtil.readBlockPos((CompoundNBT) p))
|
||||||
|
.collect(Collectors.toCollection(() -> deferredBlocks));
|
||||||
if (compound.contains("FlyingBlocks"))
|
if (compound.contains("FlyingBlocks"))
|
||||||
readFlyingBlocks(compound);
|
readFlyingBlocks(compound);
|
||||||
|
|
||||||
|
@ -273,12 +292,20 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
compound.put("Options", options);
|
compound.put("Options", options);
|
||||||
|
|
||||||
// Printer & Flying Blocks
|
// Printer & Flying Blocks
|
||||||
|
compound.putString("PrintStage", printStage.name());
|
||||||
|
|
||||||
if (target != null)
|
if (target != null)
|
||||||
compound.put("Target", NBTUtil.writeBlockPos(target));
|
compound.put("Target", NBTUtil.writeBlockPos(target));
|
||||||
ListNBT tagBlocks = new ListNBT();
|
|
||||||
|
ListNBT tagDeferredBlocks = new ListNBT();
|
||||||
|
for (BlockPos p : deferredBlocks)
|
||||||
|
tagDeferredBlocks.add(NBTUtil.writeBlockPos(p));
|
||||||
|
compound.put("DeferredBlocks", tagDeferredBlocks);
|
||||||
|
|
||||||
|
ListNBT tagFlyingBlocks = new ListNBT();
|
||||||
for (LaunchedItem b : flyingBlocks)
|
for (LaunchedItem b : flyingBlocks)
|
||||||
tagBlocks.add(b.serializeNBT());
|
tagFlyingBlocks.add(b.serializeNBT());
|
||||||
compound.put("FlyingBlocks", tagBlocks);
|
compound.put("FlyingBlocks", tagFlyingBlocks);
|
||||||
|
|
||||||
super.write(compound, clientPacket);
|
super.write(compound, clientPacket);
|
||||||
}
|
}
|
||||||
|
@ -388,7 +415,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
target = schematicAnchor.add(currentPos);
|
target = schematicAnchor.add(currentPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean entityMode = printingEntityIndex >= 0;
|
boolean entityMode = printStage == PrintStage.ENTITIES;
|
||||||
|
|
||||||
// Check block
|
// Check block
|
||||||
if (!getWorld().isAreaLoaded(target, 0)) {
|
if (!getWorld().isAreaLoaded(target, 0)) {
|
||||||
|
@ -471,13 +498,18 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
launchBlock(target, icon, blockState, null);
|
launchBlock(target, icon, blockState, null);
|
||||||
} else {
|
} else {
|
||||||
CompoundNBT data = null;
|
CompoundNBT data = null;
|
||||||
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
|
TileEntity tile = blockReader.getTileEntity(target);
|
||||||
TileEntity tile = blockReader.getTileEntity(target);
|
if (tile != null) {
|
||||||
if (tile != null) {
|
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
|
||||||
data = tile.write(new CompoundNBT());
|
data = tile.write(new CompoundNBT());
|
||||||
data = NBTProcessors.process(tile, data, true);
|
data = NBTProcessors.process(tile, data, true);
|
||||||
|
} else if (tile instanceof IPartialSafeNBT) {
|
||||||
|
data = new CompoundNBT();
|
||||||
|
((IPartialSafeNBT) tile).writeSafe(data, false);
|
||||||
|
data = NBTProcessors.process(tile, data, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
launchBlock(target, icon, blockState, data);
|
launchBlock(target, icon, blockState, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -563,7 +595,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
schematicLoaded = true;
|
schematicLoaded = true;
|
||||||
state = State.PAUSED;
|
state = State.PAUSED;
|
||||||
statusMsg = "ready";
|
statusMsg = "ready";
|
||||||
printingEntityIndex = -1;
|
printingEntityIndex = 0;
|
||||||
|
printStage = PrintStage.BLOCKS;
|
||||||
|
deferredBlocks.clear();
|
||||||
updateChecklist();
|
updateChecklist();
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
blocksToPlace += blocksPlaced;
|
blocksToPlace += blocksPlaced;
|
||||||
|
@ -649,22 +683,33 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
protected void advanceCurrentPos() {
|
protected void advanceCurrentPos() {
|
||||||
List<Entity> entities = blockReader.getEntities()
|
List<Entity> entities = blockReader.getEntities()
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
if (printingEntityIndex != -1) {
|
|
||||||
printingEntityIndex++;
|
|
||||||
|
|
||||||
// End of entities reached
|
if (printStage == PrintStage.BLOCKS) {
|
||||||
if (printingEntityIndex >= entities.size()) {
|
MutableBoundingBox bounds = blockReader.getBounds();
|
||||||
finishedPrinting();
|
while (tryAdvanceCurrentPos(bounds, entities)) {
|
||||||
return;
|
deferredBlocks.add(currentPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentPos = entities.get(printingEntityIndex)
|
|
||||||
.getBlockPos()
|
|
||||||
.subtract(schematicAnchor);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableBoundingBox bounds = blockReader.getBounds();
|
if (printStage == PrintStage.DEFERRED_BLOCKS) {
|
||||||
|
if (deferredBlocks.isEmpty()) {
|
||||||
|
printStage = PrintStage.ENTITIES;
|
||||||
|
} else {
|
||||||
|
currentPos = deferredBlocks.remove(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printStage == PrintStage.ENTITIES) {
|
||||||
|
if (printingEntityIndex < entities.size()) {
|
||||||
|
currentPos = entities.get(printingEntityIndex).getBlockPos().subtract(schematicAnchor);
|
||||||
|
printingEntityIndex++;
|
||||||
|
} else {
|
||||||
|
finishedPrinting();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean tryAdvanceCurrentPos(MutableBoundingBox bounds, List<Entity> entities) {
|
||||||
currentPos = currentPos.offset(Direction.EAST);
|
currentPos = currentPos.offset(Direction.EAST);
|
||||||
BlockPos posInBounds = currentPos.add(-bounds.minX, -bounds.minY, -bounds.minZ);
|
BlockPos posInBounds = currentPos.add(-bounds.minX, -bounds.minY, -bounds.minZ);
|
||||||
|
|
||||||
|
@ -675,15 +720,16 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
|
|
||||||
// End of blocks reached
|
// End of blocks reached
|
||||||
if (currentPos.getY() > bounds.getYSize()) {
|
if (currentPos.getY() > bounds.getYSize()) {
|
||||||
printingEntityIndex = 0;
|
printStage = PrintStage.DEFERRED_BLOCKS;
|
||||||
if (entities.isEmpty()) {
|
return false;
|
||||||
finishedPrinting();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
currentPos = entities.get(0)
|
|
||||||
.getBlockPos()
|
|
||||||
.subtract(schematicAnchor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return shouldDeferBlock(blockReader.getBlockState(schematicAnchor.add(currentPos)));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean shouldDeferBlock(BlockState state) {
|
||||||
|
Block block = state.getBlock();
|
||||||
|
return block instanceof AbstractRailBlock || block.is(AllBlocks.GANTRY_CARRIAGE.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishedPrinting() {
|
public void finishedPrinting() {
|
||||||
|
@ -705,10 +751,12 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
||||||
blockReader = null;
|
blockReader = null;
|
||||||
missingItem = null;
|
missingItem = null;
|
||||||
sendUpdate = true;
|
sendUpdate = true;
|
||||||
printingEntityIndex = -1;
|
printingEntityIndex = 0;
|
||||||
|
printStage = PrintStage.BLOCKS;
|
||||||
schematicProgress = 0;
|
schematicProgress = 0;
|
||||||
blocksPlaced = 0;
|
blocksPlaced = 0;
|
||||||
blocksToPlace = 0;
|
blocksToPlace = 0;
|
||||||
|
deferredBlocks.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean shouldPlace(BlockPos pos, BlockState state) {
|
protected boolean shouldPlace(BlockPos pos, BlockState state) {
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package com.simibubi.create.foundation.mixin;
|
||||||
|
|
||||||
|
import com.simibubi.create.content.schematics.SchematicWorld;
|
||||||
|
|
||||||
|
import net.minecraft.tileentity.TileEntity;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
import net.minecraftforge.client.model.ModelDataManager;
|
||||||
|
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import net.minecraft.client.Minecraft;
|
||||||
|
import net.minecraftforge.api.distmarker.Dist;
|
||||||
|
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||||
|
|
||||||
|
@OnlyIn(Dist.CLIENT)
|
||||||
|
@Mixin(ModelDataManager.class)
|
||||||
|
public class ModelDataRefreshMixin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Normally ModelDataManager will throw an exception if a tile entity tries
|
||||||
|
* to refresh its model data from a world the client isn't currently in,
|
||||||
|
* but we need that to not happen for tile entities in fake schematic
|
||||||
|
* worlds, so in those cases just do nothing instead.
|
||||||
|
*/
|
||||||
|
@Inject(at = @At("HEAD"), method = "requestModelDataRefresh", cancellable = true, remap = false)
|
||||||
|
private static void requestModelDataRefresh(TileEntity te, CallbackInfo ci) {
|
||||||
|
if (te != null) {
|
||||||
|
World world = te.getWorld();
|
||||||
|
if (world != Minecraft.getInstance().world && world instanceof SchematicWorld)
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -8,6 +8,8 @@ import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
import com.simibubi.create.foundation.tileEntity.behaviour.BehaviourType;
|
||||||
|
|
||||||
|
import com.simibubi.create.foundation.utility.IPartialSafeNBT;
|
||||||
|
|
||||||
import net.minecraft.block.BlockState;
|
import net.minecraft.block.BlockState;
|
||||||
import net.minecraft.nbt.CompoundNBT;
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
import net.minecraft.tileentity.ITickableTileEntity;
|
import net.minecraft.tileentity.ITickableTileEntity;
|
||||||
|
@ -16,7 +18,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
||||||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||||
import net.minecraftforge.items.CapabilityItemHandler;
|
import net.minecraftforge.items.CapabilityItemHandler;
|
||||||
|
|
||||||
public abstract class SmartTileEntity extends SyncedTileEntity implements ITickableTileEntity {
|
public abstract class SmartTileEntity extends SyncedTileEntity implements ITickableTileEntity, IPartialSafeNBT {
|
||||||
|
|
||||||
private final Map<BehaviourType<?>, TileEntityBehaviour> behaviours;
|
private final Map<BehaviourType<?>, TileEntityBehaviour> behaviours;
|
||||||
// Internally maintained to be identical to behaviorMap.values() in order to improve iteration performance.
|
// Internally maintained to be identical to behaviorMap.values() in order to improve iteration performance.
|
||||||
|
@ -118,6 +120,14 @@ public abstract class SmartTileEntity extends SyncedTileEntity implements ITicka
|
||||||
behaviourList.forEach(tb -> tb.write(compound, clientPacket));
|
behaviourList.forEach(tb -> tb.write(compound, clientPacket));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeSafe(CompoundNBT compound, boolean clientPacket) {
|
||||||
|
super.write(compound);
|
||||||
|
behaviourList.forEach(tb -> {
|
||||||
|
if (tb.isSafeNBT())
|
||||||
|
tb.write(compound, clientPacket);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void remove() {
|
public void remove() {
|
||||||
forEachBehaviour(TileEntityBehaviour::remove);
|
forEachBehaviour(TileEntityBehaviour::remove);
|
||||||
|
|
|
@ -42,6 +42,8 @@ public abstract class TileEntityBehaviour {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isSafeNBT() { return false; }
|
||||||
|
|
||||||
public void onBlockChanged(BlockState oldState) {
|
public void onBlockChanged(BlockState oldState) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -94,5 +96,4 @@ public abstract class TileEntityBehaviour {
|
||||||
SmartTileEntity ste = (SmartTileEntity) te;
|
SmartTileEntity ste = (SmartTileEntity) te;
|
||||||
return ste.getBehaviour(type);
|
return ste.getBehaviour(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,9 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
||||||
fluidFilter = false;
|
fluidFilter = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSafeNBT() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||||
nbt.put("Filter", getFilter().serializeNBT());
|
nbt.put("Filter", getFilter().serializeNBT());
|
||||||
|
|
|
@ -58,6 +58,9 @@ public class SidedFilteringBehaviour extends FilteringBehaviour {
|
||||||
removeFilter(d);
|
removeFilter(d);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSafeNBT() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||||
nbt.put("Filters", NBTHelper.writeCompoundList(sidedFilters.entrySet(), entry -> {
|
nbt.put("Filters", NBTHelper.writeCompoundList(sidedFilters.entrySet(), entry -> {
|
||||||
|
|
|
@ -115,6 +115,9 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
||||||
getHandler().removeFromNetwork(this);
|
getHandler().removeFromNetwork(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSafeNBT() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||||
super.write(nbt, clientPacket);
|
super.write(nbt, clientPacket);
|
||||||
|
|
|
@ -54,6 +54,9 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
ticksUntilScrollPacket = -1;
|
ticksUntilScrollPacket = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSafeNBT() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||||
nbt.putInt("ScrollValue", value);
|
nbt.putInt("ScrollValue", value);
|
||||||
|
@ -95,7 +98,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
clientCallback = valueCallback;
|
clientCallback = valueCallback;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScrollValueBehaviour withCallback(Consumer<Integer> valueCallback) {
|
public ScrollValueBehaviour withCallback(Consumer<Integer> valueCallback) {
|
||||||
callback = valueCallback;
|
callback = valueCallback;
|
||||||
return this;
|
return this;
|
||||||
|
@ -126,7 +129,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
this.unit = unit;
|
this.unit = unit;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScrollValueBehaviour onlyActiveWhen(Supplier<Boolean> condition) {
|
public ScrollValueBehaviour onlyActiveWhen(Supplier<Boolean> condition) {
|
||||||
isActive = condition;
|
isActive = condition;
|
||||||
return this;
|
return this;
|
||||||
|
@ -168,7 +171,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
public BehaviourType<?> getType() {
|
public BehaviourType<?> getType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isActive() {
|
public boolean isActive() {
|
||||||
return isActive.get();
|
return isActive.get();
|
||||||
}
|
}
|
||||||
|
@ -182,7 +185,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
||||||
public void setLabel(ITextComponent label) {
|
public void setLabel(ITextComponent label) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class StepContext {
|
public static class StepContext {
|
||||||
public int currentValue;
|
public int currentValue;
|
||||||
public boolean forward;
|
public boolean forward;
|
||||||
|
|
|
@ -20,6 +20,9 @@ public class DeferralBehaviour extends TileEntityBehaviour {
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isSafeNBT() { return true; }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||||
nbt.putBoolean("NeedsUpdate", needsUpdate);
|
nbt.putBoolean("NeedsUpdate", needsUpdate);
|
||||||
|
@ -38,7 +41,7 @@ public class DeferralBehaviour extends TileEntityBehaviour {
|
||||||
if (needsUpdate && callback.get())
|
if (needsUpdate && callback.get())
|
||||||
needsUpdate = false;
|
needsUpdate = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void scheduleUpdate() {
|
public void scheduleUpdate() {
|
||||||
needsUpdate = true;
|
needsUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,18 @@
|
||||||
package com.simibubi.create.foundation.utility;
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import net.minecraft.block.AbstractRailBlock;
|
||||||
|
import net.minecraft.block.RailBlock;
|
||||||
|
|
||||||
|
import net.minecraft.world.chunk.Chunk;
|
||||||
|
import net.minecraft.world.chunk.ChunkSection;
|
||||||
|
import net.minecraftforge.common.util.BlockSnapshot;
|
||||||
|
|
||||||
import org.apache.commons.lang3.mutable.MutableInt;
|
import org.apache.commons.lang3.mutable.MutableInt;
|
||||||
|
|
||||||
import com.simibubi.create.AllBlocks;
|
import com.simibubi.create.AllBlocks;
|
||||||
|
@ -234,6 +243,24 @@ public class BlockHelper {
|
||||||
.isEmpty();
|
.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void placeRailWithoutUpdate(World world, BlockState state, BlockPos target) {
|
||||||
|
int i = target.getX() & 15;
|
||||||
|
int j = target.getY();
|
||||||
|
int k = target.getZ() & 15;
|
||||||
|
Chunk chunk = world.getChunkAt(target);
|
||||||
|
ChunkSection chunksection = chunk.getSections()[j >> 4];
|
||||||
|
if (chunksection == Chunk.EMPTY_SECTION) {
|
||||||
|
chunksection = new ChunkSection(j >> 4 << 4);
|
||||||
|
chunk.getSections()[j >> 4] = chunksection;
|
||||||
|
}
|
||||||
|
BlockState old = chunksection.setBlockState(i, j & 15, k, state);
|
||||||
|
chunk.markDirty();
|
||||||
|
world.markAndNotifyBlock(target, chunk, old, state, 82, 512);
|
||||||
|
|
||||||
|
world.setBlockState(target, state, 82);
|
||||||
|
world.neighborChanged(target, world.getBlockState(target.down()).getBlock(), target.down());
|
||||||
|
}
|
||||||
|
|
||||||
public static void placeSchematicBlock(World world, BlockState state, BlockPos target, ItemStack stack,
|
public static void placeSchematicBlock(World world, BlockState state, BlockPos target, ItemStack stack,
|
||||||
@Nullable CompoundNBT data) {
|
@Nullable CompoundNBT data) {
|
||||||
// Piston
|
// Piston
|
||||||
|
@ -268,7 +295,13 @@ public class BlockHelper {
|
||||||
Block.spawnDrops(state, world, target);
|
Block.spawnDrops(state, world, target);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
world.setBlockState(target, state, 18);
|
|
||||||
|
if (state.getBlock() instanceof AbstractRailBlock) {
|
||||||
|
placeRailWithoutUpdate(world, state, target);
|
||||||
|
} else {
|
||||||
|
world.setBlockState(target, state, 18);
|
||||||
|
}
|
||||||
|
|
||||||
if (data != null) {
|
if (data != null) {
|
||||||
TileEntity tile = world.getTileEntity(target);
|
TileEntity tile = world.getTileEntity(target);
|
||||||
if (tile != null) {
|
if (tile != null) {
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
|
import net.minecraft.nbt.CompoundNBT;
|
||||||
|
|
||||||
|
public interface IPartialSafeNBT {
|
||||||
|
public void writeSafe(CompoundNBT compound, boolean clientPacket);
|
||||||
|
}
|
|
@ -19,7 +19,8 @@
|
||||||
"StoreProjectionMatrixMixin",
|
"StoreProjectionMatrixMixin",
|
||||||
"TileRemoveMixin",
|
"TileRemoveMixin",
|
||||||
"TileWorldHookMixin",
|
"TileWorldHookMixin",
|
||||||
"WindowResizeMixin"
|
"WindowResizeMixin",
|
||||||
|
"ModelDataRefreshMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
Loading…
Reference in a new issue