同步更新狗牌

This commit is contained in:
Light_Quanta 2025-05-23 15:41:28 +08:00
parent 1e0baa2a2d
commit 0e77509e0c
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
20 changed files with 736 additions and 15 deletions

View file

@ -25,6 +25,7 @@ public class ClientRenderHandler {
event.register(LauncherImageComponent.class, ClientLauncherImageTooltip::new); event.register(LauncherImageComponent.class, ClientLauncherImageTooltip::new);
event.register(SecondaryCataclysmImageComponent.class, ClientSecondaryCataclysmImageTooltip::new); event.register(SecondaryCataclysmImageComponent.class, ClientSecondaryCataclysmImageTooltip::new);
event.register(ChargingStationImageComponent.class, ClientChargingStationImageTooltip::new); event.register(ChargingStationImageComponent.class, ClientChargingStationImageTooltip::new);
event.register(DogTagImageComponent.class, ClientDogTagImageTooltip::new);
} }
@SubscribeEvent @SubscribeEvent

View file

@ -1,27 +1,35 @@
package com.atsuishio.superbwarfare.client.overlay; package com.atsuishio.superbwarfare.client.overlay;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.RenderHelper;
import com.atsuishio.superbwarfare.client.screens.DogTagEditorScreen;
import com.atsuishio.superbwarfare.client.tooltip.ClientDogTagImageTooltip;
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
import com.atsuishio.superbwarfare.config.client.KillMessageConfig; import com.atsuishio.superbwarfare.config.client.KillMessageConfig;
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
import com.atsuishio.superbwarfare.event.KillMessageHandler; import com.atsuishio.superbwarfare.event.KillMessageHandler;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.item.DogTag;
import com.atsuishio.superbwarfare.item.gun.GunItem; import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.tools.DamageTypeTool; import com.atsuishio.superbwarfare.tools.DamageTypeTool;
import com.atsuishio.superbwarfare.tools.PlayerKillRecord; import com.atsuishio.superbwarfare.tools.PlayerKillRecord;
import com.mojang.blaze3d.platform.GlStateManager; import com.mojang.blaze3d.platform.GlStateManager;
import com.mojang.blaze3d.systems.RenderSystem; import com.mojang.blaze3d.systems.RenderSystem;
import net.minecraft.ChatFormatting;
import net.minecraft.client.DeltaTracker; import net.minecraft.client.DeltaTracker;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.Font; import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics; import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.LayeredDraw; import net.minecraft.client.gui.LayeredDraw;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.core.registries.Registries; import net.minecraft.core.registries.Registries;
import net.minecraft.resources.ResourceKey; import net.minecraft.resources.ResourceKey;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn; import net.neoforged.api.distmarker.OnlyIn;
@ -176,6 +184,12 @@ public class KillMessageOverlay implements LayeredDraw.Layer {
false false
); );
// 渲染狗牌图标
if (record.target instanceof LivingEntity living && shouldRenderDogTagIcon(living)) {
currentPosX -= 14;
renderDogTagIcon(guiGraphics, living, currentPosX, top - 0.5f);
}
// 渲染伤害类型图标 // 渲染伤害类型图标
ResourceLocation damageTypeIcon = getDamageTypeIcon(record); ResourceLocation damageTypeIcon = getDamageTypeIcon(record);
if (damageTypeIcon != null) { if (damageTypeIcon != null) {
@ -222,9 +236,21 @@ public class KillMessageOverlay implements LayeredDraw.Layer {
record.attacker.getTeamColor(), record.attacker.getTeamColor(),
false false
); );
// 渲染狗牌图标
if (shouldRenderDogTagIcon(record.attacker)) {
currentPosX -= 14;
renderDogTagIcon(guiGraphics, record.attacker, currentPosX, top - 0.5f);
}
} else { } else {
float currentPosX = width + 10f; float currentPosX = width + 10f;
// 渲染狗牌图标
if (shouldRenderDogTagIcon(record.attacker)) {
renderDogTagIcon(guiGraphics, record.attacker, currentPosX, top - 0.5f);
currentPosX += 14;
}
// 渲染击杀者名称 // 渲染击杀者名称
String attackerName = getEntityName(record.attacker); String attackerName = getEntityName(record.attacker);
guiGraphics.drawString( guiGraphics.drawString(
@ -272,6 +298,12 @@ public class KillMessageOverlay implements LayeredDraw.Layer {
currentPosX += 18; currentPosX += 18;
} }
// 渲染狗牌图标
if (record.target instanceof LivingEntity living && shouldRenderDogTagIcon(living)) {
renderDogTagIcon(guiGraphics, living, currentPosX, top - 0.5f);
currentPosX += 14;
}
// 渲染被击杀者名称 // 渲染被击杀者名称
guiGraphics.drawString( guiGraphics.drawString(
Minecraft.getInstance().font, Minecraft.getInstance().font,
@ -370,4 +402,33 @@ public class KillMessageOverlay implements LayeredDraw.Layer {
} }
return null; return null;
} }
public static boolean shouldRenderDogTagIcon(LivingEntity living) {
return CuriosApi.getCuriosInventory(living)
.flatMap(c -> c.findFirstCurio(ModItems.DOG_TAG.get()))
.map(s -> ClientDogTagImageTooltip.shouldRenderIcon(s.stack()))
.orElse(false)
&& DisplayConfig.DOG_TAG_ICON_VISIBLE.get();
}
public static void renderDogTagIcon(GuiGraphics guiGraphics, LivingEntity living, float x, float y) {
CuriosApi.getCuriosInventory(living).flatMap(c -> c.findFirstCurio(ModItems.DOG_TAG.get())).ifPresent(s -> {
short[][] icon = DogTag.getColors(s.stack());
guiGraphics.pose().pushPose();
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
if (icon[i][j] == -1) continue;
var color = ChatFormatting.getById(icon[i][j]);
RenderHelper.fill(guiGraphics, RenderType.gui(),
x + i * 0.6f, y + j * 0.6f, x + (i + 1) * 0.6f, y + (j + 1) * 0.6f,
0, DogTagEditorScreen.getColorFromFormatting(color)
);
}
}
guiGraphics.pose().popPose();
});
}
} }

