mirror of
https://github.com/Creators-of-Create/Create.git
synced 2024-12-13 13:33:20 +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 (blockEntity instanceof IMultiBlockEntityContainer) {
|
||||||
if (tag.contains("LastKnownPos") || capturedMultiblocks.isEmpty()) {
|
if (tag.contains("LastKnownPos") || capturedMultiblocks.isEmpty()) {
|
||||||
tag.put("LastKnownPos", NbtUtils.writeBlockPos(BlockPos.ZERO.below(Integer.MAX_VALUE - 1)));
|
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
|
// swap nbt data to the new controller position
|
||||||
StructureBlockInfo prevControllerInfo = blocks.get(controllerPos);
|
StructureBlockInfo prevControllerInfo = blocks.get(controllerPos);
|
||||||
StructureBlockInfo newControllerInfo = blocks.get(otherPos);
|
StructureBlockInfo newControllerInfo = blocks.get(otherPos);
|
||||||
|
if (prevControllerInfo == null || newControllerInfo == null)
|
||||||
|
return;
|
||||||
|
|
||||||
blocks.put(otherPos, new StructureBlockInfo(newControllerInfo.pos, newControllerInfo.state, prevControllerInfo.nbt));
|
blocks.put(otherPos, new StructureBlockInfo(newControllerInfo.pos, newControllerInfo.state, prevControllerInfo.nbt));
|
||||||
blocks.put(controllerPos, new StructureBlockInfo(prevControllerInfo.pos, prevControllerInfo.state, newControllerInfo.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();
|
float speed = getTheoreticalSpeed();
|
||||||
if (speed != getGeneratedSpeed() && speed != 0)
|
if (speed != getGeneratedSpeed() && speed != 0)
|
||||||
stressBase *= getGeneratedSpeed() / speed;
|
stressBase *= getGeneratedSpeed() / speed;
|
||||||
speed = Math.abs(speed);
|
|
||||||
|
|
||||||
float stressTotal = stressBase * speed;
|
float stressTotal = Math.abs(stressBase * speed);
|
||||||
|
|
||||||
Lang.number(stressTotal)
|
Lang.number(stressTotal)
|
||||||
.translate("generic.unit.stress")
|
.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.content.trains.display.FlapDisplayLayout;
|
||||||
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
|
import com.simibubi.create.foundation.gui.ModularGuiLineBuilder;
|
||||||
import com.simibubi.create.foundation.utility.Components;
|
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.Component;
|
||||||
import net.minecraft.network.chat.MutableComponent;
|
import net.minecraft.network.chat.MutableComponent;
|
||||||
|
@ -38,6 +39,12 @@ public abstract class DisplaySource extends DisplayBehaviour {
|
||||||
List<MutableComponent> text = provideText(context, stats);
|
List<MutableComponent> text = provideText(context, stats);
|
||||||
if (text.isEmpty())
|
if (text.isEmpty())
|
||||||
text = EMPTY;
|
text = EMPTY;
|
||||||
|
|
||||||
|
if (activeTarget.requiresComponentSanitization())
|
||||||
|
for (MutableComponent component : text)
|
||||||
|
if (NBTProcessors.textComponentHasClickEvent(component))
|
||||||
|
return; // Naughty
|
||||||
|
|
||||||
activeTarget.acceptText(line, text, context);
|
activeTarget.acceptText(line, text, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -67,5 +67,9 @@ public abstract class DisplayTarget extends DisplayBehaviour {
|
||||||
tag.remove("DisplayLink");
|
tag.remove("DisplayLink");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean requiresComponentSanitization() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,5 +80,10 @@ public class LecternDisplayTarget extends DisplayTarget {
|
||||||
|
|
||||||
return written;
|
return written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean requiresComponentSanitization() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,5 +35,10 @@ public class SignDisplayTarget extends DisplayTarget {
|
||||||
public DisplayTargetStats provideStats(DisplayLinkContext context) {
|
public DisplayTargetStats provideStats(DisplayLinkContext context) {
|
||||||
return new DisplayTargetStats(4, 15, this);
|
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 java.util.stream.Stream;
|
||||||
|
|
||||||
import com.simibubi.create.Create;
|
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.BBHelper;
|
||||||
import com.simibubi.create.foundation.utility.NBTProcessors;
|
import com.simibubi.create.foundation.utility.NBTProcessors;
|
||||||
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
import com.simibubi.create.foundation.utility.worldWrappers.WrappedWorld;
|
||||||
|
@ -250,5 +252,25 @@ public class SchematicWorld extends WrappedWorld implements ServerLevelAccessor
|
||||||
}
|
}
|
||||||
throw new IllegalStateException("Cannot use IServerWorld#getWorld in a client environment");
|
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);
|
schematic.placeInWorld(w, pos, pos, placementSettings, w.getRandom(), Block.UPDATE_CLIENTS);
|
||||||
for (BlockEntity blockEntity : w.getBlockEntities())
|
for (BlockEntity blockEntity : w.getBlockEntities())
|
||||||
blockEntity.setLevel(w);
|
blockEntity.setLevel(w);
|
||||||
|
w.fixControllerBlockEntities();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Minecraft.getInstance().player.displayClientMessage(Lang.translate("schematic.error")
|
Minecraft.getInstance().player.displayClientMessage(Lang.translate("schematic.error")
|
||||||
.component(), false);
|
.component(), false);
|
||||||
|
@ -182,6 +183,7 @@ public class SchematicHandler {
|
||||||
placementSettings.getMirror());
|
placementSettings.getMirror());
|
||||||
for (BlockEntity be : wMirroredFB.getRenderedBlockEntities())
|
for (BlockEntity be : wMirroredFB.getRenderedBlockEntities())
|
||||||
transform.apply(be);
|
transform.apply(be);
|
||||||
|
wMirroredFB.fixControllerBlockEntities();
|
||||||
|
|
||||||
placementSettings.setMirror(Mirror.LEFT_RIGHT);
|
placementSettings.setMirror(Mirror.LEFT_RIGHT);
|
||||||
pos = BlockPos.ZERO.south(size.getZ() - 1);
|
pos = BlockPos.ZERO.south(size.getZ() - 1);
|
||||||
|
@ -190,6 +192,7 @@ public class SchematicHandler {
|
||||||
placementSettings.getMirror());
|
placementSettings.getMirror());
|
||||||
for (BlockEntity be : wMirroredLR.getRenderedBlockEntities())
|
for (BlockEntity be : wMirroredLR.getRenderedBlockEntities())
|
||||||
transform.apply(be);
|
transform.apply(be);
|
||||||
|
wMirroredLR.fixControllerBlockEntities();
|
||||||
|
|
||||||
renderers.get(0)
|
renderers.get(0)
|
||||||
.display(w);
|
.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.BeltBlock;
|
||||||
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
|
import com.simibubi.create.content.kinetics.belt.BeltBlockEntity;
|
||||||
import com.simibubi.create.content.schematics.SchematicWorld;
|
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.blockEntity.SmartBlockEntity;
|
||||||
import com.simibubi.create.foundation.mixin.accessor.ParticleEngineAccessor;
|
import com.simibubi.create.foundation.mixin.accessor.ParticleEngineAccessor;
|
||||||
import com.simibubi.create.foundation.ponder.element.WorldSectionElement;
|
import com.simibubi.create.foundation.ponder.element.WorldSectionElement;
|
||||||
|
@ -252,38 +251,22 @@ public class PonderWorld extends SchematicWorld {
|
||||||
smartBlockEntity.markVirtual();
|
smartBlockEntity.markVirtual();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public void fixControllerBlockEntities() {
|
public void fixControllerBlockEntities() {
|
||||||
|
super.fixControllerBlockEntities();
|
||||||
for (BlockEntity blockEntity : blockEntities.values()) {
|
for (BlockEntity blockEntity : blockEntities.values()) {
|
||||||
|
if (!(blockEntity instanceof BeltBlockEntity beltBlockEntity))
|
||||||
if (blockEntity instanceof BeltBlockEntity) {
|
continue;
|
||||||
BeltBlockEntity beltBlockEntity = (BeltBlockEntity) blockEntity;
|
if (!beltBlockEntity.isController())
|
||||||
if (!beltBlockEntity.isController())
|
continue;
|
||||||
|
BlockPos controllerPos = blockEntity.getBlockPos();
|
||||||
|
for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) {
|
||||||
|
BlockEntity blockEntity2 = getBlockEntity(blockPos);
|
||||||
|
if (!(blockEntity2 instanceof BeltBlockEntity))
|
||||||
continue;
|
continue;
|
||||||
BlockPos controllerPos = blockEntity.getBlockPos();
|
BeltBlockEntity belt2 = (BeltBlockEntity) blockEntity2;
|
||||||
for (BlockPos blockPos : BeltBlock.getBeltChain(this, controllerPos)) {
|
belt2.setController(controllerPos);
|
||||||
BlockEntity blockEntity2 = getBlockEntity(blockPos);
|
|
||||||
if (!(blockEntity2 instanceof BeltBlockEntity))
|
|
||||||
continue;
|
|
||||||
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;
|
||||||
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
import com.simibubi.create.content.processing.burner.BlazeBurnerBlock.HeatLevel;
|
||||||
import com.simibubi.create.foundation.blockEntity.IMergeableBE;
|
import com.simibubi.create.foundation.blockEntity.IMergeableBE;
|
||||||
|
import com.simibubi.create.foundation.blockEntity.IMultiBlockEntityContainer;
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.core.Direction;
|
import net.minecraft.core.Direction;
|
||||||
|
@ -19,6 +20,7 @@ import net.minecraft.core.Registry;
|
||||||
import net.minecraft.core.SectionPos;
|
import net.minecraft.core.SectionPos;
|
||||||
import net.minecraft.core.particles.ParticleTypes;
|
import net.minecraft.core.particles.ParticleTypes;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
|
import net.minecraft.nbt.NbtUtils;
|
||||||
import net.minecraft.server.level.ServerLevel;
|
import net.minecraft.server.level.ServerLevel;
|
||||||
import net.minecraft.sounds.SoundEvents;
|
import net.minecraft.sounds.SoundEvents;
|
||||||
import net.minecraft.sounds.SoundSource;
|
import net.minecraft.sounds.SoundSource;
|
||||||
|
@ -316,8 +318,11 @@ public class BlockHelper {
|
||||||
data.putInt("x", target.getX());
|
data.putInt("x", target.getX());
|
||||||
data.putInt("y", target.getY());
|
data.putInt("y", target.getY());
|
||||||
data.putInt("z", target.getZ());
|
data.putInt("z", target.getZ());
|
||||||
if (blockEntity instanceof KineticBlockEntity)
|
if (blockEntity instanceof KineticBlockEntity kbe)
|
||||||
((KineticBlockEntity) blockEntity).warnOfMovement();
|
kbe.warnOfMovement();
|
||||||
|
if (blockEntity instanceof IMultiBlockEntityContainer imbe)
|
||||||
|
if (!imbe.isController())
|
||||||
|
data.put("Controller", NbtUtils.writeBlockPos(imbe.getController()));
|
||||||
blockEntity.load(data);
|
blockEntity.load(data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.simibubi.create.foundation.utility;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.UnaryOperator;
|
import java.util.function.UnaryOperator;
|
||||||
|
|
||||||
|
@ -57,6 +58,24 @@ public final class NBTProcessors {
|
||||||
});
|
});
|
||||||
addProcessor(AllBlockEntityTypes.CREATIVE_CRATE.get(), itemProcessor("Filter"));
|
addProcessor(AllBlockEntityTypes.CREATIVE_CRATE.get(), itemProcessor("Filter"));
|
||||||
addProcessor(AllBlockEntityTypes.PLACARD.get(), itemProcessor("Item"));
|
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
|
// Triggered by block tag, not BE type
|
||||||
|
@ -120,7 +139,13 @@ public final class NBTProcessors {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean textComponentHasClickEvent(String json) {
|
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()
|
return component != null && component.getStyle() != null && component.getStyle()
|
||||||
.getClickEvent() != null;
|
.getClickEvent() != null;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +169,7 @@ public final class NBTProcessors {
|
||||||
return signProcessor.apply(compound);
|
return signProcessor.apply(compound);
|
||||||
if (blockEntity.onlyOpCanSetNbt())
|
if (blockEntity.onlyOpCanSetNbt())
|
||||||
return null;
|
return null;
|
||||||
return withUnsafeNBTDiscarded(compound);
|
return compound;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue