Zappers Safe-NBT support

This commit is contained in:
Snownee 2020-12-12 19:09:10 +08:00
parent 1a052d1ec1
commit 0941d9403f
7 changed files with 70 additions and 19 deletions

View file

@ -1,6 +1,9 @@
package com.simibubi.create.content.curiosities.zapper; package com.simibubi.create.content.curiosities.zapper;
import java.util.Objects;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.networking.NbtPacket; import com.simibubi.create.foundation.networking.NbtPacket;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
@ -12,6 +15,7 @@ import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.state.properties.BlockStateProperties; import net.minecraft.state.properties.BlockStateProperties;
import net.minecraft.state.properties.StairsShape; import net.minecraft.state.properties.StairsShape;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
import net.minecraft.util.SoundCategory; import net.minecraft.util.SoundCategory;
@ -68,7 +72,7 @@ public class ZapperInteractionHandler {
if (BlockHelper.getRequiredItem(newState) if (BlockHelper.getRequiredItem(newState)
.isEmpty()) .isEmpty())
return false; return false;
if (player.world.getTileEntity(pos) != null) if (newState.hasTileEntity() && !AllBlockTags.SAFE_NBT.matches(newState))
return false; return false;
if (newState.has(BlockStateProperties.DOUBLE_BLOCK_HALF)) if (newState.has(BlockStateProperties.DOUBLE_BLOCK_HALF))
return false; return false;
@ -85,14 +89,31 @@ public class ZapperInteractionHandler {
if (newState.has(BlockStateProperties.WATERLOGGED)) if (newState.has(BlockStateProperties.WATERLOGGED))
newState = newState.with(BlockStateProperties.WATERLOGGED, false); newState = newState.with(BlockStateProperties.WATERLOGGED, false);
CompoundNBT data = null;
TileEntity tile = player.world.getTileEntity(pos);
if (tile != null) {
data = tile.write(new CompoundNBT());
data.remove("x");
data.remove("y");
data.remove("z");
data.remove("id");
}
CompoundNBT tag = stack.getOrCreateTag(); CompoundNBT tag = stack.getOrCreateTag();
if (tag.contains("BlockUsed") && NBTUtil.readBlockState(stack.getTag() if (tag.contains("BlockUsed")
.getCompound("BlockUsed")) == newState) && NBTUtil.readBlockState(
stack.getTag().getCompound("BlockUsed")) == newState
&& Objects.equals(data, tag.get("BlockData"))) {
return false; return false;
}
tag.put("BlockUsed", NBTUtil.writeBlockState(newState)); tag.put("BlockUsed", NBTUtil.writeBlockState(newState));
if (data == null)
tag.remove("BlockData");
else
tag.put("BlockData", data);
player.world.playSound(player, player.getPosition(), AllSoundEvents.BLOCKZAPPER_CONFIRM.get(), player.world.playSound(player, player.getPosition(), AllSoundEvents.BLOCKZAPPER_CONFIRM.get(),
SoundCategory.BLOCKS, 0.5f, 0.8f); SoundCategory.BLOCKS, 0.5f, 0.8f);
return true; return true;
} }

View file