View file

@ -0,0 +1,280 @@
package com.atsuishio.superbwarfare.client.screens;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.item.DogTag;
import com.atsuishio.superbwarfare.menu.DogTagEditorMenu;
import com.atsuishio.superbwarfare.network.message.send.DogTagFinishEditMessage;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.components.AbstractButton;
import net.minecraft.client.gui.components.EditBox;
import net.minecraft.client.gui.narration.NarrationElementOutput;
import net.minecraft.client.gui.screens.Screen;
import net.minecraft.client.gui.screens.inventory.AbstractContainerScreen;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.game.ServerboundRenameItemPacket;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.entity.player.Inventory;
import net.minecraft.world.item.ItemStack;
import net.neoforged.api.distmarker.Dist;
import net.neoforged.api.distmarker.OnlyIn;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
@OnlyIn(Dist.CLIENT)
public class DogTagEditorScreen extends AbstractContainerScreen<DogTagEditorMenu> {
private static final ResourceLocation TEXTURE = Mod.loc("textures/gui/dog_tag_editor.png");
public EditBox name;
private short currentColor = 0;
private short[][] icon = new short[16][16];
public ItemStack stack;
private boolean init = false;
public DogTagEditorScreen(DogTagEditorMenu pMenu, Inventory pPlayerInventory, Component pTitle) {
super(pMenu, pPlayerInventory, pTitle);
this.stack = pMenu.stack;
imageWidth = 207;
imageHeight = 185;
}
@Override
protected void renderBg(GuiGraphics pGuiGraphics, float pPartialTick, int pMouseX, int pMouseY) {
int i = (this.width - this.imageWidth) / 2;
int j = (this.height - this.imageHeight) / 2;
pGuiGraphics.blit(TEXTURE, i, j, 0, 0, this.imageWidth, this.imageHeight, 256, 256);
ItemStack stack = DogTagEditorScreen.this.menu.stack;
pGuiGraphics.renderItem(stack, i + 18, j + 36);
var pose = pGuiGraphics.pose();
pose.pushPose();
for (int x = 0; x < this.icon.length; x++) {
for (int y = 0; y < this.icon.length; y++) {
int num = this.icon[x][y];
if (num != -1) {
var color = ChatFormatting.getById(num);
pGuiGraphics.fill(i + 66 + x * 9, j + 44 + y * 9, i + 58 + x * 9, j + 36 + y * 9,
getColorFromFormatting(color));
}
}
}
pose.popPose();
}
@Override
public void render(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
this.renderBackground(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
super.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
this.name.render(pGuiGraphics, pMouseX, pMouseY, pPartialTick);
this.renderTooltip(pGuiGraphics, pMouseX, pMouseY);
}
@Override
public boolean mouseClicked(double pMouseX, double pMouseY, int pButton) {
this.drawColor(pMouseX, pMouseY, pButton);
return super.mouseClicked(pMouseX, pMouseY, pButton);
}
@Override
public boolean mouseDragged(double pMouseX, double pMouseY, int pButton, double pDragX, double pDragY) {
this.drawColor(pMouseX, pMouseY, pButton);
return super.mouseDragged(pMouseX, pMouseY, pButton, pDragX, pDragY);
}
private void drawColor(double pMouseX, double pMouseY, int pButton) {
int i = (this.width - this.imageWidth) / 2;
int j = (this.height - this.imageHeight) / 2;
if (pMouseX >= i + 57 && pMouseX <= i + 201 && pMouseY >= j + 36 && pMouseY <= j + 179) {
double posX = pMouseX - i - 57;
double posY = pMouseY - j - 36;
if (Math.ceil(posX) % 9 == 0 || Math.ceil(posY) % 9 == 0)
return;
int x = (int) Math.floor(posX / 9);
int y = (int) Math.floor(posY / 9);
this.icon[Mth.clamp(x, 0, 15)][Mth.clamp(y, 0, 15)] = pButton == 0 ? this.currentColor : -1;
}
}
@Override
public void containerTick() {
super.containerTick();
// this.name.tick();
if (!this.init) {
if (!this.stack.isEmpty()) {
this.name.setValue(this.stack.getHoverName().getString());
this.icon = DogTag.getColors(this.stack);
}
this.init = true;
}
}
@Override
protected void init() {
super.init();
this.subInit();
this.clearColors();
int i = (this.width - this.imageWidth) / 2;
int j = (this.height - this.imageHeight) / 2;
for (short k = 0; k < 16; k++) {
var button = new ColorButton(k, i + 6 + (k % 2) * 22, j + 62 + (k / 2) * 10, 18, 8);
this.addRenderableWidget(button);
}
var eraserButton = new ColorButton((short) -1, i + 17, j + 143, 18, 8);
this.addRenderableWidget(eraserButton);
var finishButton = new FinishButton(i + 6, j + 167, 40, 13);
this.addRenderableWidget(finishButton);
}
protected void subInit() {
int i = (this.width - this.imageWidth) / 2;
int j = (this.height - this.imageHeight) / 2;
this.name = new EditBox(this.font, i + 9, j + 11, 180, 12, Component.literal(""));
this.name.setCanLoseFocus(false);
this.name.setTextColor(-1);
this.name.setTextColorUneditable(-1);
this.name.setBordered(false);
this.name.setMaxLength(30);
this.name.setResponder(this::onNameChanged);
// this.name.setValue(this.stack.getHoverName().getString());
this.addWidget(this.name);
this.setInitialFocus(this.name);
this.name.setEditable(true);
}
private void onNameChanged(String name) {
String s = name;
ItemStack stack = DogTagEditorScreen.this.menu.stack;
if (!stack.has(DataComponents.CUSTOM_NAME)) {
s = "";
}
if (this.menu.setItemName(s)) {
if (this.minecraft != null && this.minecraft.player != null) {
this.minecraft.player.connection.send(new ServerboundRenameItemPacket(s));
}
}
}
// 留空
@Override
protected void renderLabels(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY) {
}
public void clearColors() {
for (var el : this.icon) {
Arrays.fill(el, (short) -1);
}
}
@OnlyIn(Dist.CLIENT)
class ColorButton extends AbstractButton {
short color;
public ColorButton(short color, int pX, int pY, int pWidth, int pHeight) {
super(pX, pY, pWidth, pHeight, Component.literal(""));
this.color = color;
}
@Override
public void onPress() {
DogTagEditorScreen.this.currentColor = this.color;
if (this.color == -1 && Screen.hasShiftDown()) {
DogTagEditorScreen.this.clearColors();
}
}
@Override
protected void updateWidgetNarration(@NotNull NarrationElementOutput pNarrationElementOutput) {
}
@Override
protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
if (this.isHovered || DogTagEditorScreen.this.currentColor == this.color) {
if (this.color == -1) {
pGuiGraphics.blit(TEXTURE, this.getX(), this.getY(), 19, 186,
18, 8, 256, 256);
} else {
pGuiGraphics.blit(TEXTURE, this.getX(), this.getY(), 0, 186,
18, 8, 256, 256);
}
}
}
}
@OnlyIn(Dist.CLIENT)
class FinishButton extends AbstractButton {
public FinishButton(int pX, int pY, int pWidth, int pHeight) {
super(pX, pY, pWidth, pHeight, Component.literal(""));
}
@Override
public void onPress() {
if (!DogTagEditorScreen.this.init) return;
var colors = new ArrayList<Short>(DogTagEditorScreen.this.icon.length * DogTagEditorScreen.this.icon[0].length);
for (var row : DogTagEditorScreen.this.icon) {
for (var color : row) {
colors.add(color);
}
}
PacketDistributor.sendToServer(new DogTagFinishEditMessage(colors, DogTagEditorScreen.this.name.getValue()));
}
@Override
protected void renderWidget(@NotNull GuiGraphics pGuiGraphics, int pMouseX, int pMouseY, float pPartialTick) {
if (this.isHovered) {
pGuiGraphics.blit(TEXTURE, this.getX(), this.getY(), 0, 195,
40, 13, 256, 256);
}
}
@Override
protected void updateWidgetNarration(@NotNull NarrationElementOutput pNarrationElementOutput) {
}
}
public static int getColorFromFormatting(ChatFormatting chatFormatting) {
if (chatFormatting == null) {
return -1;
}
return switch (chatFormatting) {
case BLACK -> 0xFF000000;
case DARK_BLUE -> 0xFF0000AA;
case DARK_GREEN -> 0xFF00AA00;
case DARK_AQUA -> 0xFF00AAAA;
case DARK_RED -> 0xFFAA0000;
case DARK_PURPLE -> 0xFFAA00AA;
case GOLD -> 0xFFFFAA00;
case GRAY -> 0xFFAAAAAA;
case DARK_GRAY -> 0xFF555555;
case BLUE -> 0xFF5555FF;
case GREEN -> 0xFF55FF55;
case AQUA -> 0xFF55FFFF;
case RED -> 0xFFFF5555;
case LIGHT_PURPLE -> 0xFFFF55FF;
case YELLOW -> 0xFFFFFF55;
case WHITE -> 0xFFFFFFFF;
default -> -1;
};
}
}

View file

@ -0,0 +1,80 @@
package com.atsuishio.superbwarfare.client.tooltip;
import com.atsuishio.superbwarfare.client.screens.DogTagEditorScreen;
import com.atsuishio.superbwarfare.client.tooltip.component.DogTagImageComponent;
import com.atsuishio.superbwarfare.item.DogTag;
import net.minecraft.ChatFormatting;
import net.minecraft.client.gui.Font;
import net.minecraft.client.gui.GuiGraphics;
import net.minecraft.client.gui.screens.inventory.tooltip.ClientTooltipComponent;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault;
public class ClientDogTagImageTooltip implements ClientTooltipComponent {
protected final int width;
protected final int height;
protected final ItemStack stack;
public ClientDogTagImageTooltip(DogTagImageComponent tooltip) {
this.width = tooltip.width;
this.height = tooltip.height;
this.stack = tooltip.stack;
}
@Override
@ParametersAreNonnullByDefault
public void renderImage(Font pFont, int pX, int pY, GuiGraphics pGuiGraphics) {
short[][] colors = DogTag.getColors(this.stack);
if (isAllMinusOne(colors)) return;
pGuiGraphics.pose().pushPose();
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
if (colors[i][j] == -1) continue;
var color = ChatFormatting.getById(colors[i][j]);
pGuiGraphics.fill(5 + pX + i * 4 + 4, 5 + pY + j * 4 + 4, 5 + pX + i * 4, 5 + pY + j * 4,
DogTagEditorScreen.getColorFromFormatting(color));
}
}
pGuiGraphics.pose().popPose();
}
@Override
public int getHeight() {
return !shouldRenderIcon(this.stack) ? 0 : this.height;
}
@Override
public int getWidth(@NotNull Font pFont) {
return !shouldRenderIcon(this.stack) ? 0 : this.width;
}
public static boolean shouldRenderIcon(ItemStack stack) {
short[][] colors = DogTag.getColors(stack);
return !isAllMinusOne(colors);
}
public static boolean isAllMinusOne(short[][] arr) {
if (arr == null) {
return false;
}
for (short[] row : arr) {
if (row == null) {
return false;
}
for (short element : row) {
if (element != (short) -1) {
return false;
}
}
}
return true;
}
}

View file

