mirror of
https://github.com/XevianLight/Aphelion.git
synced 2026-05-11 01:50:56 +01:00
RocketEntity.disassemble and dupe fixes. Fixed VAF menu not appearing.
This commit is contained in:
@@ -42,7 +42,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvider, TickableBlockEntity {
|
public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvider, TickableBlockEntity, IArcFurnaceLike {
|
||||||
|
|
||||||
private final int SIZE = 4;
|
private final int SIZE = 4;
|
||||||
private int ENERGY_CAPACITY = 64000;
|
private int ENERGY_CAPACITY = 64000;
|
||||||
@@ -309,6 +309,11 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
|||||||
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
level.sendBlockUpdated(getBlockPos(), getBlockState(), getBlockState(), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IEnergyStorage getTrueEnergyStorage() {
|
||||||
|
return ENERGY_STORAGE;
|
||||||
|
}
|
||||||
|
|
||||||
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{INPUT_SLOT, SECONDARY_INPUT_SLOT, OUTPUT_SLOT, ENERGY_SLOT}, true, true);
|
private final IItemHandler fullHandler = new SidedSlotHandler(inventory, new int[]{INPUT_SLOT, SECONDARY_INPUT_SLOT, OUTPUT_SLOT, ENERGY_SLOT}, true, true);
|
||||||
private final IItemHandler emptyJeiHandler = new SidedSlotHandler(inventory, new int[]{}, false, false);
|
private final IItemHandler emptyJeiHandler = new SidedSlotHandler(inventory, new int[]{}, false, false);
|
||||||
private final IItemHandler inputHandler = new SidedSlotHandler(inventory, new int[]{0,1}, true, true);
|
private final IItemHandler inputHandler = new SidedSlotHandler(inventory, new int[]{0,1}, true, true);
|
||||||
@@ -344,6 +349,11 @@ public class ElectricArcFurnaceEntity extends BlockEntity implements MenuProvide
|
|||||||
return inventory;
|
return inventory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModEnergyStorage getEnergy() {
|
||||||
|
return ENERGY_STORAGE;
|
||||||
|
}
|
||||||
|
|
||||||
public void drops() {
|
public void drops() {
|
||||||
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
SimpleContainer inv = new SimpleContainer(inventory.getSlots());
|
||||||
for(int i = 0; i < inventory.getSlots(); i++) {
|
for(int i = 0; i < inventory.getSlots(); i++) {
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package net.xevianlight.aphelion.block.entity.custom;
|
||||||
|
|
||||||
|
import net.minecraft.core.Direction;
|
||||||
|
import net.minecraft.world.inventory.ContainerData;
|
||||||
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.neoforged.neoforge.energy.IEnergyStorage;
|
||||||
|
import net.neoforged.neoforge.items.ItemStackHandler;
|
||||||
|
import net.xevianlight.aphelion.block.entity.energy.ModEnergyStorage;
|
||||||
|
|
||||||
|
|
||||||
|
public interface IArcFurnaceLike {
|
||||||
|
ItemStackHandler getInventory();
|
||||||
|
ModEnergyStorage getEnergy();
|
||||||
|
|
||||||
|
void sendUpdate();
|
||||||
|
|
||||||
|
BlockState getBlockState();
|
||||||
|
|
||||||
|
IEnergyStorage getTrueEnergyStorage();
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ import net.minecraft.world.level.block.Block;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.phys.AABB;
|
||||||
import net.xevianlight.aphelion.Aphelion;
|
import net.xevianlight.aphelion.Aphelion;
|
||||||
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
import net.xevianlight.aphelion.block.custom.base.TickableBlockEntity;
|
||||||
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
import net.xevianlight.aphelion.core.init.ModBlockEntities;
|
||||||
@@ -35,6 +36,7 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
Direction facing;
|
Direction facing;
|
||||||
BlockPos padScanStart = BlockPos.ZERO;
|
BlockPos padScanStart = BlockPos.ZERO;
|
||||||
private PadInfo padBounds;
|
private PadInfo padBounds;
|
||||||
|
RocketEntity lastRocket;
|
||||||
|
|
||||||
public @Nullable PadInfo getPadBounds() {
|
public @Nullable PadInfo getPadBounds() {
|
||||||
return padBounds;
|
return padBounds;
|
||||||
@@ -279,11 +281,14 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
if (level == null) return null;
|
if (level == null) return null;
|
||||||
RocketStructure structure = scan();
|
RocketStructure structure = scan();
|
||||||
RocketEntity rocket = null;
|
RocketEntity rocket = null;
|
||||||
|
if (lastRocket != null)
|
||||||
|
lastRocket.disassemble();
|
||||||
if (structure != null && seatPos != null) {
|
if (structure != null && seatPos != null) {
|
||||||
RocketStructure.clearCaptured(level, seatPos, structure);
|
RocketStructure.clearCaptured(level, seatPos, structure);
|
||||||
rocket = RocketEntity.spawnRocket(level, seatPos, structure);
|
rocket = RocketEntity.spawnRocket(level, seatPos, structure);
|
||||||
Aphelion.LOGGER.info("Spawn rocket result: {}", rocket);
|
Aphelion.LOGGER.info("Spawn rocket result: {}", rocket);
|
||||||
}
|
}
|
||||||
|
lastRocket = rocket;
|
||||||
return rocket;
|
return rocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -394,4 +399,6 @@ public class RocketAssemblerBlockEntity extends BlockEntity implements TickableB
|
|||||||
this.loadAdditional(tag, registries);
|
this.loadAdditional(tag, registries);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public class VacuumArcFurnaceControllerEntity extends BlockEntity implements MenuProvider, IMultiblockController, TickableBlockEntity {
|
public class VacuumArcFurnaceControllerEntity extends BlockEntity implements MenuProvider, IMultiblockController, TickableBlockEntity, IArcFurnaceLike {
|
||||||
|
|
||||||
private final int SIZE = 4;
|
private final int SIZE = 4;
|
||||||
private final int ENERGY_CAPACITY = 64000;
|
private final int ENERGY_CAPACITY = 64000;
|
||||||
@@ -357,7 +357,8 @@ public class VacuumArcFurnaceControllerEntity extends BlockEntity implements Men
|
|||||||
return isFormed() ? ENERGY_STORAGE : null;
|
return isFormed() ? ENERGY_STORAGE : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnergyStorage getTrueEnergyStorage(@Nullable Direction direction) {
|
@Override
|
||||||
|
public IEnergyStorage getTrueEnergyStorage() {
|
||||||
return this.ENERGY_STORAGE;
|
return this.ENERGY_STORAGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,24 @@ public class RocketAssemblerBlockEntityRenderer implements BlockEntityRenderer<R
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AABB getRenderBoundingBox(RocketAssemblerBlockEntity blockEntity) {
|
||||||
|
// If we don't know bounds yet, fall back to default BE culling.
|
||||||
|
RocketAssemblerBlockEntity.PadInfo pad = blockEntity.getPadBounds();
|
||||||
|
if (pad == null) {
|
||||||
|
return BlockEntityRenderer.super.getRenderBoundingBox(blockEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockPos min = pad.min();
|
||||||
|
BlockPos max = pad.max();
|
||||||
|
|
||||||
|
// Expand slightly to avoid edge precision culling
|
||||||
|
return new AABB(
|
||||||
|
min.getX(), min.getY(), min.getZ(),
|
||||||
|
max.getX() + 1, max.getY() + 1, max.getZ() + 1
|
||||||
|
).inflate(0.5);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void render(@NotNull RocketAssemblerBlockEntity be, float v, @NotNull PoseStack poseStack, @NotNull MultiBufferSource multiBufferSource, int i, int i1) {
|
public void render(@NotNull RocketAssemblerBlockEntity be, float v, @NotNull PoseStack poseStack, @NotNull MultiBufferSource multiBufferSource, int i, int i1) {
|
||||||
// if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) return;
|
// if (!Minecraft.getInstance().gui.getDebugOverlay().showDebugScreen()) return;
|
||||||
|
|||||||
@@ -474,6 +474,22 @@ public class AphelionCommand {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
.then(Commands.literal("disassemble")
|
||||||
|
.executes(context -> {
|
||||||
|
Entity entity = EntityArgument.getEntity(context, "entity");
|
||||||
|
|
||||||
|
if (entity instanceof RocketEntity rocket) {
|
||||||
|
if (rocket.disassemble()) {
|
||||||
|
context.getSource().sendSuccess(() -> Component.translatable("command.aphelion.rocket.disassemble.success"), true);
|
||||||
|
} else {
|
||||||
|
context.getSource().sendFailure(Component.translatable("command.aphelion.rocket.disassemble.failure"));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
context.getSource().sendFailure(Component.translatable("command.aphelion.rocket.entity_invalid"));
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
})
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -506,4 +506,54 @@ public class RocketEntity extends VehicleEntity implements IEntityWithComplexSpa
|
|||||||
return InteractionResult.sidedSuccess(level().isClientSide);
|
return InteractionResult.sidedSuccess(level().isClientSide);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean disassemble() {
|
||||||
|
if (level().isClientSide) return false;
|
||||||
|
if (!(level() instanceof ServerLevel server)) return false;
|
||||||
|
|
||||||
|
// Optional: only allow when not in flight
|
||||||
|
if (getPhase() == FlightPhase.ASCEND || getPhase() == FlightPhase.TRANSIT || getPhase() == FlightPhase.DESCEND) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Kick riders off first (so we don't place blocks inside them)
|
||||||
|
ejectPassengers();
|
||||||
|
|
||||||
|
// Anchor: blocks were captured relative to the scan origin.
|
||||||
|
// Your rocket is spawned at seatPos + (0.5, 0, 0.5), so we convert back to the block origin.
|
||||||
|
BlockPos origin = BlockPos.containing(getX(), getY(), getZ());
|
||||||
|
|
||||||
|
// Place blocks
|
||||||
|
for (int i = 0; i < structure.size(); i++) {
|
||||||
|
int packed = structure.packedPosAt(i);
|
||||||
|
|
||||||
|
int dx = RocketStructure.unpackX(packed);
|
||||||
|
int dy = RocketStructure.unpackY(packed);
|
||||||
|
int dz = RocketStructure.unpackZ(packed);
|
||||||
|
|
||||||
|
BlockPos wp = origin.offset(dx, dy, dz);
|
||||||
|
var stateToPlace = structure.stateAt(i);
|
||||||
|
|
||||||
|
// Don't place air (shouldn't exist in structure anyway, but safe)
|
||||||
|
if (stateToPlace.isAir()) continue;
|
||||||
|
|
||||||
|
// Safety: don't overwrite existing blocks
|
||||||
|
if (!server.getBlockState(wp).isAir()) {
|
||||||
|
// If you want strict behavior, abort entirely:
|
||||||
|
// return false;
|
||||||
|
|
||||||
|
// Otherwise just skip conflicts:
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extra safety: avoid accidentally placing into portal/void/etc if desired
|
||||||
|
// if (!server.isInWorldBounds(wp)) continue;
|
||||||
|
|
||||||
|
server.setBlock(wp, stateToPlace, 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the rocket entity
|
||||||
|
discard(); // preferred over kill() for "just remove this entity"
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,13 +12,14 @@ import net.minecraft.world.level.Level;
|
|||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.neoforged.neoforge.items.SlotItemHandler;
|
import net.neoforged.neoforge.items.SlotItemHandler;
|
||||||
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
import net.xevianlight.aphelion.block.entity.custom.ElectricArcFurnaceEntity;
|
||||||
|
import net.xevianlight.aphelion.block.entity.custom.IArcFurnaceLike;
|
||||||
import net.xevianlight.aphelion.util.EnergyItemSlot;
|
import net.xevianlight.aphelion.util.EnergyItemSlot;
|
||||||
import net.xevianlight.aphelion.util.ExtractOnlySlot;
|
import net.xevianlight.aphelion.util.ExtractOnlySlot;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
||||||
|
|
||||||
public final ElectricArcFurnaceEntity blockEntity;
|
public final IArcFurnaceLike blockEntity;
|
||||||
private final Level level;
|
private final Level level;
|
||||||
private final ContainerData data;
|
private final ContainerData data;
|
||||||
|
|
||||||
@@ -28,17 +29,17 @@ public class ElectricArcFurnaceMenu extends AbstractContainerMenu {
|
|||||||
|
|
||||||
public ElectricArcFurnaceMenu(int i, Inventory inventory, BlockEntity blockEntity, ContainerData data) {
|
public ElectricArcFurnaceMenu(int i, Inventory inventory, BlockEntity blockEntity, ContainerData data) {
|
||||||
super(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), i);
|
super(ModMenuTypes.ELECTRIC_ARC_FURNACE_MENU.get(), i);
|
||||||
this.blockEntity = ((ElectricArcFurnaceEntity) blockEntity);
|
this.blockEntity = ((IArcFurnaceLike) blockEntity);
|
||||||
this.level = inventory.player.level();
|
this.level = inventory.player.level();
|
||||||
this.data = data;
|
this.data = data;
|
||||||
|
|
||||||
addPlayerInventory(inventory);
|
addPlayerInventory(inventory);
|
||||||
addPlayerHotbar(inventory);
|
addPlayerHotbar(inventory);
|
||||||
|
|
||||||
this.addSlot(new EnergyItemSlot(this.blockEntity.inventory, ElectricArcFurnaceEntity.ENERGY_SLOT, 8, 54));
|
this.addSlot(new EnergyItemSlot(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.ENERGY_SLOT, 8, 54));
|
||||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, ElectricArcFurnaceEntity.INPUT_SLOT, 63, 35));
|
this.addSlot(new SlotItemHandler(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.INPUT_SLOT, 63, 35));
|
||||||
this.addSlot(new SlotItemHandler(this.blockEntity.inventory, ElectricArcFurnaceEntity.SECONDARY_INPUT_SLOT, 40, 35));
|
this.addSlot(new SlotItemHandler(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.SECONDARY_INPUT_SLOT, 40, 35));
|
||||||
this.addSlot(new ExtractOnlySlot(this.blockEntity.inventory, ElectricArcFurnaceEntity.OUTPUT_SLOT, 125, 35));
|
this.addSlot(new ExtractOnlySlot(this.blockEntity.getInventory(), ElectricArcFurnaceEntity.OUTPUT_SLOT, 125, 35));
|
||||||
|
|
||||||
addDataSlots(data);
|
addDataSlots(data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ public class ElectricArcFurnaceScreen extends AbstractContainerScreen<ElectricAr
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
||||||
int stored = menu.blockEntity.getTrueEnergyStorage(null).getEnergyStored();
|
int stored = menu.blockEntity.getTrueEnergyStorage().getEnergyStored();
|
||||||
int max = menu.blockEntity.getTrueEnergyStorage(null).getMaxEnergyStored();
|
int max = menu.blockEntity.getTrueEnergyStorage().getMaxEnergyStored();
|
||||||
|
|
||||||
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
||||||
h = Math.max(0, Math.min(42, h));
|
h = Math.max(0, Math.min(42, h));
|
||||||
@@ -79,7 +79,7 @@ public class ElectricArcFurnaceScreen extends AbstractContainerScreen<ElectricAr
|
|||||||
|
|
||||||
private void assignEnergyInfoArea() {
|
private void assignEnergyInfoArea() {
|
||||||
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
||||||
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(null), 14, 42);
|
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(), 14, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
||||||
|
|||||||
@@ -62,8 +62,8 @@ public class VacuumArcFurnaceScreen extends AbstractContainerScreen<VacuumArcFur
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
private void renderEnergyBar(GuiGraphics guiGraphics, int x, int y) {
|
||||||
int stored = menu.blockEntity.getTrueEnergyStorage(null).getEnergyStored();
|
int stored = menu.blockEntity.getTrueEnergyStorage().getEnergyStored();
|
||||||
int max = menu.blockEntity.getTrueEnergyStorage(null).getMaxEnergyStored();
|
int max = menu.blockEntity.getTrueEnergyStorage().getMaxEnergyStored();
|
||||||
|
|
||||||
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
int h = (max <= 0) ? 0 : (int) Math.round((stored / (double) max) * 42.0);
|
||||||
h = Math.max(0, Math.min(42, h));
|
h = Math.max(0, Math.min(42, h));
|
||||||
@@ -79,7 +79,7 @@ public class VacuumArcFurnaceScreen extends AbstractContainerScreen<VacuumArcFur
|
|||||||
|
|
||||||
private void assignEnergyInfoArea() {
|
private void assignEnergyInfoArea() {
|
||||||
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
energyInfoArea = new EnergyDisplayTooltipArea(((width - imageWidth) / 2) + 9,
|
||||||
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(null), 14, 42);
|
((height - imageHeight) / 2 ) + 9, menu.blockEntity.getTrueEnergyStorage(), 14, 42);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
private void renderEnergyAreaTooltip(GuiGraphics guiGraphics, int pMouseX, int pMouseY, int x, int y) {
|
||||||
|
|||||||
@@ -5,8 +5,11 @@ import it.unimi.dsi.fastutil.ints.IntList;
|
|||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.nbt.*;
|
import net.minecraft.nbt.*;
|
||||||
import net.minecraft.world.level.Level;
|
import net.minecraft.world.level.Level;
|
||||||
|
import net.minecraft.world.level.block.Block;
|
||||||
import net.minecraft.world.level.block.Blocks;
|
import net.minecraft.world.level.block.Blocks;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
import net.minecraft.world.level.block.state.properties.BlockStateProperties;
|
||||||
|
import net.minecraft.world.level.block.state.properties.DoubleBlockHalf;
|
||||||
import net.minecraft.world.phys.AABB;
|
import net.minecraft.world.phys.AABB;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -170,15 +173,54 @@ public final class RocketStructure {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void clearCaptured(Level level, BlockPos origin, RocketStructure struct) {
|
public static void clearCaptured(Level level, BlockPos origin, RocketStructure struct) {
|
||||||
|
final int flags = Block.UPDATE_CLIENTS;
|
||||||
|
|
||||||
|
// Pass 1: remove blocks which implement DOUBLE_BLOCK_HALF like doors to try and prevent duplication.
|
||||||
for (int i = 0; i < struct.size(); i++) {
|
for (int i = 0; i < struct.size(); i++) {
|
||||||
int packed = struct.packedPosAt(i);
|
int packed = struct.packedPosAt(i);
|
||||||
int dx = RocketStructure.unpackX(packed);
|
BlockPos wp = origin.offset(
|
||||||
int dy = RocketStructure.unpackY(packed);
|
RocketStructure.unpackX(packed),
|
||||||
int dz = RocketStructure.unpackZ(packed);
|
RocketStructure.unpackY(packed),
|
||||||
|
RocketStructure.unpackZ(packed)
|
||||||
|
);
|
||||||
|
|
||||||
BlockPos wp = origin.offset(dx, dy, dz);
|
BlockState st = level.getBlockState(wp);
|
||||||
if (level.getBlockState(wp).is(struct.stateAt(i).getBlock()))
|
if (st.isAir()) continue;
|
||||||
level.setBlock(wp, Blocks.AIR.defaultBlockState(), 3);
|
|
||||||
|
if (st.hasProperty(BlockStateProperties.DOUBLE_BLOCK_HALF)) {
|
||||||
|
DoubleBlockHalf half = st.getValue(BlockStateProperties.DOUBLE_BLOCK_HALF);
|
||||||
|
BlockPos bottom = (half == DoubleBlockHalf.LOWER) ? wp : null;
|
||||||
|
|
||||||
|
// Break the BOTTOM block to stop potential dupes, as it seems that is the "master" block for doors.
|
||||||
|
// If you set the top block to air, the bottom one breaks a moment later and drops.
|
||||||
|
// If this doesn't work I declare it NOT MY FAULT!
|
||||||
|
// DoubleBlockHalf blocks should have a way to delete the entire thing at once god damnit
|
||||||
|
if (bottom != null && !level.getBlockState(bottom).isAir()) {
|
||||||
|
level.setBlock(bottom, Blocks.AIR.defaultBlockState(), flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass 2: remove likely-attached blocks first. This should stop duplication of torches/buttons/whatever else may break due to its supporting block being broken
|
||||||
|
for (int i = 0; i < struct.size(); i++) {
|
||||||
|
int packed = struct.packedPosAt(i);
|
||||||
|
BlockPos wp = origin.offset(unpackX(packed), unpackY(packed), unpackZ(packed));
|
||||||
|
BlockState st = level.getBlockState(wp);
|
||||||
|
if (st.isAir()) continue;
|
||||||
|
|
||||||
|
// Heuristic: if it isn't a full collision cube, it's often "attached" (buttons, torches, etc.)
|
||||||
|
if (!st.isCollisionShapeFullBlock(level, wp)) {
|
||||||
|
level.setBlock(wp, Blocks.AIR.defaultBlockState(), flags);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pass 3: remove the rest
|
||||||
|
for (int i = 0; i < struct.size(); i++) {
|
||||||
|
int packed = struct.packedPosAt(i);
|
||||||
|
BlockPos wp = origin.offset(unpackX(packed), unpackY(packed), unpackZ(packed));
|
||||||
|
if (!level.getBlockState(wp).isAir()) {
|
||||||
|
level.setBlock(wp, Blocks.AIR.defaultBlockState(), flags);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -52,5 +52,7 @@
|
|||||||
"command.aphelion.rocket.get_dim.success": "Target dimension of rocket is %s",
|
"command.aphelion.rocket.get_dim.success": "Target dimension of rocket is %s",
|
||||||
"command.aphelion.rocket.set_pos.success": "Set target position of rocket to %s",
|
"command.aphelion.rocket.set_pos.success": "Set target position of rocket to %s",
|
||||||
"command.aphelion.rocket.get_pos.success": "Target position of rocket is %s",
|
"command.aphelion.rocket.get_pos.success": "Target position of rocket is %s",
|
||||||
"command.aphelion.rocket.get_pos.success.null": "Target position of rocket is not set"
|
"command.aphelion.rocket.get_pos.success.null": "Target position of rocket is not set",
|
||||||
|
"command.aphelion.rocket.disassemble.success": "Rocket disassembled",
|
||||||
|
"command.aphelion.rocket.disassemble.failure": "Could not disassemble rocket"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user