@ -5,6 +5,7 @@ import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import com.simibubi.create.AllSoundEvents; import com.simibubi.create.AllSoundEvents;
import com.simibubi.create.AllTags.AllBlockTags;
import com.simibubi.create.foundation.item.ItemDescription; import com.simibubi.create.foundation.item.ItemDescription;
import com.simibubi.create.foundation.networking.AllPackets; import com.simibubi.create.foundation.networking.AllPackets;
import com.simibubi.create.foundation.utility.BlockHelper; import com.simibubi.create.foundation.utility.BlockHelper;
@ -23,6 +24,7 @@ import net.minecraft.item.Rarity;
import net.minecraft.item.UseAction; import net.minecraft.item.UseAction;
import net.minecraft.nbt.CompoundNBT; import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.NBTUtil; import net.minecraft.nbt.NBTUtil;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.ActionResult; import net.minecraft.util.ActionResult;
import net.minecraft.util.ActionResultType; import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand; import net.minecraft.util.Hand;
@ -35,12 +37,12 @@ import net.minecraft.util.math.RayTraceContext.BlockMode;
import net.minecraft.util.math.RayTraceContext.FluidMode; import net.minecraft.util.math.RayTraceContext.FluidMode;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.TranslationTextComponent; import net.minecraft.util.text.TranslationTextComponent;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn; import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.util.Constants.NBT;
import net.minecraftforge.fml.DistExecutor; import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.network.PacketDistributor; import net.minecraftforge.fml.network.PacketDistributor;
@ -149,6 +151,10 @@ public abstract class ZapperItem extends Item {
if (nbt.contains("BlockUsed")) if (nbt.contains("BlockUsed"))
stateToUse = NBTUtil.readBlockState(nbt.getCompound("BlockUsed")); stateToUse = NBTUtil.readBlockState(nbt.getCompound("BlockUsed"));
stateToUse = BlockHelper.setZeroAge(stateToUse); stateToUse = BlockHelper.setZeroAge(stateToUse);
CompoundNBT data = null;
if (AllBlockTags.SAFE_NBT.matches(stateToUse) && nbt.contains("BlockData", NBT.TAG_COMPOUND)) {
data = nbt.getCompound("BlockData");
}
// Raytrace - Find the target // Raytrace - Find the target
Vec3d start = player.getPositionVec() Vec3d start = player.getPositionVec()
@ -181,7 +187,7 @@ public abstract class ZapperItem extends Item {
} }
// Server side // Server side
if (activate(world, player, item, stateToUse, raytrace)) { if (activate(world, player, item, stateToUse, raytrace, data)) {
applyCooldown(player, item, gunInOtherHand); applyCooldown(player, item, gunInOtherHand);
AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> player), AllPackets.channel.send(PacketDistributor.TRACKING_ENTITY.with(() -> player),
new ZapperBeamPacket(barrelPos, raytrace.getHitVec(), hand, false)); new ZapperBeamPacket(barrelPos, raytrace.getHitVec(), hand, false));
@ -200,7 +206,7 @@ public abstract class ZapperItem extends Item {
} }
protected abstract boolean activate(World world, PlayerEntity player, ItemStack item, BlockState stateToUse, protected abstract boolean activate(World world, PlayerEntity player, ItemStack item, BlockState stateToUse,
BlockRayTraceResult raytrace); BlockRayTraceResult raytrace, CompoundNBT data);
@OnlyIn(Dist.CLIENT) @OnlyIn(Dist.CLIENT)
protected abstract void openHandgunGUI(ItemStack item, boolean b); protected abstract void openHandgunGUI(ItemStack item, boolean b);
@ -234,4 +240,16 @@ public abstract class ZapperItem extends Item {
return UseAction.NONE; return UseAction.NONE;
} }
public static void setTileData(World world, BlockPos pos, CompoundNBT data) {
if (data != null) {
TileEntity tile = world.getTileEntity(pos);
if (tile != null && !tile.onlyOpsCanSetNbt()) {
data.putInt("x", pos.getX());
data.putInt("y", pos.getY());
data.putInt("z", pos.getZ());
tile.read(data);
}
}
}
} }

View file