@ -0,0 +1,21 @@
package com.atsuishio.superbwarfare.client.tooltip.component;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.ItemStack;
public class DogTagImageComponent implements TooltipComponent {
public int width;
public int height;
public ItemStack stack;
public DogTagImageComponent(int width, int height, ItemStack stack) {
this.width = width;
this.height = height;
this.stack = stack;
}
public DogTagImageComponent(ItemStack stack) {
this(80, 80, stack);
}
}

View file

@ -59,6 +59,22 @@ public class DisplayClothConfig {
.build() .build()
); );
category.addEntry(entryBuilder
.startBooleanToggle(Component.translatable("config.superbwarfare.client.display.dog_tag_name_visible"), DisplayConfig.DOG_TAG_NAME_VISIBLE.get())
.setDefaultValue(true)
.setSaveConsumer(DisplayConfig.DOG_TAG_NAME_VISIBLE::set)
.setTooltip(Component.translatable("config.superbwarfare.client.display.dog_tag_name_visible.des"))
.build()
);
category.addEntry(entryBuilder
.startBooleanToggle(Component.translatable("config.superbwarfare.client.display.dog_tag_icon_visible"), DisplayConfig.DOG_TAG_ICON_VISIBLE.get())
.setDefaultValue(false)
.setSaveConsumer(DisplayConfig.DOG_TAG_ICON_VISIBLE::set)
.setTooltip(Component.translatable("config.superbwarfare.client.display.dog_tag_icon_visible.des"))
.build()
);
category.addEntry(entryBuilder category.addEntry(entryBuilder
.startIntSlider(Component.translatable("config.superbwarfare.client.display.weapon_screen_shake"), DisplayConfig.WEAPON_SCREEN_SHAKE.get(), .startIntSlider(Component.translatable("config.superbwarfare.client.display.weapon_screen_shake"), DisplayConfig.WEAPON_SCREEN_SHAKE.get(),
0, 100) 0, 100)

View file

@ -49,6 +49,11 @@ public class ModDataComponents {
builder -> builder.persistent(AmmoBoxInfo.CODEC) builder -> builder.persistent(AmmoBoxInfo.CODEC)
); );
public static final DeferredHolder<DataComponentType<?>, DataComponentType<List<Short>>> DOG_TAG_IMAGE = register(
"dog_tag_image",
builder -> builder.persistent(Codec.SHORT.listOf())
);
private static <T> DeferredHolder<DataComponentType<?>, DataComponentType<T>> register(String name, UnaryOperator<DataComponentType.Builder<T>> builderOperator) { private static <T> DeferredHolder<DataComponentType<?>, DataComponentType<T>> register(String name, UnaryOperator<DataComponentType.Builder<T>> builderOperator) {
return DATA_COMPONENT_TYPES.register(name, () -> builderOperator.apply(DataComponentType.builder()).build()); return DATA_COMPONENT_TYPES.register(name, () -> builderOperator.apply(DataComponentType.builder()).build());
} }

View file

@ -10,6 +10,8 @@ public class DisplayConfig {
public static ModConfigSpec.BooleanValue CAMERA_ROTATE; public static ModConfigSpec.BooleanValue CAMERA_ROTATE;
public static ModConfigSpec.BooleanValue ARMOR_PLATE_HUD; public static ModConfigSpec.BooleanValue ARMOR_PLATE_HUD;
public static ModConfigSpec.BooleanValue STAMINA_HUD; public static ModConfigSpec.BooleanValue STAMINA_HUD;
public static ModConfigSpec.BooleanValue DOG_TAG_NAME_VISIBLE;
public static ModConfigSpec.BooleanValue DOG_TAG_ICON_VISIBLE;
public static ModConfigSpec.IntValue WEAPON_SCREEN_SHAKE; public static ModConfigSpec.IntValue WEAPON_SCREEN_SHAKE;
public static ModConfigSpec.IntValue EXPLOSION_SCREEN_SHAKE; public static ModConfigSpec.IntValue EXPLOSION_SCREEN_SHAKE;
public static ModConfigSpec.IntValue SHOCK_SCREEN_SHAKE; public static ModConfigSpec.IntValue SHOCK_SCREEN_SHAKE;
@ -35,6 +37,12 @@ public class DisplayConfig {
builder.comment("Set true to enable stamina hud"); builder.comment("Set true to enable stamina hud");
STAMINA_HUD = builder.define("stamina_hud", true); STAMINA_HUD = builder.define("stamina_hud", true);
builder.comment("Set true to show the name of dog tag in kill messages");
DOG_TAG_NAME_VISIBLE = builder.define("dog_tag_name_visible", true);
builder.comment("Set true to show the icon of dog tag in kill messages");
DOG_TAG_ICON_VISIBLE = builder.define("dog_tag_icon_visible", false);
builder.comment("The strength of screen shaking while firing with a weapon"); builder.comment("The strength of screen shaking while firing with a weapon");
WEAPON_SCREEN_SHAKE = builder.defineInRange("weapon_screen_shake", 100, 0, 100); WEAPON_SCREEN_SHAKE = builder.defineInRange("weapon_screen_shake", 100, 0, 100);

View file

@ -1,10 +1,7 @@
package com.atsuishio.superbwarfare.init; package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.menu.ChargingStationMenu; import com.atsuishio.superbwarfare.menu.*;
import com.atsuishio.superbwarfare.menu.FuMO25Menu;
import com.atsuishio.superbwarfare.menu.ReforgingTableMenu;
import com.atsuishio.superbwarfare.menu.VehicleMenu;
import net.minecraft.core.registries.BuiltInRegistries; import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.world.inventory.MenuType; import net.minecraft.world.inventory.MenuType;
import net.neoforged.neoforge.common.extensions.IMenuTypeExtension; import net.neoforged.neoforge.common.extensions.IMenuTypeExtension;
@ -28,4 +25,8 @@ public class ModMenuTypes {
public static final Supplier<MenuType<FuMO25Menu>> FUMO_25_MENU = public static final Supplier<MenuType<FuMO25Menu>> FUMO_25_MENU =
REGISTRY.register("fumo_25_menu", REGISTRY.register("fumo_25_menu",
() -> IMenuTypeExtension.create((windowId, inv, data) -> new FuMO25Menu(windowId, inv))); () -> IMenuTypeExtension.create((windowId, inv, data) -> new FuMO25Menu(windowId, inv)));
public static final Supplier<MenuType<DogTagEditorMenu>> DOG_TAG_EDITOR_MENU =
REGISTRY.register("dog_tag_editor_menu",
() -> IMenuTypeExtension.create((windowId, inv, data) -> new DogTagEditorMenu(windowId)));
} }

View file

@ -1,10 +1,7 @@
package com.atsuishio.superbwarfare.init; package com.atsuishio.superbwarfare.init;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.client.screens.ChargingStationScreen; import com.atsuishio.superbwarfare.client.screens.*;
import com.atsuishio.superbwarfare.client.screens.FuMO25Screen;
import com.atsuishio.superbwarfare.client.screens.ReforgingTableScreen;
import com.atsuishio.superbwarfare.client.screens.VehicleScreen;
import net.neoforged.api.distmarker.Dist; import net.neoforged.api.distmarker.Dist;
import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber; import net.neoforged.fml.common.EventBusSubscriber;
@ -19,5 +16,6 @@ public class ModScreens {
event.register(ModMenuTypes.CHARGING_STATION_MENU.get(), ChargingStationScreen::new); event.register(ModMenuTypes.CHARGING_STATION_MENU.get(), ChargingStationScreen::new);
event.register(ModMenuTypes.VEHICLE_MENU.get(), VehicleScreen::new); event.register(ModMenuTypes.VEHICLE_MENU.get(), VehicleScreen::new);
event.register(ModMenuTypes.FUMO_25_MENU.get(), FuMO25Screen::new); event.register(ModMenuTypes.FUMO_25_MENU.get(), FuMO25Screen::new);
event.register(ModMenuTypes.DOG_TAG_EDITOR_MENU.get(), DogTagEditorScreen::new);
} }
} }

