实现充电站范围显示

This commit is contained in:
Light_Quanta 2025-01-09 19:49:41 +08:00
parent a4fb286a17
commit f30c0e385c
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
10 changed files with 217 additions and 1 deletions

View file

@ -164,6 +164,7 @@ public class ModUtils {
addNetworkMessage(RadarSetPosMessage.class, RadarSetPosMessage::encode, RadarSetPosMessage::decode, RadarSetPosMessage::handler); addNetworkMessage(RadarSetPosMessage.class, RadarSetPosMessage::encode, RadarSetPosMessage::decode, RadarSetPosMessage::handler);
addNetworkMessage(PlayerStopRidingMessage.class, PlayerStopRidingMessage::encode, PlayerStopRidingMessage::decode, PlayerStopRidingMessage::handler); addNetworkMessage(PlayerStopRidingMessage.class, PlayerStopRidingMessage::encode, PlayerStopRidingMessage::decode, PlayerStopRidingMessage::handler);
addNetworkMessage(AimVillagerMessage.class, AimVillagerMessage::encode, AimVillagerMessage::decode, AimVillagerMessage::handler); addNetworkMessage(AimVillagerMessage.class, AimVillagerMessage::encode, AimVillagerMessage::decode, AimVillagerMessage::handler);
addNetworkMessage(ShowChargingRangeMessage.class, ShowChargingRangeMessage::encode, ShowChargingRangeMessage::decode, ShowChargingRangeMessage::handler);
event.enqueueWork(() -> BrewingRecipeRegistry.addRecipe(Ingredient.of(PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)), event.enqueueWork(() -> BrewingRecipeRegistry.addRecipe(Ingredient.of(PotionUtils.setPotion(new ItemStack(Items.POTION), Potions.WATER)),
Ingredient.of(Items.LIGHTNING_ROD), PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotion.SHOCK.get()))); Ingredient.of(Items.LIGHTNING_ROD), PotionUtils.setPotion(new ItemStack(Items.POTION), ModPotion.SHOCK.get())));

View file