@ -22,7 +22,6 @@ import com.simibubi.create.foundation.utility.NBTHelper;
import net.minecraft.advancements.CriteriaTriggers; import net.minecraft.advancements.CriteriaTriggers;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.RedstoneLampBlock;
import net.minecraft.client.gui.screen.Screen; import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.util.ITooltipFlag; import net.minecraft.client.util.ITooltipFlag;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
@ -97,7 +96,7 @@ public class BlockzapperItem extends ZapperItem {
@Override @Override
protected boolean activate(World world, PlayerEntity player, ItemStack stack, BlockState selectedState, protected boolean activate(World world, PlayerEntity player, ItemStack stack, BlockState selectedState,
BlockRayTraceResult raytrace) { BlockRayTraceResult raytrace, CompoundNBT data) {
CompoundNBT nbt = stack.getOrCreateTag(); CompoundNBT nbt = stack.getOrCreateTag();
boolean replace = nbt.contains("Replace") && nbt.getBoolean("Replace"); boolean replace = nbt.contains("Replace") && nbt.getBoolean("Replace");
@ -136,6 +135,7 @@ public class BlockzapperItem extends ZapperItem {
blocksnapshot.restore(true, false); blocksnapshot.restore(true, false);
return false; return false;
} }
setTileData(world, placed, data);
if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) { if (player instanceof ServerPlayerEntity && world instanceof ServerWorld) {
ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player; ServerPlayerEntity serverPlayer = (ServerPlayerEntity) player;

View file

@ -4,11 +4,13 @@ import java.util.List;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import com.simibubi.create.content.curiosities.zapper.ZapperItem;
import com.simibubi.create.foundation.gui.AllIcons; import com.simibubi.create.foundation.gui.AllIcons;
import com.simibubi.create.foundation.utility.Lang; import com.simibubi.create.foundation.utility.Lang;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.Direction; import net.minecraft.util.Direction;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
@ -34,7 +36,7 @@ public enum TerrainTools {
return this != Clear && this != Flatten; return this != Clear && this != Flatten;
} }
public void run(World world, List<BlockPos> targetPositions, Direction facing, @Nullable BlockState paintedState) { public void run(World world, List<BlockPos> targetPositions, Direction facing, @Nullable BlockState paintedState, @Nullable CompoundNBT data) {
switch (this) { switch (this) {
case Clear: case Clear:
targetPositions.forEach(p -> world.setBlockState(p, Blocks.AIR.getDefaultState())); targetPositions.forEach(p -> world.setBlockState(p, Blocks.AIR.getDefaultState()));
@ -45,6 +47,7 @@ public enum TerrainTools {
if (!isReplaceable(toReplace)) if (!isReplaceable(toReplace))
return; return;
world.setBlockState(p, paintedState); world.setBlockState(p, paintedState);
ZapperItem.setTileData(world, p, data);
}); });
break; break;
case Flatten: case Flatten:
@ -64,11 +67,13 @@ public enum TerrainTools {
if (!isReplaceable(toReplace)) if (!isReplaceable(toReplace))
return; return;
world.setBlockState(p, paintedState); world.setBlockState(p, paintedState);
ZapperItem.setTileData(world, p, data);
}); });
break; break;
case Place: case Place:
targetPositions.forEach(p -> { targetPositions.forEach(p -> {
world.setBlockState(p, paintedState); world.setBlockState(p, paintedState);
ZapperItem.setTileData(world, p, data);
}); });
break; break;
case Replace: case Replace:
@ -77,6 +82,7 @@ public enum TerrainTools {
if (isReplaceable(toReplace)) if (isReplaceable(toReplace))
return; return;
world.setBlockState(p, paintedState); world.setBlockState(p, paintedState);
ZapperItem.setTileData(world, p, data);
}); });
break; break;
} }

View file

@ -60,7 +60,7 @@ public class WorldshaperItem extends ZapperItem {
@Override @Override
protected boolean activate(World world, PlayerEntity player, ItemStack stack, BlockState stateToUse, protected boolean activate(World world, PlayerEntity player, ItemStack stack, BlockState stateToUse,
BlockRayTraceResult raytrace) { BlockRayTraceResult raytrace, CompoundNBT data) {
BlockPos targetPos = raytrace.getPos(); BlockPos targetPos = raytrace.getPos();
List<BlockPos> affectedPositions = new ArrayList<>(); List<BlockPos> affectedPositions = new ArrayList<>();
@ -77,7 +77,7 @@ public class WorldshaperItem extends ZapperItem {
for (BlockPos blockPos : brush.getIncludedPositions()) for (BlockPos blockPos : brush.getIncludedPositions())
affectedPositions.add(targetPos.add(blockPos)); affectedPositions.add(targetPos.add(blockPos));
PlacementPatterns.applyPattern(affectedPositions, stack); PlacementPatterns.applyPattern(affectedPositions, stack);
tool.run(world, affectedPositions, raytrace.getFace(), stateToUse); tool.run(world, affectedPositions, raytrace.getFace(), stateToUse, data);
return true; return true;
} }

View file

@ -107,6 +107,10 @@ public abstract class LaunchedItem {
CompoundNBT serializeNBT = super.serializeNBT(); CompoundNBT serializeNBT = super.serializeNBT();
serializeNBT.put("BlockState", NBTUtil.writeBlockState(state)); serializeNBT.put("BlockState", NBTUtil.writeBlockState(state));
if (data != null) { if (data != null) {
data.remove("x");
data.remove("y");
data.remove("z");
data.remove("id");
serializeNBT.put("Data", data); serializeNBT.put("Data", data);
} }
return serializeNBT; return serializeNBT;
@ -154,6 +158,9 @@ public abstract class LaunchedItem {
if (data != null) { if (data != null) {
TileEntity tile = world.getTileEntity(target); TileEntity tile = world.getTileEntity(target);
if (tile != null) { if (tile != null) {
data.putInt("x", target.getX());
data.putInt("y", target.getY());
data.putInt("z", target.getZ());
tile.read(data); tile.read(data);
} }
} }

View file

@ -1,9 +1,8 @@
package com.simibubi.create.foundation.tileEntity.behaviour.linked; package com.simibubi.create.foundation.tileEntity.behaviour.linked;
import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
import java.util.function.Supplier; import java.util.function.IntConsumer;
import java.util.function.IntSupplier;
import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.lang3.tuple.Pair;
import com.simibubi.create.Create; import com.simibubi.create.Create;
@ -35,8 +34,8 @@ public class LinkBehaviour extends TileEntityBehaviour {
public boolean newPosition; public boolean newPosition;
private Mode mode; private Mode mode;
private Supplier<Integer> transmission; private IntSupplier transmission;
private Consumer<Integer> signalCallback; private IntConsumer signalCallback;
protected LinkBehaviour(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots) { protected LinkBehaviour(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots) {
super(te); super(te);
@ -49,7 +48,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
} }
public static LinkBehaviour receiver(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots, public static LinkBehaviour receiver(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
Consumer<Integer> signalCallback) { IntConsumer signalCallback) {
LinkBehaviour behaviour = new LinkBehaviour(te, slots); LinkBehaviour behaviour = new LinkBehaviour(te, slots);
behaviour.signalCallback = signalCallback; behaviour.signalCallback = signalCallback;
behaviour.mode = Mode.RECEIVE; behaviour.mode = Mode.RECEIVE;
@ -57,7 +56,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
} }
public static LinkBehaviour transmitter(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots, public static LinkBehaviour transmitter(SmartTileEntity te, Pair<ValueBoxTransform, ValueBoxTransform> slots,
Supplier<Integer> transmission) { IntSupplier transmission) {
LinkBehaviour behaviour = new LinkBehaviour(te, slots); LinkBehaviour behaviour = new LinkBehaviour(te, slots);
behaviour.transmission = transmission; behaviour.transmission = transmission;
behaviour.mode = Mode.TRANSMIT; behaviour.mode = Mode.TRANSMIT;
@ -81,7 +80,7 @@ public class LinkBehaviour extends TileEntityBehaviour {
} }
public int getTransmittedStrength() { public int getTransmittedStrength() {
return mode == Mode.TRANSMIT ? transmission.get() : 0; return mode == Mode.TRANSMIT ? transmission.getAsInt() : 0;
} }
public void updateReceiver(int networkPower) { public void updateReceiver(int networkPower) {