View file

@ -1,15 +1,30 @@
package com.atsuishio.superbwarfare.item; package com.atsuishio.superbwarfare.item;
import com.atsuishio.superbwarfare.client.tooltip.component.DogTagImageComponent;
import com.atsuishio.superbwarfare.component.ModDataComponents;
import com.atsuishio.superbwarfare.menu.DogTagEditorMenu;
import net.minecraft.network.chat.Component;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResultHolder;
import net.minecraft.world.SimpleMenuProvider;
import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.inventory.tooltip.TooltipComponent;
import net.minecraft.world.item.Item; import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import top.theillusivec4.curios.api.CuriosApi; import top.theillusivec4.curios.api.CuriosApi;
import top.theillusivec4.curios.api.SlotContext; import top.theillusivec4.curios.api.SlotContext;
import top.theillusivec4.curios.api.type.capability.ICurioItem; import top.theillusivec4.curios.api.type.capability.ICurioItem;
import java.util.Arrays;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
public class DogTag extends Item implements ICurioItem { public class DogTag extends Item implements ICurioItem {
public DogTag() { public DogTag() {
super(new Properties().stacksTo(1)); super(new Properties().stacksTo(1));
} }
@ -22,4 +37,41 @@ public class DogTag extends Item implements ICurioItem {
return flag.get(); return flag.get();
} }
@Override
public @NotNull InteractionResultHolder<ItemStack> use(Level level, Player player, @NotNull InteractionHand usedHand) {
ItemStack stack = player.getItemInHand(usedHand);
if (level.isClientSide) {
return InteractionResultHolder.success(stack);
} else {
player.openMenu(new SimpleMenuProvider((i, inventory, p) ->
new DogTagEditorMenu(i, ContainerLevelAccess.create(level, p.getOnPos()), stack), Component.literal("")));
return InteractionResultHolder.consume(stack);
}
}
@Override
public @NotNull Optional<TooltipComponent> getTooltipImage(@NotNull ItemStack pStack) {
return Optional.of(new DogTagImageComponent(pStack));
}
public static short[][] getColors(ItemStack stack) {
short[][] colors = new short[16][16];
for (var el : colors) {
Arrays.fill(el, (short) -1);
}
var data = stack.get(ModDataComponents.DOG_TAG_IMAGE);
if (data == null) return colors;
var index = 0;
for (int i = 0; i < 16; i++) {
for (int j = 0; j < 16; j++) {
colors[i][j] = data.get(index);
index++;
}
}
return colors;
}
} }

View file

