mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-13 13:43:16 +01:00
Multiblock Madness
- Fixed moving single-tile tanks and vaults leading to corrupt nbt #6915 #6925 #6943 #6979 - Display links now check for click events in transferred components #6942 - Fixed negative values displayed on kinetic generator goggle overlay
This commit is contained in:
parent
f51c99e715
commit
2828c88d80
11 changed files with 97 additions and 35 deletions
|
@ -1139,6 +1139,7 @@ public abstract class Contraption {
|
|||
if (blockEntity instanceof IMultiBlockEntityContainer) {
|
||||
if (tag.contains("LastKnownPos") || capturedMultiblocks.isEmpty()) {
|
||||
tag.put("LastKnownPos", NbtUtils.writeBlockPos(BlockPos.ZERO.below(Integer.MAX_VALUE - 1)));
|
||||
tag.remove("Controller");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1195,6 +1196,9 @@ public abstract class Contraption {
|
|||
// swap nbt data to the new controller position
|
||||
StructureBlockInfo prevControllerInfo = blocks.get(controllerPos);
|
||||
StructureBlockInfo newControllerInfo = blocks.get(otherPos);
|
||||
if (prevControllerInfo == null || newControllerInfo == null)
|
||||
return;
|
||||
|
||||
blocks.put(otherPos, new StructureBlockInfo(newControllerInfo.pos, newControllerInfo.state, prevControllerInfo.nbt));
|
||||
blocks.put(controllerPos, new StructureBlockInfo(prevControllerInfo.pos, prevControllerInfo.state, newControllerInfo.nbt));
|
||||
});
|
||||
|
|
|
@ -73,9 +73,8 @@ public abstract class GeneratingKineticBlockEntity extends KineticBlockEntity {
|
|||
float speed = getTheoreticalSpeed();
|
||||
if (speed != getGeneratedSpeed() && speed != 0)
|
||||
stressBase *= getGeneratedSpeed() / speed;
|
||||
speed = Math.abs(speed);
|
||||
|
||||
float stressTotal = stressBase * speed;
|
||||
float stressTotal = Math.abs(stressBase * speed);
|
||||
|
||||
Lang.number(stressTotal)
|
||||
.translate("generic.unit.stress")
|
||||
|
|
|
@ -13,6 +13,7 @@ import com.simibubi.create.content.trains.display.FlapDisplayBlockEntity;
|
|||
import com.simibubi.create.content.trains.display.FlapDisplayLayout;
|
||||
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
|
||||
import com.simibubi.create.foundation.utility.Components;
|
||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||
|
||||
import net.minecraft.network.chat.Component;
|
||||
import net.minecraft.network.chat.MutableComponent;
|
||||
|
@ -38,6 +39,12 @@ public abstract class DisplaySource extends DisplayBehaviour {
|
|||
List<MutableComponent> text = provideText(context, stats);
|
||||
if (text.isEmpty())
|
||||
text = EMPTY;
|
||||
|
||||
if (activeTarget.requiresComponentSanitization())
|
||||
for (MutableComponent component : text)
|
||||
if (NBTProcessors.textComponentHasClickEvent(component))
|
||||
return; // Naughty
|
||||
|
||||
activeTarget.acceptText(line, text, context);
|
||||
}
|
||||
|
||||
|
|
|
@ -68,4 +68,8 @@ public abstract class DisplayTarget extends DisplayBehaviour {
|
|||
return false;
|
||||
}
|
||||
|
||||
public boolean requiresComponentSanitization() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -81,4 +81,9 @@ public class LecternDisplayTarget extends DisplayTarget {
|
|||
return written;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresComponentSanitization() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -36,4 +36,9 @@ public class SignDisplayTarget extends DisplayTarget {
|
|||
return new DisplayTargetStats(4, 15, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresComponentSanitization() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,8 @@ import java.util.function.Predicate;
|
|||
import java.util.stream.Stream;
|
||||
|
||||
import com.simibubi.create.Create;
|
||||
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.utility.BBHelper;
|
||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||
|
@ -251,4 +253,24 @@ public class SchematicWorld extends WrappedWorld implements ServerLevelAccessor
|
|||
throw new IllegalStateException("Cannot use IServerWorld#getWorld in a client environment");
|
||||
}
|
||||
|
||||
public void fixControllerBlockEntities() {
|
||||
for (BlockEntity blockEntity : blockEntities.values()) {
|
||||
if (!(blockEntity instanceof IMultiBlockEntityContainer multiBlockEntity))
|
||||
continue;
|
||||
BlockPos lastKnown = multiBlockEntity.getLastKnownPos();
|
||||
BlockPos current = blockEntity.getBlockPos();
|
||||
if (lastKnown == null || current == null)
|
||||
continue;
|
||||
if (multiBlockEntity.isController())
|
||||
continue;
|
||||
if (!lastKnown.equals(current)) {
|
||||
BlockPos newControllerPos = multiBlockEntity.getController()
|
||||
.offset(current.subtract(lastKnown));
|
||||
if (multiBlockEntity instanceof SmartBlockEntity sbe)
|
||||
sbe.markVirtual();
|
||||
multiBlockEntity.setController(newControllerPos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -168,6 +168,7 @@ public class SchematicHandler {
|
|||
schematic.placeInWorld(w, pos, pos, placementSettings, w.getRandom(), Block.UPDATE_CLIENTS);
|
||||
for (BlockEntity blockEntity : w.getBlockEntities())
|
||||
blockEntity.setLevel(w);
|
||||
w.fixControllerBlockEntities();
|
||||
} catch (Exception e) {
|
||||
Minecraft.getInstance().player.displayClientMessage(Lang.translate("schematic.error")
|
||||
.component(), false);
|
||||
|
@ -182,6 +183,7 @@ public class SchematicHandler {
|
|||
placementSettings.getMirror());
|
||||
for (BlockEntity be : wMirroredFB.getRenderedBlockEntities())
|
||||
transform.apply(be);
|
||||
wMirroredFB.fixControllerBlockEntities();
|
||||
|
||||
placementSettings.setMirror(Mirror.LEFT_RIGHT);
|
||||
pos = BlockPos.ZERO.south(size.getZ() - 1);
|
||||
|
@ -190,6 +192,7 @@ public class SchematicHandler {
|
|||
placementSettings.getMirror());
|
||||
for (BlockEntity be : wMirroredLR.getRenderedBlockEntities())
|
||||
transform.apply(be);
|
||||
wMirroredLR.fixControllerBlockEntities();
|
||||
|
||||
renderers.get(0)
|
||||
.display(w);
|
||||
|
|
|
@ -14,7 +14,6 @@ import com.mojang.blaze3d.vertex.PoseStack;
|
|||
import com.simibubi.create.content.kinetics.belt.BeltBlock;
|
||||
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
|
||||
import com.simibubi.create.content.schematics.SchematicWorld;
|
||||
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||
import com.simibubi.create.foundation.blockEntity.SmartBlockEntity;
|
||||
import com.simibubi.create.foundation.mixin.accessor.ParticleEngineAccessor;
|
||||
import com.simibubi.create.foundation.ponder.element.WorldSectionElement;
|
||||
|
@ -252,38 +251,22 @@ public class PonderWorld extends SchematicWorld {
|
|||
smartBlockEntity.markVirtual();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixControllerBlockEntities() {
|
||||
super.fixControllerBlockEntities();
|
||||
for (BlockEntity blockEntity : blockEntities.values()) {
|
||||
|
||||
if (blockEntity instanceof BeltBlockEntity) {
|
||||
BeltBlockEntity beltBlockEntity = (BeltBlockEntity) blockEntity;
|
||||
if (!beltBlockEntity.isController())
|
||||
if (!(blockEntity instanceof BeltBlockEntity beltBlockEntity))
|
||||
continue;
|
||||
if (!beltBlockEntity.isController())
|
||||
continue;
|
||||
BlockPos controllerPos = blockEntity.getBlockPos();
|
||||
for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) {
|
||||
BlockEntity blockEntity2 = getBlockEntity(blockPos);
|
||||
if (!(blockEntity2 instanceof BeltBlockEntity))
|
||||
continue;
|
||||
BlockPos controllerPos = blockEntity.getBlockPos();
|
||||
for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) {
|
||||
BlockEntity blockEntity2 = getBlockEntity(blockPos);
|
||||
if (!(blockEntity2 instanceof BeltBlockEntity))
|
||||
continue;
|
||||
BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2;
|
||||
belt2.setController(controllerPos);
|
||||
}
|
||||
BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2;
|
||||
belt2.setController(controllerPos);
|
||||
}
|
||||
|
||||
if (blockEntity instanceof IMultiBlockEntityContainer) {
|
||||
IMultiBlockEntityContainer multiBlockEntity = (IMultiBlockEntityContainer) blockEntity;
|
||||
BlockPos lastKnown = multiBlockEntity.getLastKnownPos();
|
||||
BlockPos current = blockEntity.getBlockPos();
|
||||
if (lastKnown == null || current == null)
|
||||
continue;
|
||||
if (multiBlockEntity.isController())
|
||||
continue;
|
||||
if (!lastKnown.equals(current)) {
|
||||
BlockPos newControllerPos = multiBlockEntity.getController()
|
||||
.offset(current.subtract(lastKnown));
|
||||
multiBlockEntity.setController(newControllerPos);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ import com.simibubi.create.content.kinetics.base.KineticBlockEntity;
|
|||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock;
|
||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||
import com.simibubi.create.foundation.blockEntity.IMergeableBE;
|
||||
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||
|
||||
import net.minecraft.core.BlockPos;
|
||||
import net.minecraft.core.Direction;
|
||||
|
@ -19,6 +20,7 @@ import net.minecraft.core.Registry;
|
|||
import net.minecraft.core.SectionPos;
|
||||
import net.minecraft.core.particles.ParticleTypes;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.nbt.NbtUtils;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundEvents;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
|
@ -316,8 +318,11 @@ public class BlockHelper {
|
|||
data.putInt("x", target.getX());
|
||||
data.putInt("y", target.getY());
|
||||
data.putInt("z", target.getZ());
|
||||
if (blockEntity instanceof KineticBlockEntity)
|
||||
((KineticBlockEntity) blockEntity).warnOfMovement();
|
||||
if (blockEntity instanceof KineticBlockEntity kbe)
|
||||
kbe.warnOfMovement();
|
||||
if (blockEntity instanceof IMultiBlockEntityContainer imbe)
|
||||
if (!imbe.isController())
|
||||
data.put("Controller", NbtUtils.writeBlockPos(imbe.getController()));
|
||||
blockEntity.load(data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.utility;
|
|||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.UnaryOperator;
|
||||
|
||||
|
@ -57,6 +58,24 @@ public final class NBTProcessors {
|
|||
});
|
||||
addProcessor(AllBlockEntityTypes.CREATIVE_CRATE.get(), itemProcessor("Filter"));
|
||||
addProcessor(AllBlockEntityTypes.PLACARD.get(), itemProcessor("Item"));
|
||||
addProcessor(AllBlockEntityTypes.CLIPBOARD.get(), data -> {
|
||||
if (!data.contains("Item", Tag.TAG_COMPOUND))
|
||||
return data;
|
||||
CompoundTag book = data.getCompound("Item");
|
||||
|
||||
if (!book.contains("tag", Tag.TAG_COMPOUND))
|
||||
return data;
|
||||
CompoundTag itemData = book.getCompound("tag");
|
||||
|
||||
for (List<String> entries : NBTHelper.readCompoundList(itemData.getList("Pages", Tag.TAG_COMPOUND),
|
||||
pageTag -> NBTHelper.readCompoundList(pageTag.getList("Entries", Tag.TAG_COMPOUND),
|
||||
tag -> tag.getString("Text")))) {
|
||||
for (String entry : entries)
|
||||
if (textComponentHasClickEvent(entry))
|
||||
return null;
|
||||
}
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
// Triggered by block tag, not BE type
|
||||
|
@ -120,7 +139,13 @@ public final class NBTProcessors {
|
|||
}
|
||||
|
||||
public static boolean textComponentHasClickEvent(String json) {
|
||||
Component component = Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json);
|
||||
return textComponentHasClickEvent(Component.Serializer.fromJson(json.isEmpty() ? "\"\"" : json));
|
||||
}
|
||||
|
||||
public static boolean textComponentHasClickEvent(Component component) {
|
||||
for (Component sibling : component.getSiblings())
|
||||
if (textComponentHasClickEvent(sibling))
|
||||
return true;
|
||||
return component != null && component.getStyle() != null && component.getStyle()
|
||||
.getClickEvent() != null;
|
||||
}
|
||||
|
@ -144,7 +169,7 @@ public final class NBTProcessors {
|
|||
return signProcessor.apply(compound);
|
||||
if (blockEntity.onlyOpCanSetNbt())
|
||||
return null;
|
||||
return withUnsafeNBTDiscarded(compound);
|
||||
return compound;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue