mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-28 16:06:48 +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
|
||||
a6d814f94926d88764c38862cc4ece9c367e023b assets/create/lang/en_ud.json
|
||||
d1838140c8383ee4537db90eb8f657d0c268fe91 assets/create/lang/en_us.json
|
||||
9d6f26ca7b59d3707ce996e513358cc9b873cad1 assets/create/lang/unfinished/de_de.json
|
||||
7fafb7565349aa52f4ccb829d4886a179eb547dc assets/create/lang/unfinished/es_es.json
|
||||
822b912d290d40c5f02011393af44bf37684f9b4 assets/create/lang/unfinished/es_mx.json
|
||||
502d761465a0de7aeb15acec4147b8ec8bee92cf assets/create/lang/unfinished/fr_fr.json
|
||||
dac15c17578fb37bbdb874cee5a0a078110b7481 assets/create/lang/unfinished/it_it.json
|
||||
fd270c9c8bc46d4df21aa04ecc7bf059011e4b3e assets/create/lang/unfinished/ja_jp.json
|
||||
a5b002e047a2f509a8d35b9e638627f970b4810e assets/create/lang/unfinished/ko_kr.json
|
||||
50f65aaba8c4fec5404ab1fc40f74b4970a55edd assets/create/lang/unfinished/nl_nl.json
|
||||
ff61e567f15ded6ba127522af03860232069cdd2 assets/create/lang/unfinished/pl_pl.json
|
||||
a7a28fb3896bc38e00f746e650433160f5b53c90 assets/create/lang/unfinished/pt_br.json
|
||||
ffa1901b392719634403048419d29b268704bd10 assets/create/lang/unfinished/ru_ru.json
|
||||
38b843c5232167876b3678328b47ec95f30cf69f assets/create/lang/unfinished/zh_cn.json
|
||||
b806d1e6fe9ebee27f417a3c4d6c818124ee4cde assets/create/lang/unfinished/zh_tw.json
|
||||
4fcda300efe5a2ad8695b5ae3f24a54ea109a954 assets/create/lang/unfinished/de_de.json
|
||||
6a1dde57b2224d4b0287ebc705d6a75d329b5e1f assets/create/lang/unfinished/es_es.json
|
||||
93ee0e30a56b405a9e766d353c36276e36a84b5c assets/create/lang/unfinished/es_mx.json
|
||||
49a691320c73e09f921cd0ea97398126231e99fa assets/create/lang/unfinished/fr_fr.json
|
||||
cf14b3828b6c11013f606f277d88fb63245bb2a8 assets/create/lang/unfinished/it_it.json
|
||||
73c1c1489833cbcb28bb1ce90541c8c8bdf329c0 assets/create/lang/unfinished/ja_jp.json
|
||||
924303b9bcf56aedbbfc46108655f71324308e12 assets/create/lang/unfinished/ko_kr.json
|
||||
079aea6843e756efbfca0976983be1957863717c assets/create/lang/unfinished/nl_nl.json
|
||||
b7bab15167400ee48a9728f81446e572c494fd8d assets/create/lang/unfinished/pl_pl.json
|
||||
07e84cc3eee3faa1ab3d26e0c85c7f09c8573368 assets/create/lang/unfinished/pt_br.json
|
||||
6ffb0cf20d712aee23a42a9ec440dd7dc92293d6 assets/create/lang/unfinished/ru_ru.json
|
||||
0ae98a18e59f478da41d8c5d832737b65f6a8c8a assets/create/lang/unfinished/zh_cn.json
|
||||
4c96e5a76e72368a59190b7588d389fdd2cc75e1 assets/create/lang/unfinished/zh_tw.json
|
||||
487a511a01b2a4531fb672f917922312db78f958 assets/create/models/block/acacia_window.json
|
||||
b48060cba1a382f373a05bf0039054053eccf076 assets/create/models/block/acacia_window_pane_noside.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
|
||||
30de11bec82606fead9d6bff7bba0232e97f1039 data/create/loot_tables/blocks/sail_frame.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
|
||||
bb670ac5dd2fa4c743bc268cd0547926eb6cdb68 data/create/loot_tables/blocks/scoria_bricks.json
|
||||
a7217ea301a282d0ef52f2d8c06dd8683398408d data/create/loot_tables/blocks/scoria_bricks_slab.json
|
||||
|
|
|
@ -6,6 +6,19 @@
|
|||
"entries": [
|
||||
{
|
||||
"type": "minecraft:item",
|
||||
"functions": [
|
||||
{
|
||||
"function": "minecraft:copy_nbt",
|
||||
"source": "block_entity",
|
||||
"ops": [
|
||||
{
|
||||
"source": "Options",
|
||||
"target": "BlockEntityTag.Options",
|
||||
"op": "replace"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"name": "create:schematicannon"
|
||||
}
|
||||
],
|
||||
|
|
|
@ -215,6 +215,16 @@ public class AllBlocks {
|
|||
REGISTRATE.block("schematicannon", SchematicannonBlock::new)
|
||||
.initialProperties(() -> Blocks.DISPENSER)
|
||||
.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()
|
||||
.transform(customItemModel())
|
||||
.register();
|
||||
|
|
|
@ -54,6 +54,7 @@ import net.minecraft.util.ActionResultType;
|
|||
import net.minecraft.util.Direction;
|
||||
import net.minecraft.util.Direction.Axis;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Mirror;
|
||||
import net.minecraft.util.Rotation;
|
||||
import net.minecraft.util.SoundCategory;
|
||||
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) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public ActionResultType onWrenched(BlockState state, ItemUseContext context) {
|
||||
World world = context.getWorld();
|
||||
if (world.isRemote)
|
||||
return ActionResultType.SUCCESS;
|
||||
BlockPos pos = context.getPos();
|
||||
BlockState newState = state.with(RAIL_SHAPE,
|
||||
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.setBlockState(pos, rotate(state, Rotation.CLOCKWISE_90), 3);
|
||||
world.notifyNeighborsOfStateChange(pos.down(), this);
|
||||
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;
|
||||
}
|
||||
|
||||
@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
|
||||
public void neighborChanged(BlockState state, World worldIn, BlockPos pos, Block p_220069_4_, BlockPos p_220069_5_,
|
||||
boolean p_220069_6_) {
|
||||
|
@ -260,7 +274,7 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
|
|||
return super.areStatesKineticallyEquivalent(oldState, newState)
|
||||
&& oldState.get(POWERED) == newState.get(POWERED);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public float getParticleTargetRadius() {
|
||||
return .35f;
|
||||
|
@ -270,7 +284,7 @@ public class GantryShaftBlock extends DirectionalKineticBlock {
|
|||
public float getParticleInitialRadius() {
|
||||
return .25f;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean allowsMovement(BlockState state, IBlockReader reader, BlockPos pos, PathType type) {
|
||||
return false;
|
||||
|
|
|
@ -19,15 +19,12 @@ public class GantryShaftTileEntity extends KineticTileEntity {
|
|||
super(typeIn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeedChanged(float previousSpeed) {
|
||||
super.onSpeedChanged(previousSpeed);
|
||||
|
||||
public void checkAttachedCarriageBlocks() {
|
||||
if (!canAssembleOn())
|
||||
return;
|
||||
for (Direction d : Iterate.directions) {
|
||||
if (d.getAxis() == getBlockState().get(GantryShaftBlock.FACING)
|
||||
.getAxis())
|
||||
.getAxis())
|
||||
continue;
|
||||
BlockPos offset = pos.offset(d);
|
||||
BlockState pinionState = world.getBlockState(offset);
|
||||
|
@ -39,7 +36,12 @@ public class GantryShaftTileEntity extends KineticTileEntity {
|
|||
if (tileEntity instanceof GantryCarriageTileEntity)
|
||||
((GantryCarriageTileEntity) tileEntity).queueAssembly();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSpeedChanged(float previousSpeed) {
|
||||
super.onSpeedChanged(previousSpeed);
|
||||
checkAttachedCarriageBlocks();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -99,7 +101,7 @@ public class GantryShaftTileEntity extends KineticTileEntity {
|
|||
return 0;
|
||||
return MathHelper.clamp(-getSpeed() / 512f, -.49f, .49f);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected boolean isNoisy() {
|
||||
return false;
|
||||
|
|
|
@ -122,14 +122,14 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
}
|
||||
if (world.isRemote)
|
||||
return;
|
||||
|
||||
|
||||
if (phase == Phase.MOVE_TO_INPUT)
|
||||
collectItem();
|
||||
else if (phase == Phase.MOVE_TO_OUTPUT)
|
||||
depositItem();
|
||||
else if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
||||
searchForItem();
|
||||
|
||||
|
||||
if (targetReached)
|
||||
lazyTick();
|
||||
}
|
||||
|
@ -142,7 +142,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
return;
|
||||
if (chasedPointProgress < .5f)
|
||||
return;
|
||||
if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
||||
if (phase == Phase.SEARCH_INPUTS || phase == Phase.DANCING)
|
||||
checkForMusic();
|
||||
if (phase == Phase.SEARCH_OUTPUTS)
|
||||
searchForDestination();
|
||||
|
@ -175,7 +175,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
}
|
||||
|
||||
private boolean tickMovementProgress() {
|
||||
boolean targetReachedPreviously = chasedPointProgress >= 1;
|
||||
boolean targetReachedPreviously = chasedPointProgress >= 1;
|
||||
chasedPointProgress += Math.min(256, Math.abs(getSpeed())) / 1024f;
|
||||
if (chasedPointProgress > 1)
|
||||
chasedPointProgress = 1;
|
||||
|
@ -349,7 +349,7 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
chasedPointIndex = -1;
|
||||
sendData();
|
||||
markDirty();
|
||||
|
||||
|
||||
if (!prevHeld.isItemEqual(heldItem))
|
||||
world.playSound(null, pos, SoundEvents.ENTITY_ITEM_PICKUP, SoundCategory.BLOCKS, .125f,
|
||||
.5f + Create.random.nextFloat() * .25f);
|
||||
|
@ -416,23 +416,26 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
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
|
||||
public void write(CompoundNBT compound, boolean clientPacket) {
|
||||
super.write(compound, clientPacket);
|
||||
|
||||
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);
|
||||
}
|
||||
writeInteractionPoints(compound);
|
||||
|
||||
NBTHelper.writeEnum(compound, "Phase", phase);
|
||||
compound.putBoolean("Powered", redstoneLocked);
|
||||
|
@ -441,6 +444,13 @@ public class ArmTileEntity extends KineticTileEntity {
|
|||
compound.putFloat("MovementProgress", chasedPointProgress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeSafe(CompoundNBT compound, boolean clientPacket) {
|
||||
super.writeSafe(compound, clientPacket);
|
||||
|
||||
writeInteractionPoints(compound);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void fromTag(BlockState state, CompoundNBT compound, boolean clientPacket) {
|
||||
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.tileEntity.SmartTileEntity;
|
||||
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.IPartialSafeNBT;
|
||||
import com.simibubi.create.foundation.utility.Iterate;
|
||||
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.Blocks;
|
||||
import net.minecraft.block.PistonHeadBlock;
|
||||
|
@ -79,6 +84,10 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
STOPPED, PAUSED, RUNNING;
|
||||
}
|
||||
|
||||
public enum PrintStage {
|
||||
BLOCKS, DEFERRED_BLOCKS, ENTITIES
|
||||
}
|
||||
|
||||
// Inventory
|
||||
public SchematicannonInventory inventory;
|
||||
|
||||
|
@ -99,12 +108,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
private int skipsLeft;
|
||||
private boolean blockSkipped;
|
||||
private int printingEntityIndex;
|
||||
private PrintStage printStage;
|
||||
|
||||
public BlockPos target;
|
||||
public BlockPos previousTarget;
|
||||
public LinkedHashSet<LazyOptional<IItemHandler>> attachedInventories;
|
||||
public List<LaunchedItem> flyingBlocks;
|
||||
public MaterialChecklist checklist;
|
||||
public List<BlockPos> deferredBlocks;
|
||||
|
||||
// Gui information
|
||||
public float fuelLevel;
|
||||
|
@ -142,7 +153,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
inventory = new SchematicannonInventory(this);
|
||||
statusMsg = "idle";
|
||||
state = State.STOPPED;
|
||||
printingEntityIndex = -1;
|
||||
printingEntityIndex = 0;
|
||||
printStage = PrintStage.BLOCKS;
|
||||
deferredBlocks = new LinkedList<>();
|
||||
replaceMode = 2;
|
||||
checklist = new MaterialChecklist();
|
||||
}
|
||||
|
@ -198,8 +211,14 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
replaceTileEntities = options.getBoolean("ReplaceTileEntities");
|
||||
|
||||
// Printer & Flying Blocks
|
||||
if (compound.contains("PrintStage"))
|
||||
printStage = PrintStage.valueOf(compound.getString("PrintStage"));
|
||||
if (compound.contains("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"))
|
||||
readFlyingBlocks(compound);
|
||||
|
||||
|
@ -273,12 +292,20 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
compound.put("Options", options);
|
||||
|
||||
// Printer & Flying Blocks
|
||||
compound.putString("PrintStage", printStage.name());
|
||||
|
||||
if (target != null)
|
||||
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)
|
||||
tagBlocks.add(b.serializeNBT());
|
||||
compound.put("FlyingBlocks", tagBlocks);
|
||||
tagFlyingBlocks.add(b.serializeNBT());
|
||||
compound.put("FlyingBlocks", tagFlyingBlocks);
|
||||
|
||||
super.write(compound, clientPacket);
|
||||
}
|
||||
|
@ -388,7 +415,7 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
target = schematicAnchor.add(currentPos);
|
||||
}
|
||||
|
||||
boolean entityMode = printingEntityIndex >= 0;
|
||||
boolean entityMode = printStage == PrintStage.ENTITIES;
|
||||
|
||||
// Check block
|
||||
if (!getWorld().isAreaLoaded(target, 0)) {
|
||||
|
@ -471,13 +498,18 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
launchBlock(target, icon, blockState, null);
|
||||
} else {
|
||||
CompoundNBT data = null;
|
||||
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
|
||||
TileEntity tile = blockReader.getTileEntity(target);
|
||||
if (tile != null) {
|
||||
TileEntity tile = blockReader.getTileEntity(target);
|
||||
if (tile != null) {
|
||||
if (AllBlockTags.SAFE_NBT.matches(blockState)) {
|
||||
data = tile.write(new CompoundNBT());
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -563,7 +595,9 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
schematicLoaded = true;
|
||||
state = State.PAUSED;
|
||||
statusMsg = "ready";
|
||||
printingEntityIndex = -1;
|
||||
printingEntityIndex = 0;
|
||||
printStage = PrintStage.BLOCKS;
|
||||
deferredBlocks.clear();
|
||||
updateChecklist();
|
||||
sendUpdate = true;
|
||||
blocksToPlace += blocksPlaced;
|
||||
|
@ -649,22 +683,33 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
protected void advanceCurrentPos() {
|
||||
List<Entity> entities = blockReader.getEntities()
|
||||
.collect(Collectors.toList());
|
||||
if (printingEntityIndex != -1) {
|
||||
printingEntityIndex++;
|
||||
|
||||
// End of entities reached
|
||||
if (printingEntityIndex >= entities.size()) {
|
||||
finishedPrinting();
|
||||
return;
|
||||
if (printStage == PrintStage.BLOCKS) {
|
||||
MutableBoundingBox bounds = blockReader.getBounds();
|
||||
while (tryAdvanceCurrentPos(bounds, entities)) {
|
||||
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);
|
||||
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
|
||||
if (currentPos.getY() > bounds.getYSize()) {
|
||||
printingEntityIndex = 0;
|
||||
if (entities.isEmpty()) {
|
||||
finishedPrinting();
|
||||
return;
|
||||
}
|
||||
currentPos = entities.get(0)
|
||||
.getBlockPos()
|
||||
.subtract(schematicAnchor);
|
||||
printStage = PrintStage.DEFERRED_BLOCKS;
|
||||
return false;
|
||||
}
|
||||
|
||||
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() {
|
||||
|
@ -705,10 +751,12 @@ public class SchematicannonTileEntity extends SmartTileEntity implements INamedC
|
|||
blockReader = null;
|
||||
missingItem = null;
|
||||
sendUpdate = true;
|
||||
printingEntityIndex = -1;
|
||||
printingEntityIndex = 0;
|
||||
printStage = PrintStage.BLOCKS;
|
||||
schematicProgress = 0;
|
||||
blocksPlaced = 0;
|
||||
blocksToPlace = 0;
|
||||
deferredBlocks.clear();
|
||||
}
|
||||
|
||||
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.utility.IPartialSafeNBT;
|
||||
|
||||
import net.minecraft.block.BlockState;
|
||||
import net.minecraft.nbt.CompoundNBT;
|
||||
import net.minecraft.tileentity.ITickableTileEntity;
|
||||
|
@ -16,7 +18,7 @@ import net.minecraftforge.common.capabilities.Capability;
|
|||
import net.minecraftforge.fluids.capability.CapabilityFluidHandler;
|
||||
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;
|
||||
// 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));
|
||||
}
|
||||
|
||||
public void writeSafe(CompoundNBT compound, boolean clientPacket) {
|
||||
super.write(compound);
|
||||
behaviourList.forEach(tb -> {
|
||||
if (tb.isSafeNBT())
|
||||
tb.write(compound, clientPacket);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void remove() {
|
||||
forEachBehaviour(TileEntityBehaviour::remove);
|
||||
|
|
|
@ -42,6 +42,8 @@ public abstract class TileEntityBehaviour {
|
|||
|
||||
}
|
||||
|
||||
public boolean isSafeNBT() { return false; }
|
||||
|
||||
public void onBlockChanged(BlockState oldState) {
|
||||
|
||||
}
|
||||
|
@ -94,5 +96,4 @@ public abstract class TileEntityBehaviour {
|
|||
SmartTileEntity ste = (SmartTileEntity) te;
|
||||
return ste.getBehaviour(type);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,6 +57,9 @@ public class FilteringBehaviour extends TileEntityBehaviour {
|
|||
fluidFilter = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeNBT() { return true; }
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||
nbt.put("Filter", getFilter().serializeNBT());
|
||||
|
|
|
@ -58,6 +58,9 @@ public class SidedFilteringBehaviour extends FilteringBehaviour {
|
|||
removeFilter(d);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeNBT() { return true; }
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||
nbt.put("Filters", NBTHelper.writeCompoundList(sidedFilters.entrySet(), entry -> {
|
||||
|
|
|
@ -115,6 +115,9 @@ public class LinkBehaviour extends TileEntityBehaviour {
|
|||
getHandler().removeFromNetwork(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeNBT() { return true; }
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||
super.write(nbt, clientPacket);
|
||||
|
|
|
@ -54,6 +54,9 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
|||
ticksUntilScrollPacket = -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeNBT() { return true; }
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||
nbt.putInt("ScrollValue", value);
|
||||
|
@ -95,7 +98,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
|||
clientCallback = valueCallback;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public ScrollValueBehaviour withCallback(Consumer<Integer> valueCallback) {
|
||||
callback = valueCallback;
|
||||
return this;
|
||||
|
@ -126,7 +129,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
|||
this.unit = unit;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public ScrollValueBehaviour onlyActiveWhen(Supplier<Boolean> condition) {
|
||||
isActive = condition;
|
||||
return this;
|
||||
|
@ -168,7 +171,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
|||
public BehaviourType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
|
||||
public boolean isActive() {
|
||||
return isActive.get();
|
||||
}
|
||||
|
@ -182,7 +185,7 @@ public class ScrollValueBehaviour extends TileEntityBehaviour {
|
|||
public void setLabel(ITextComponent label) {
|
||||
this.label = label;
|
||||
}
|
||||
|
||||
|
||||
public static class StepContext {
|
||||
public int currentValue;
|
||||
public boolean forward;
|
||||
|
|
|
@ -20,6 +20,9 @@ public class DeferralBehaviour extends TileEntityBehaviour {
|
|||
this.callback = callback;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSafeNBT() { return true; }
|
||||
|
||||
@Override
|
||||
public void write(CompoundNBT nbt, boolean clientPacket) {
|
||||
nbt.putBoolean("NeedsUpdate", needsUpdate);
|
||||
|
@ -38,7 +41,7 @@ public class DeferralBehaviour extends TileEntityBehaviour {
|
|||
if (needsUpdate && callback.get())
|
||||
needsUpdate = false;
|
||||
}
|
||||
|
||||
|
||||
public void scheduleUpdate() {
|
||||
needsUpdate = true;
|
||||
}
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
package com.simibubi.create.foundation.utility;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
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 com.simibubi.create.AllBlocks;
|
||||
|
@ -234,6 +243,24 @@ public class BlockHelper {
|
|||
.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,
|
||||
@Nullable CompoundNBT data) {
|
||||
// Piston
|
||||
|
@ -268,7 +295,13 @@ public class BlockHelper {
|
|||
Block.spawnDrops(state, world, target);
|
||||
return;
|
||||
}
|
||||
world.setBlockState(target, state, 18);
|
||||
|
||||
if (state.getBlock() instanceof AbstractRailBlock) {
|
||||
placeRailWithoutUpdate(world, state, target);
|
||||
} else {
|
||||
world.setBlockState(target, state, 18);
|
||||
}
|
||||
|
||||
if (data != null) {
|
||||
TileEntity tile = world.getTileEntity(target);
|
||||
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",
|
||||
"TileRemoveMixin",
|
||||
"TileWorldHookMixin",
|
||||
"WindowResizeMixin"
|
||||
"WindowResizeMixin",
|
||||
"ModelDataRefreshMixin"
|
||||
],
|
||||
"injectors": {
|
||||
"defaultRequire": 1
|
||||
|
|
Loading…
Reference in a new issue