@ -45,7 +45,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
protected static final int SLOT_CHARGE = 1; protected static final int SLOT_CHARGE = 1;
public static final int MAX_ENERGY = 4000000; public static final int MAX_ENERGY = 4000000;
public static final int MAX_DATA_COUNT = 3; public static final int MAX_DATA_COUNT = 4;
public static final int DEFAULT_FUEL_TIME = 1600; public static final int DEFAULT_FUEL_TIME = 1600;
public static final int CHARGE_SPEED = 128; public static final int CHARGE_SPEED = 128;
public static final int CHARGE_OTHER_SPEED = 100000; public static final int CHARGE_OTHER_SPEED = 100000;
@ -59,6 +59,8 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
public int fuelTick = 0; public int fuelTick = 0;
public int maxFuelTick = DEFAULT_FUEL_TIME; public int maxFuelTick = DEFAULT_FUEL_TIME;
public boolean showRange = false;
protected final ContainerEnergyData dataAccess = new ContainerEnergyData() { protected final ContainerEnergyData dataAccess = new ContainerEnergyData() {
public long get(int pIndex) { public long get(int pIndex) {
return switch (pIndex) { return switch (pIndex) {
@ -69,6 +71,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
ChargingStationBlockEntity.this.getCapability(ForgeCapabilities.ENERGY).ifPresent(consumer -> energy.set(consumer.getEnergyStored())); ChargingStationBlockEntity.this.getCapability(ForgeCapabilities.ENERGY).ifPresent(consumer -> energy.set(consumer.getEnergyStored()));
yield energy.get(); yield energy.get();
} }
case 3 -> ChargingStationBlockEntity.this.showRange ? 1 : 0;
default -> 0; default -> 0;
}; };
} }
@ -84,6 +87,9 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
case 2: case 2:
ChargingStationBlockEntity.this.getCapability(ForgeCapabilities.ENERGY).ifPresent(consumer -> consumer.receiveEnergy((int) pValue, false)); ChargingStationBlockEntity.this.getCapability(ForgeCapabilities.ENERGY).ifPresent(consumer -> consumer.receiveEnergy((int) pValue, false));
break; break;
case 3:
ChargingStationBlockEntity.this.showRange = pValue == 1;
break;
} }
} }
@ -217,6 +223,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
} }
this.fuelTick = pTag.getInt("FuelTick"); this.fuelTick = pTag.getInt("FuelTick");
this.maxFuelTick = pTag.getInt("MaxFuelTick"); this.maxFuelTick = pTag.getInt("MaxFuelTick");
this.showRange = pTag.getBoolean("ShowRange");
this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY); this.items = NonNullList.withSize(this.getContainerSize(), ItemStack.EMPTY);
ContainerHelper.loadAllItems(pTag, this.items); ContainerHelper.loadAllItems(pTag, this.items);
} }
@ -228,6 +235,7 @@ public class ChargingStationBlockEntity extends BlockEntity implements WorldlyCo
getCapability(ForgeCapabilities.ENERGY).ifPresent(handler -> pTag.put("Energy", ((EnergyStorage) handler).serializeNBT())); getCapability(ForgeCapabilities.ENERGY).ifPresent(handler -> pTag.put("Energy", ((EnergyStorage) handler).serializeNBT()));
pTag.putInt("FuelTick", this.fuelTick); pTag.putInt("FuelTick", this.fuelTick);
pTag.putInt("MaxFuelTick", this.maxFuelTick); pTag.putInt("MaxFuelTick", this.maxFuelTick);
pTag.putBoolean("ShowRange", this.showRange);
ContainerHelper.saveAllItems(pTag, this.items); ContainerHelper.saveAllItems(pTag, this.items);
} }

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.client; package com.atsuishio.superbwarfare.client;
import com.atsuishio.superbwarfare.client.renderer.block.ChargingStationBlockEntityRenderer;
import com.atsuishio.superbwarfare.client.renderer.block.ContainerBlockEntityRenderer; import com.atsuishio.superbwarfare.client.renderer.block.ContainerBlockEntityRenderer;
import com.atsuishio.superbwarfare.client.renderer.block.FuMO25BlockEntityRenderer; import com.atsuishio.superbwarfare.client.renderer.block.FuMO25BlockEntityRenderer;
import com.atsuishio.superbwarfare.client.tooltip.*; import com.atsuishio.superbwarfare.client.tooltip.*;
@ -29,6 +30,7 @@ public class ClientRenderHandler {
public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) { public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
event.registerBlockEntityRenderer(ModBlockEntities.CONTAINER.get(), context -> new ContainerBlockEntityRenderer()); event.registerBlockEntityRenderer(ModBlockEntities.CONTAINER.get(), context -> new ContainerBlockEntityRenderer());
event.registerBlockEntityRenderer(ModBlockEntities.FUMO_25.get(), FuMO25BlockEntityRenderer::new); event.registerBlockEntityRenderer(ModBlockEntities.FUMO_25.get(), FuMO25BlockEntityRenderer::new);
event.registerBlockEntityRenderer(ModBlockEntities.CHARGING_STATION.get(), context -> new ChargingStationBlockEntityRenderer());
} }
} }

View file

@ -0,0 +1,25 @@
package com.atsuishio.superbwarfare.client.renderer;
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
import com.mojang.blaze3d.vertex.VertexFormat;
import net.minecraft.client.renderer.RenderType;
public class CustomRenderType extends RenderType {
public CustomRenderType(String pName, VertexFormat pFormat, VertexFormat.Mode pMode, int pBufferSize, boolean pAffectsCrumbling, boolean pSortOnUpload, Runnable pSetupState, Runnable pClearState) {
super(pName, pFormat, pMode, pBufferSize, pAffectsCrumbling, pSortOnUpload, pSetupState, pClearState);
}
public static final RenderType BLOCK_OVERLAY = create("block_overlay",
DefaultVertexFormat.POSITION_COLOR, VertexFormat.Mode.QUADS, 256, false, false,
RenderType.CompositeState.builder()
.setShaderState(ShaderStateShard.POSITION_COLOR_SHADER)
.setLayeringState(NO_LAYERING)
.setTransparencyState(TRANSLUCENT_TRANSPARENCY)
.setTextureState(NO_TEXTURE)
.setDepthTestState(LEQUAL_DEPTH_TEST)
.setCullState(NO_CULL)
.setLightmapState(NO_LIGHTMAP)
.setWriteMaskState(COLOR_WRITE)
.createCompositeState(false));
}