@ -0,0 +1,106 @@
package com.atsuishio.superbwarfare.menu;
import com.atsuishio.superbwarfare.component.ModDataComponents;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModMenuTypes;
import com.atsuishio.superbwarfare.network.message.receive.DogTagEditorMessage;
import net.minecraft.core.component.DataComponents;
import net.minecraft.network.chat.Component;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.util.StringUtil;
import net.minecraft.world.Container;
import net.minecraft.world.SimpleContainer;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.inventory.AbstractContainerMenu;
import net.minecraft.world.inventory.ContainerLevelAccess;
import net.minecraft.world.item.ItemStack;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.event.entity.player.PlayerContainerEvent;
import net.neoforged.neoforge.network.PacketDistributor;
import org.jetbrains.annotations.NotNull;
import javax.annotation.Nullable;
import java.util.List;
@EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME)
public class DogTagEditorMenu extends AbstractContainerMenu {
protected final Container container;
protected final ContainerLevelAccess access;
@Nullable
private String itemName;
public ItemStack stack;
public DogTagEditorMenu(int pContainerId) {
this(pContainerId, new SimpleContainer(0), ContainerLevelAccess.NULL, ItemStack.EMPTY);
}
public DogTagEditorMenu(int pContainerId, ContainerLevelAccess access, ItemStack stack) {
this(pContainerId, new SimpleContainer(0), access, stack);
}
public DogTagEditorMenu(int pContainerId, Container container, ContainerLevelAccess pContainerLevelAccess, ItemStack stack) {
super(ModMenuTypes.DOG_TAG_EDITOR_MENU.get(), pContainerId);
checkContainerSize(container, 0);
this.container = container;
this.access = pContainerLevelAccess;
this.stack = stack;
}
@Override
public @NotNull ItemStack quickMoveStack(@NotNull Player player, int index) {
return ItemStack.EMPTY;
}
@Override
public boolean stillValid(Player pPlayer) {
return pPlayer.isAlive();
}
public boolean setItemName(String name) {
String s = validateName(name);
if (s != null && !s.equals(this.itemName)) {
this.itemName = s;
if (!this.stack.isEmpty()) {
if (StringUtil.isBlank(s)) {
this.stack.remove(DataComponents.CUSTOM_NAME);
} else {
this.stack.set(DataComponents.CUSTOM_NAME, Component.literal(s));
}
}
return true;
} else {
return false;
}
}
@Nullable
private static String validateName(String pItemName) {
String s = StringUtil.filterText(pItemName);
return s.length() <= 30 ? s : null;
}
@SubscribeEvent
public static void onContainerOpened(PlayerContainerEvent.Open event) {
if (event.getContainer() instanceof DogTagEditorMenu menu && event.getEntity() instanceof ServerPlayer serverPlayer) {
var stack = serverPlayer.getItemInHand(serverPlayer.getUsedItemHand());
if (stack.is(ModItems.DOG_TAG.get())) {
PacketDistributor.sendToPlayer(serverPlayer, new DogTagEditorMessage(menu.containerId, stack));
}
}
}
public void finishEdit(List<Short> colors, String name) {
if (this.stack.isEmpty()) return;
stack.set(ModDataComponents.DOG_TAG_IMAGE, colors);
if (!name.isEmpty()) {
this.stack.set(DataComponents.CUSTOM_NAME, Component.literal(name));
}
}
}

View file

@ -1,9 +1,12 @@
package com.atsuishio.superbwarfare.network; package com.atsuishio.superbwarfare.network;
import com.atsuishio.superbwarfare.client.screens.DogTagEditorScreen;
import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.menu.DogTagEditorMenu;
import net.minecraft.client.CameraType; import net.minecraft.client.CameraType;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import java.util.Objects; import java.util.Objects;
@ -22,4 +25,14 @@ public class ClientPacketHandler {
Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON)); Minecraft.getInstance().options.setCameraType(Objects.requireNonNullElse(ClientEventHandler.lastCameraType, CameraType.FIRST_PERSON));
} }
public static void handleDogTagEditorMessage(int containerId, ItemStack stack) {
Minecraft mc = Minecraft.getInstance();
if (mc.player != null && mc.player.containerMenu.containerId == containerId) {
((DogTagEditorMenu) mc.player.containerMenu).stack = stack;
if (mc.screen instanceof DogTagEditorScreen dogTagEditorScreen) {
dogTagEditorScreen.stack = stack;
}
}
}
} }

View file

@ -23,6 +23,7 @@ public class NetworkRegistry {
registrar.playToClient(RadarMenuCloseMessage.TYPE, RadarMenuCloseMessage.STREAM_CODEC, RadarMenuCloseMessage::handler); registrar.playToClient(RadarMenuCloseMessage.TYPE, RadarMenuCloseMessage.STREAM_CODEC, RadarMenuCloseMessage::handler);
registrar.playToClient(SimulationDistanceMessage.TYPE, SimulationDistanceMessage.STREAM_CODEC, SimulationDistanceMessage::handler); registrar.playToClient(SimulationDistanceMessage.TYPE, SimulationDistanceMessage.STREAM_CODEC, SimulationDistanceMessage::handler);
registrar.playToClient(ClientTacticalSprintSyncMessage.TYPE, ClientTacticalSprintSyncMessage.STREAM_CODEC, (msg, ctx) -> ClientTacticalSprintSyncMessage.handler(msg)); registrar.playToClient(ClientTacticalSprintSyncMessage.TYPE, ClientTacticalSprintSyncMessage.STREAM_CODEC, (msg, ctx) -> ClientTacticalSprintSyncMessage.handler(msg));
registrar.playToClient(DogTagEditorMessage.TYPE, DogTagEditorMessage.STREAM_CODEC, (msg, ctx) -> DogTagEditorMessage.handler(msg));
registrar.playToServer(LaserShootMessage.TYPE, LaserShootMessage.STREAM_CODEC, LaserShootMessage::handler); registrar.playToServer(LaserShootMessage.TYPE, LaserShootMessage.STREAM_CODEC, LaserShootMessage::handler);
registrar.playToServer(ShootMessage.TYPE, ShootMessage.STREAM_CODEC, ShootMessage::handler); registrar.playToServer(ShootMessage.TYPE, ShootMessage.STREAM_CODEC, ShootMessage::handler);
@ -55,5 +56,6 @@ public class NetworkRegistry {
registrar.playToServer(ChangeVehicleSeatMessage.TYPE, ChangeVehicleSeatMessage.STREAM_CODEC, ChangeVehicleSeatMessage::handler); registrar.playToServer(ChangeVehicleSeatMessage.TYPE, ChangeVehicleSeatMessage.STREAM_CODEC, ChangeVehicleSeatMessage::handler);
registrar.playToServer(ShowChargingRangeMessage.TYPE, ShowChargingRangeMessage.STREAM_CODEC, ShowChargingRangeMessage::handler); registrar.playToServer(ShowChargingRangeMessage.TYPE, ShowChargingRangeMessage.STREAM_CODEC, ShowChargingRangeMessage::handler);
registrar.playToServer(TacticalSprintMessage.TYPE, TacticalSprintMessage.STREAM_CODEC, TacticalSprintMessage::handler); registrar.playToServer(TacticalSprintMessage.TYPE, TacticalSprintMessage.STREAM_CODEC, TacticalSprintMessage::handler);
registrar.playToServer(DogTagFinishEditMessage.TYPE, DogTagFinishEditMessage.STREAM_CODEC, DogTagFinishEditMessage::handler);
} }
} }

View file

@ -0,0 +1,31 @@
package com.atsuishio.superbwarfare.network.message.receive;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.network.ClientPacketHandler;
import net.minecraft.network.RegistryFriendlyByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.world.item.ItemStack;
import org.jetbrains.annotations.NotNull;
public record DogTagEditorMessage(int containerId, ItemStack stack) implements CustomPacketPayload {
public static final Type<DogTagEditorMessage> TYPE = new Type<>(Mod.loc("dog_tag_editor"));
public static final StreamCodec<RegistryFriendlyByteBuf, DogTagEditorMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.INT, DogTagEditorMessage::containerId,
ItemStack.STREAM_CODEC, DogTagEditorMessage::stack,
DogTagEditorMessage::new
);
public static void handler(DogTagEditorMessage message) {
ClientPacketHandler.handleDogTagEditorMessage(message.containerId, message.stack);
}
@Override
public @NotNull Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View file

@ -0,0 +1,39 @@
package com.atsuishio.superbwarfare.network.message.send;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.menu.DogTagEditorMenu;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
import net.minecraft.network.protocol.common.custom.CustomPacketPayload;
import net.minecraft.server.level.ServerPlayer;
import net.neoforged.neoforge.network.handling.IPayloadContext;
import org.jetbrains.annotations.NotNull;
import java.util.List;
public record DogTagFinishEditMessage(List<Short> colors, String name) implements CustomPacketPayload {
public static final Type<DogTagFinishEditMessage> TYPE = new Type<>(Mod.loc("dog_tag_finish_edit"));
public static final StreamCodec<ByteBuf, DogTagFinishEditMessage> STREAM_CODEC = StreamCodec.composite(
ByteBufCodecs.SHORT.apply(ByteBufCodecs.list()), DogTagFinishEditMessage::colors,
ByteBufCodecs.STRING_UTF8, DogTagFinishEditMessage::name,
DogTagFinishEditMessage::new
);
public static void handler(DogTagFinishEditMessage message, final IPayloadContext context) {
ServerPlayer serverPlayer = (ServerPlayer) context.player();
if (serverPlayer.containerMenu instanceof DogTagEditorMenu menu) {
menu.finishEdit(message.colors, message.name);
}
serverPlayer.closeContainer();
}
@Override
public @NotNull Type<? extends CustomPacketPayload> type() {
return TYPE;
}
}

View file

@ -169,12 +169,10 @@
"item.superbwarfare.wire_guide_missile": "Wire Guide Missile", "item.superbwarfare.wire_guide_missile": "Wire Guide Missile",
"des.superbwarfare.wire_guide_missile": "Suitable for BMP-2", "des.superbwarfare.wire_guide_missile": "Suitable for BMP-2",
"item.superbwarfare.swarm_drone": "Swarm Drone", "item.superbwarfare.swarm_drone": "Swarm Drone",
"des.superbwarfare.swarm_drone": "Suitable for YX-100 MBT",
"item.superbwarfare.medium_aerial_bomb": "Medium Aerial Bomb", "item.superbwarfare.medium_aerial_bomb": "Medium Aerial Bomb",
"des.superbwarfare.medium_aerial_bomb": "Suitable for A-10 Thunderbolt II", "des.superbwarfare.medium_aerial_bomb": "Suitable for A-10 Thunderbolt II",
"item.superbwarfare.agm": "Air-to-ground Missile", "item.superbwarfare.agm": "Air-to-ground Missile",
"des.superbwarfare.agm": "Suitable for A-10 Thunderbolt II", "des.superbwarfare.agm": "Suitable for A-10 Thunderbolt II",
"item.superbwarfare.beast": "BEAST", "item.superbwarfare.beast": "BEAST",
"des.superbwarfare.beast": "You are one one one...", "des.superbwarfare.beast": "You are one one one...",
"item.superbwarfare.firing_parameters": "Firing Parameters", "item.superbwarfare.firing_parameters": "Firing Parameters",
@ -256,7 +254,6 @@
"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",
"des.superbwarfare.charging_station": "Charge nearby entities and adjacent blocks",
"des.superbwarfare.charging_station.energy": "Energy: %1$s / %2$s FE", "des.superbwarfare.charging_station.energy": "Energy: %1$s / %2$s FE",
"block.superbwarfare.creative_charging_station": "Creative Charging Station", "block.superbwarfare.creative_charging_station": "Creative Charging Station",
"des.superbwarfare.creative_charging_station": "Charge nearby entities and adjacent blocks, can also be used as a power source item", "des.superbwarfare.creative_charging_station": "Charge nearby entities and adjacent blocks, can also be used as a power source item",
@ -542,8 +539,8 @@
"tips.superbwarfare.shoot.rings": "Rings", "tips.superbwarfare.shoot.rings": "Rings",
"tips.superbwarfare.annihilator.energy_not_enough": "Insufficient Power!", "tips.superbwarfare.annihilator.energy_not_enough": "Insufficient Power!",
"tips.superbwarfare.target.down": "Target Down %1$s", "tips.superbwarfare.target.down": "Target Down %1$s",
"tips.superbwarfare.target.damage": "Damage: %1$s Distance: %2$s",
"tips.superbwarfare.dps_generator.dps": "DPS: %1$s", "tips.superbwarfare.dps_generator.dps": "DPS: %1$s",
"tips.superbwarfare.target.damage": "Damage: %1$s Distance: %2$s",
"tips.superbwarfare.mortar.range": "Range: ", "tips.superbwarfare.mortar.range": "Range: ",
"tips.superbwarfare.mortar.yaw": "Yaw: ", "tips.superbwarfare.mortar.yaw": "Yaw: ",
"tips.superbwarfare.mortar.pitch": "Pitch: ", "tips.superbwarfare.mortar.pitch": "Pitch: ",
@ -595,6 +592,10 @@
"config.superbwarfare.client.display.explosion_screen_shake.des": "The strength of the screen shake caused by explosions", "config.superbwarfare.client.display.explosion_screen_shake.des": "The strength of the screen shake caused by explosions",
"config.superbwarfare.client.display.shock_screen_shake": "Shock Screen Shake Strength", "config.superbwarfare.client.display.shock_screen_shake": "Shock Screen Shake Strength",
"config.superbwarfare.client.display.shock_screen_shake.des": "The strength of the screen shake caused by shock effect", "config.superbwarfare.client.display.shock_screen_shake.des": "The strength of the screen shake caused by shock effect",
"config.superbwarfare.client.display.dog_tag_name_visible": "Dog Tag Name Visibility",
"config.superbwarfare.client.display.dog_tag_name_visible.des": "Whether to display the name of dog tag in kill messages",
"config.superbwarfare.client.display.dog_tag_icon_visible": "Dog Tag Icon Visibility",
"config.superbwarfare.client.display.dog_tag_icon_visible.des": "Whether to display the icon of dog tag in kill messages",
"config.superbwarfare.client.vehicle": "Control Vehicle", "config.superbwarfare.client.vehicle": "Control Vehicle",
"config.superbwarfare.client.vehicle.invert_aircraft_control": "Invert Aircraft Control", "config.superbwarfare.client.vehicle.invert_aircraft_control": "Invert Aircraft Control",
"config.superbwarfare.client.vehicle.left_click_reload.des": "Set TRUE to invert aircraft control", "config.superbwarfare.client.vehicle.left_click_reload.des": "Set TRUE to invert aircraft control",