View file

@ -0,0 +1,93 @@
package com.atsuishio.superbwarfare.client.renderer.block;
import com.atsuishio.superbwarfare.block.entity.ChargingStationBlockEntity;
import com.atsuishio.superbwarfare.client.renderer.CustomRenderType;
import com.mojang.blaze3d.vertex.PoseStack;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.CLIENT)
public class ChargingStationBlockEntityRenderer implements BlockEntityRenderer<ChargingStationBlockEntity> {
@Override
public void render(ChargingStationBlockEntity pBlockEntity, float pPartialTick, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight, int pPackedOverlay) {
// TODO 正确判断是否开启范围展示
if (!pBlockEntity.showRange) return;
pPoseStack.pushPose();
var pos = pBlockEntity.getBlockPos();
pPoseStack.translate(-pos.getX(), -pos.getY(), -pos.getZ());
var aabb = new AABB(pos).inflate(ChargingStationBlockEntity.CHARGE_RADIUS);
float startX = (float) aabb.minX - 0.001f;
float startY = (float) aabb.minY - 0.001f;
float startZ = (float) aabb.minZ - 0.001f;
float endX = (float) aabb.maxX + 0.001f;
float endY = (float) aabb.maxY + 0.001f;
float endZ = (float) aabb.maxZ + 0.001f;
var red = 0.0f;
var green = 1.0f;
var blue = 0.0f;
var alpha = 0.2f;
var builder = pBuffer.getBuffer(CustomRenderType.BLOCK_OVERLAY);
var m4f = pPoseStack.last().pose();
// east
builder.vertex(m4f, startX, startY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, endY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, endY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, startY, startZ).color(red, green, blue, alpha).endVertex();
// west
builder.vertex(m4f, startX, startY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, startY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, endY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, endY, endZ).color(red, green, blue, alpha).endVertex();
// south
builder.vertex(m4f, endX, startY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, endY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, endY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, startY, endZ).color(red, green, blue, alpha).endVertex();
// north
builder.vertex(m4f, startX, startY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, startY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, endY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, endY, startZ).color(red, green, blue, alpha).endVertex();
// top
builder.vertex(m4f, startX, endY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, endY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, endY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, endY, endZ).color(red, green, blue, alpha).endVertex();
// bottom
builder.vertex(m4f, startX, startY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, startY, startZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, endX, startY, endZ).color(red, green, blue, alpha).endVertex();
builder.vertex(m4f, startX, startY, endZ).color(red, green, blue, alpha).endVertex();
pPoseStack.popPose();
}
@Override
public boolean shouldRenderOffScreen(ChargingStationBlockEntity pBlockEntity) {
return true;
}
@Override
public boolean shouldRender(ChargingStationBlockEntity pBlockEntity, Vec3 pCameraPos) {
return true;
}
}

View file

@ -3,7 +3,10 @@ package com.atsuishio.superbwarfare.client.screens;
import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.block.entity.ChargingStationBlockEntity; import com.atsuishio.superbwarfare.block.entity.ChargingStationBlockEntity;
import com.atsuishio.superbwarfare.menu.ChargingStationMenu; import com.atsuishio.superbwarfare.menu.ChargingStationMenu;
import com.atsuishio.superbwarfare.network.message.ShowChargingRangeMessage;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractButton;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen; import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.network.chat.Component; import net.minecraft.network.chat.Component;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
@ -73,6 +76,35 @@ public class ChargingStationScreen extends AbstractContainerScreen<ChargingStati
} }
} }
@OnlyIn(Dist.CLIENT)
class ShowRangeButton extends AbstractButton {
@Override
protected void renderWidget(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
this.setMessage(ChargingStationScreen.this.menu.showRange() ? Component.translatable("container.superbwarfare.charging_station.hide_range") : Component.translatable("container.superbwarfare.charging_station.show_range"));
super.renderWidget(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
}
public ShowRangeButton(int pX, int pY) {
super(pX + 7, pY + 55, 33, 14, Component.translatable("container.superbwarfare.charging_station.show_range"));
}
@Override
public void render(GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
}
@Override
public void onPress() {
ModUtils.PACKET_HANDLER.sendToServer(new ShowChargingRangeMessage(!ChargingStationScreen.this.menu.showRange()));
}
@Override
protected void updateWidgetNarration(NarrationElementOutput pNarrationElementOutput) {
}
}
@Override @Override
protected void init() { protected void init() {
super.init(); super.init();
@ -80,6 +112,10 @@ public class ChargingStationScreen extends AbstractContainerScreen<ChargingStati
this.titleLabelY = 5; this.titleLabelY = 5;
this.inventoryLabelX = 8; this.inventoryLabelX = 8;
this.inventoryLabelY = 74; this.inventoryLabelY = 74;
int i = (this.width - this.imageWidth) / 2;
int j = (this.height - this.imageHeight) / 2;
this.addRenderableWidget(new ShowRangeButton(i, j));
} }
} }