View file

@ -169,12 +169,10 @@
"item.superbwarfare.wire_guide_missile": "线控导弹", "item.superbwarfare.wire_guide_missile": "线控导弹",
"des.superbwarfare.wire_guide_missile": "适配BMP-2步兵战车", "des.superbwarfare.wire_guide_missile": "适配BMP-2步兵战车",
"item.superbwarfare.swarm_drone": "蜂群无人机", "item.superbwarfare.swarm_drone": "蜂群无人机",
"des.superbwarfare.swarm_drone": "适配YX-100主战坦克",
"item.superbwarfare.medium_aerial_bomb": "中型航空炸弹", "item.superbwarfare.medium_aerial_bomb": "中型航空炸弹",
"des.superbwarfare.medium_aerial_bomb": "适配A-10攻击机", "des.superbwarfare.medium_aerial_bomb": "适配A-10攻击机",
"item.superbwarfare.agm": "空对地导弹", "item.superbwarfare.agm": "空对地导弹",
"des.superbwarfare.agm": "适配A-10攻击机", "des.superbwarfare.agm": "适配A-10攻击机",
"item.superbwarfare.beast": "BEAST", "item.superbwarfare.beast": "BEAST",
"des.superbwarfare.beast": "你是一个一个一个......", "des.superbwarfare.beast": "你是一个一个一个......",
"item.superbwarfare.firing_parameters": "射击诸元", "item.superbwarfare.firing_parameters": "射击诸元",
@ -256,7 +254,6 @@
"block.superbwarfare.silver_block": "银块", "block.superbwarfare.silver_block": "银块",
"block.superbwarfare.cemented_carbide_block": "硬质合金块", "block.superbwarfare.cemented_carbide_block": "硬质合金块",
"block.superbwarfare.charging_station": "充电站", "block.superbwarfare.charging_station": "充电站",
"des.superbwarfare.charging_station": "充能附近的实体和相邻方块",
"des.superbwarfare.charging_station.energy": "能量:%1$s / %2$s FE", "des.superbwarfare.charging_station.energy": "能量:%1$s / %2$s FE",
"block.superbwarfare.creative_charging_station": "创造模式充电站", "block.superbwarfare.creative_charging_station": "创造模式充电站",
"des.superbwarfare.creative_charging_station": "充能附近的实体和相邻方块,也可以作为电源物品使用", "des.superbwarfare.creative_charging_station": "充能附近的实体和相邻方块,也可以作为电源物品使用",
@ -595,6 +592,10 @@
"config.superbwarfare.client.display.explosion_screen_shake.des": "爆炸时,屏幕抖动的强度", "config.superbwarfare.client.display.explosion_screen_shake.des": "爆炸时,屏幕抖动的强度",
"config.superbwarfare.client.display.shock_screen_shake": "电击屏幕抖动", "config.superbwarfare.client.display.shock_screen_shake": "电击屏幕抖动",
"config.superbwarfare.client.display.shock_screen_shake.des": "受到电击效果时,屏幕抖动的强度", "config.superbwarfare.client.display.shock_screen_shake.des": "受到电击效果时,屏幕抖动的强度",
"config.superbwarfare.client.display.dog_tag_name_visible": "狗牌名称可见性",
"config.superbwarfare.client.display.dog_tag_name_visible.des": "是否在击杀提示中显示狗牌的名称",
"config.superbwarfare.client.display.dog_tag_icon_visible": "狗牌图标可见性",
"config.superbwarfare.client.display.dog_tag_icon_visible.des": "是否在击杀提示中显示狗牌的图标",
"config.superbwarfare.client.vehicle": "载具控制", "config.superbwarfare.client.vehicle": "载具控制",
"config.superbwarfare.client.vehicle.invert_aircraft_control": "飞行器鼠标反转", "config.superbwarfare.client.vehicle.invert_aircraft_control": "飞行器鼠标反转",
"config.superbwarfare.client.vehicle.left_click_reload.des": "开启飞行器鼠标反转", "config.superbwarfare.client.vehicle.left_click_reload.des": "开启飞行器鼠标反转",

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -0,0 +1,5 @@
{
"order": 114,
"size": 1,
"icon": "superbwarfare:slot/dog_tag_slot"
}