View file

@ -115,6 +115,14 @@ public class ChargingStationMenu extends EnergyMenu {
return this.containerData.get(2); return this.containerData.get(2);
} }
public boolean showRange() {
return this.containerData.get(3) == 1;
}
public void setShowRange(boolean showRange) {
this.containerData.set(3, showRange ? 1 : 0);
}
static class ChargingSlot extends Slot { static class ChargingSlot extends Slot {
public ChargingSlot(Container pContainer, int pSlot, int pX, int pY) { public ChargingSlot(Container pContainer, int pSlot, int pX, int pY) {

View file

@ -0,0 +1,39 @@
package com.atsuishio.superbwarfare.network.message;
import com.atsuishio.superbwarfare.menu.ChargingStationMenu;
import net.minecraft.network.FriendlyByteBuf;
import net.minecraftforge.network.NetworkEvent;
import java.util.function.Supplier;
public class ShowChargingRangeMessage {
private final boolean operation;
public ShowChargingRangeMessage(boolean operation) {
this.operation = operation;
}
public static ShowChargingRangeMessage decode(FriendlyByteBuf buffer) {
return new ShowChargingRangeMessage(buffer.readBoolean());
}
public static void encode(ShowChargingRangeMessage message, FriendlyByteBuf buffer) {
buffer.writeBoolean(message.operation);
}
public static void handler(ShowChargingRangeMessage message, Supplier<NetworkEvent.Context> contextSupplier) {
NetworkEvent.Context context = contextSupplier.get();
context.enqueueWork(() -> {
if (context.getSender() == null) return;
var player = context.getSender();
var menu = player.containerMenu;
if (menu instanceof ChargingStationMenu chargingStationMenu) {
if (!chargingStationMenu.stillValid(player)) return;
chargingStationMenu.setShowRange(message.operation);
}
});
context.setPacketHandled(true);
}
}

View file

@ -216,6 +216,8 @@
"block.superbwarfare.silver_block": "Silver Block", "block.superbwarfare.silver_block": "Silver Block",
"block.superbwarfare.cemented_carbide_block": "Cemented Carbide Block", "block.superbwarfare.cemented_carbide_block": "Cemented Carbide Block",
"block.superbwarfare.charging_station": "Charging Station", "block.superbwarfare.charging_station": "Charging Station",
"container.superbwarfare.charging_station.show_range": "Show Range",
"container.superbwarfare.charging_station.hide_range": "Hide Range",
"des.superbwarfare.charging_station.energy": "Energy: %1$s / %2$s FE", "des.superbwarfare.charging_station.energy": "Energy: %1$s / %2$s FE",
"block.superbwarfare.fumo_25": "FuMO25 Fire Control Radar", "block.superbwarfare.fumo_25": "FuMO25 Fire Control Radar",
"des.superbwarfare.fumo_25.current_pos": "Current Pos: %1$s", "des.superbwarfare.fumo_25.current_pos": "Current Pos: %1$s",

View file

@ -443,6 +443,8 @@
"container.superbwarfare.reforging_table": "枪械重铸台", "container.superbwarfare.reforging_table": "枪械重铸台",
"container.superbwarfare.charging_station": "充电站", "container.superbwarfare.charging_station": "充电站",
"container.superbwarfare.charging_station.show_range": "显示范围",
"container.superbwarfare.charging_station.hide_range": "隐藏范围",
"config.superbwarfare.title": "卓越前线", "config.superbwarfare.title": "卓越前线",
"config.superbwarfare.client.reload": "换弹配置", "config.superbwarfare.client.reload": "换弹配置",