重写useBackpackAmmo

This commit is contained in:
Light_Quanta 2025-04-18 00:18:41 +08:00
parent 07dc5b0c57
commit ef76e5ae50
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
9 changed files with 103 additions and 124 deletions

View file

@ -327,7 +327,7 @@ public class ClickHandler {
ClientEventHandler.holdFire = true; ClientEventHandler.holdFire = true;
} }
if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() != null if (stack.getItem() instanceof GunItem && !(player.getVehicle() != null
&& player.getVehicle() instanceof CannonEntity) && player.getVehicle() instanceof CannonEntity)
&& clientTimer.getProgress() == 0 && clientTimer.getProgress() == 0
&& !notInGame() && !notInGame()
@ -339,7 +339,7 @@ public class ClickHandler {
handTimer = 0; handTimer = 0;
} }
if (!gunItem.useBackpackAmmo(stack) && data.ammo.get() <= 0 && data.reload.time() == 0) { if (!data.useBackpackAmmo() && data.ammo.get() <= 0 && data.reload.time() == 0) {
if (ReloadConfig.LEFT_CLICK_RELOAD.get()) { if (ReloadConfig.LEFT_CLICK_RELOAD.get()) {
PacketDistributor.sendToServer(new ReloadMessage(0)); PacketDistributor.sendToServer(new ReloadMessage(0));
ClientEventHandler.burstFireAmount = 0; ClientEventHandler.burstFireAmount = 0;

View file

@ -42,28 +42,15 @@ public class AmmoBarOverlay implements LayeredDraw.Layer {
return player.isCreative() || InventoryTool.hasCreativeAmmoBox(player); return player.isCreative() || InventoryTool.hasCreativeAmmoBox(player);
} }
private static int getGunAmmoCount(Player player) { private static String getGunAmmoString(GunData data, Player player) {
ItemStack stack = player.getMainHandItem(); if (data.useBackpackAmmo() && hasCreativeAmmo()) return "";
return data.useBackpackAmmo() ? data.countBackupAmmo(player) + "" : data.ammo.get() + "";
if (stack.getItem() == ModItems.MINIGUN.get()) {
return GunData.from(stack).countBackupAmmo(player);
}
return GunData.from(stack).ammo.get();
} }
private static String getPlayerAmmoCount(Player player) { private static String getBackupAmmoString(GunData data, Player player) {
ItemStack stack = player.getMainHandItem(); if (data.useBackpackAmmo()) return "";
if (stack.getItem() == ModItems.MINIGUN.get()) { return hasCreativeAmmo() ? "" : data.countBackupAmmo(player) + "";
return "";
}
if (!hasCreativeAmmo()) {
var data = GunData.from(stack);
return data.countBackupAmmo(player) + "";
}
return "";
} }
@Override @Override
@ -79,8 +66,8 @@ public class AmmoBarOverlay implements LayeredDraw.Layer {
if (player.isSpectator()) return; if (player.isSpectator()) return;
ItemStack stack = player.getMainHandItem(); ItemStack stack = player.getMainHandItem();
final var tag = NBTTool.getTag(stack);
if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) { if (stack.getItem() instanceof GunItem gunItem && !(player.getVehicle() instanceof ArmedVehicleEntity vehicle && vehicle.banHand(player))) {
final var tag = NBTTool.getTag(stack);
PoseStack poseStack = guiGraphics.pose(); PoseStack poseStack = guiGraphics.pose();
var data = GunData.from(stack); var data = GunData.from(stack);
@ -174,32 +161,21 @@ public class AmmoBarOverlay implements LayeredDraw.Layer {
poseStack.pushPose(); poseStack.pushPose();
poseStack.scale(1.5f, 1.5f, 1f); poseStack.scale(1.5f, 1.5f, 1f);
if (stack.getItem() == ModItems.MINIGUN.get() && hasCreativeAmmo()) { guiGraphics.drawString(
guiGraphics.drawString( Minecraft.getInstance().font,
Minecraft.getInstance().font, getGunAmmoString(data, player),
"", w / 1.5f - 64 / 1.5f,
w / 1.5f - 64 / 1.5f, h / 1.5f - 48 / 1.5f,
h / 1.5f - 48 / 1.5f, 0xFFFFFF,
0xFFFFFF, true
true );
);
} else {
guiGraphics.drawString(
Minecraft.getInstance().font,
getGunAmmoCount(player) + "",
w / 1.5f - 64 / 1.5f,
h / 1.5f - 48 / 1.5f,
0xFFFFFF,
true
);
}
poseStack.popPose(); poseStack.popPose();
// 渲染备弹量 // 渲染备弹量
guiGraphics.drawString( guiGraphics.drawString(
Minecraft.getInstance().font, Minecraft.getInstance().font,
getPlayerAmmoCount(player), getBackupAmmoString(data, player),
w - 64, w - 64,
h - 35, h - 35,
0xCCCCCC, 0xCCCCCC,

View file

@ -82,7 +82,7 @@ public class JavelinHudOverlay implements LayeredDraw.Layer {
float j1 = l + j; float j1 = l + j;
preciseBlit(guiGraphics, Mod.loc("textures/screens/javelin/javelin_hud.png"), k, l, 0, 0.0F, i, j, i, j); preciseBlit(guiGraphics, Mod.loc("textures/screens/javelin/javelin_hud.png"), k, l, 0, 0.0F, i, j, i, j);
preciseBlit(guiGraphics, Mod.loc(tag.getBoolean("TopMode") ? "textures/screens/javelin/top.png" : "textures/screens/javelin/dir.png"), k, l, 0, 0.0F, i, j, i, j); preciseBlit(guiGraphics, Mod.loc(tag.getBoolean("TopMode") ? "textures/screens/javelin/top.png" : "textures/screens/javelin/dir.png"), k, l, 0, 0.0F, i, j, i, j);
preciseBlit(guiGraphics, Mod.loc(data.ammo.get() > 0 ? "textures/screens/javelin/missile_green.png" : "textures/screens/javelin/missile_red.png"), k, l, 0, 0.0F, i, j, i, j); preciseBlit(guiGraphics, Mod.loc(data.hasEnoughAmmoToShoot(player) ? "textures/screens/javelin/missile_green.png" : "textures/screens/javelin/missile_red.png"), k, l, 0, 0.0F, i, j, i, j);
if (tag.getInt("SeekTime") > 1 && tag.getInt("SeekTime") < 20) { if (tag.getInt("SeekTime") > 1 && tag.getInt("SeekTime") < 20) {
preciseBlit(guiGraphics, Mod.loc("textures/screens/javelin/seek.png"), k, l, 0, 0.0F, i, j, i, j); preciseBlit(guiGraphics, Mod.loc("textures/screens/javelin/seek.png"), k, l, 0, 0.0F, i, j, i, j);
} }

View file

@ -582,7 +582,7 @@ public class ClientEventHandler {
&& (!(data.reload.normal() || data.reload.empty()) && (!(data.reload.normal() || data.reload.empty())
&& !data.reloading() && !data.reloading()
&& !data.charging() && !data.charging()
&& data.ammo.get() > 0 && data.hasEnoughAmmoToShoot(player)
&& !player.getCooldowns().isOnCooldown(stack.getItem()) && !player.getCooldowns().isOnCooldown(stack.getItem())
&& !data.bolt.needed.get() && !data.bolt.needed.get()
&& revolverPre(data)) && revolverPre(data))
@ -659,67 +659,66 @@ public class ClientEventHandler {
ItemStack stack = player.getMainHandItem(); ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem)) return; if (!(stack.getItem() instanceof GunItem)) return;
var data = GunData.from(stack); var data = GunData.from(stack);
if (!data.hasEnoughAmmoToShoot(player)) return;
if (stack.is(ModTags.Items.NORMAL_GUN)) { if (stack.is(ModTags.Items.NORMAL_GUN)) {
if (data.ammo.get() > 0) { int mode = data.fireMode.get();
int mode = data.fireMode.get(); if (mode != 2) {
if (mode != 2) { holdFire = false;
holdFire = false;
}
if (mode == 1) {
if (data.ammo.get() == 1) {
burstFireAmount = 1;
}
if (burstFireAmount == 1) {
cantFireTime = 30;
}
}
if (burstFireAmount > 0) {
burstFireAmount--;
}
if (stack.is(ModItems.DEVOTION.get())) {
int perkLevel = data.perk.getLevel(ModPerks.TURBO_CHARGER);
customRpm = Math.min(customRpm + 15 + ((perkLevel > 0 ? 5 : 0) + 3 * perkLevel), 500);
}
if (stack.getItem() == ModItems.SENTINEL.get()) {
chamberRot = 1;
}
if (stack.getItem() == ModItems.NTW_20.get()) {
actionMove = 1;
}
// 判断是否为栓动武器BoltActionTime > 0并在开火后给一个需要上膛的状态
if (data.defaultActionTime() > 0 && data.ammo.get() > (stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) {
data.bolt.needed.set(true);
}
revolverPreTime = 0;
revolverWheelPreTime = 0;
playGunClientSounds(player);
handleClientShoot();
} }
if (mode == 1) {
if (data.ammo.get() == 1) {
burstFireAmount = 1;
}
if (burstFireAmount == 1) {
cantFireTime = 30;
}
}
if (burstFireAmount > 0) {
burstFireAmount--;
}
if (stack.is(ModItems.DEVOTION.get())) {
int perkLevel = data.perk.getLevel(ModPerks.TURBO_CHARGER);
customRpm = Math.min(customRpm + 15 + ((perkLevel > 0 ? 5 : 0) + 3 * perkLevel), 500);
}
if (stack.getItem() == ModItems.SENTINEL.get()) {
chamberRot = 1;
}
if (stack.getItem() == ModItems.NTW_20.get()) {
actionMove = 1;
}
// 判断是否为栓动武器BoltActionTime > 0并在开火后给一个需要上膛的状态
if (data.defaultActionTime() > 0 && data.ammo.get() > (stack.is(ModTags.Items.REVOLVER) ? 0 : 1)) {
data.bolt.needed.set(true);
}
revolverPreTime = 0;
revolverWheelPreTime = 0;
playGunClientSounds(player);
handleClientShoot();
} else if (stack.is(ModItems.MINIGUN.get())) { } else if (stack.is(ModItems.MINIGUN.get())) {
if (data.hasBackupAmmo(player)) { // TODO 提取通用处理方法
var perk = data.perk.get(Perk.Type.AMMO); var perk = data.perk.get(Perk.Type.AMMO);
float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat"))); float pitch = tag.getDouble("heat") <= 40 ? 1 : (float) (1 - 0.025 * Math.abs(40 - tag.getDouble("heat")));
player.playSound(ModSounds.MINIGUN_FIRE_1P.get(), 1f, pitch); player.playSound(ModSounds.MINIGUN_FIRE_1P.get(), 1f, pitch);
if (perk == ModPerks.BEAST_BULLET.get()) { if (perk == ModPerks.BEAST_BULLET.get()) {
player.playSound(ModSounds.HENG.get(), 1f, 1f); player.playSound(ModSounds.HENG.get(), 1f, 1f);
}
double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos())));
Mod.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
} }
double shooterHeight = player.getEyePosition().distanceTo((Vec3.atLowerCornerOf(player.level().clip(new ClipContext(player.getEyePosition(), player.getEyePosition().add(new Vec3(0, -1, 0).scale(10)),
ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, player)).getBlockPos())));
Mod.queueClientWork((int) (1 + 1.5 * shooterHeight), () -> player.playSound(ModSounds.SHELL_CASING_NORMAL.get(), (float) Math.max(1.5 - 0.2 * shooterHeight, 0), 1));
handleClientShoot(); handleClientShoot();
} }
} }

View file

@ -246,15 +246,6 @@ public abstract class GunItem extends Item implements CustomRendererItem {
return false; return false;
} }
/**
* 武器是否直接使用背包内的弹药物品进行发射而不是使用玩家存储的弹药
*
* @param stack 武器物品
*/
public boolean useBackpackAmmo(ItemStack stack) {
return false;
}
/** /**
* 武器是否能进行改装 * 武器是否能进行改装
* *
@ -512,15 +503,19 @@ public abstract class GunItem extends Item implements CustomRendererItem {
data.bolt.needed.set(true); data.bolt.needed.set(true);
} }
data.ammo.set(data.ammo.get() - 1); if (!data.useBackpackAmmo()) {
data.isEmpty.set(true); data.ammo.set(data.ammo.get() - 1);
data.isEmpty.set(true);
} else {
data.consumeBackupAmmo(player, 1);
}
} }
/** /**
* 服务端处理开火 * 服务端处理开火
*/ */
public void onShoot(GunData data, Player player, double spread, boolean zoom) { public void onShoot(GunData data, Player player, double spread, boolean zoom) {
if (data.ammo.get() <= 0) return; if (!data.hasEnoughAmmoToShoot(player)) return;
// 开火前事件 // 开火前事件
data.item.beforeShoot(data, player, spread, zoom); data.item.beforeShoot(data, player, spread, zoom);
@ -574,7 +569,7 @@ public abstract class GunItem extends Item implements CustomRendererItem {
* 服务端处理按下开火按键时的额外行为 * 服务端处理按下开火按键时的额外行为
*/ */
public void onFireKeyPress(final GunData data, Player player, boolean zoom) { public void onFireKeyPress(final GunData data, Player player, boolean zoom) {
if (data.reload.prepareTimer.get() == 0 && data.reloading() && data.ammo.get() > 0) { if (data.reload.prepareTimer.get() == 0 && data.reloading() && data.hasEnoughAmmoToShoot(player)) {
data.forceStop.set(true); data.forceStop.set(true);
} }

View file

@ -171,6 +171,13 @@ public class GunData {
return defaultGunData().magazine + item.getCustomMagazine(stack); return defaultGunData().magazine + item.getCustomMagazine(stack);
} }
/**
* 武器是否直接使用背包内弹药
*/
public boolean useBackpackAmmo() {
return magazine() <= 0;
}
public int projectileAmount() { public int projectileAmount() {
return defaultGunData().projectileAmount; return defaultGunData().projectileAmount;
} }
@ -362,11 +369,20 @@ public class GunData {
} }
} }
/**
* 是否拥有足够的弹药进行开火
*/
public boolean hasEnoughAmmoToShoot(Player player) {
return useBackpackAmmo() ? hasBackupAmmo(player) : this.ammo.get() > 0;
}
public void reload(Player player) { public void reload(Player player) {
reload(player, false); reload(player, false);
} }
public void reload(Player player, boolean extraOne) { public void reload(Player player, boolean extraOne) {
if (useBackpackAmmo()) return;
int mag = magazine(); int mag = magazine();
int ammo = this.ammo.get(); int ammo = this.ammo.get();
int ammoNeeded = mag - ammo + (extraOne ? 1 : 0); int ammoNeeded = mag - ammo + (extraOne ? 1 : 0);

View file

@ -215,8 +215,4 @@ public class MinigunItem extends GunItem implements GeoItem {
return true; return true;
} }
@Override
public boolean useBackpackAmmo(ItemStack stack) {
return true;
}
} }

View file

@ -133,11 +133,6 @@ public class BocekItem extends GunItem implements GeoItem {
return Optional.of(new BocekImageComponent(pStack)); return Optional.of(new BocekImageComponent(pStack));
} }
@Override
public boolean useBackpackAmmo(ItemStack stack) {
return true;
}
@Override @Override
public String getAmmoDisplayName(GunData data) { public String getAmmoDisplayName(GunData data) {
return "Arrow"; return "Arrow";

View file

@ -28,15 +28,17 @@ public record ReloadMessage(int msgType) implements CustomPacketPayload {
public static void pressAction(Player player, int type) { public static void pressAction(Player player, int type) {
if (type != 0) return; if (type != 0) return;
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem gunItem)) return;
var data = GunData.from(stack);
if (data.useBackpackAmmo()) return;
var cap = player.getData(ModAttachments.PLAYER_VARIABLE).watch(); var cap = player.getData(ModAttachments.PLAYER_VARIABLE).watch();
cap.edit = false; cap.edit = false;
player.setData(ModAttachments.PLAYER_VARIABLE, cap); player.setData(ModAttachments.PLAYER_VARIABLE, cap);
cap.sync(player); cap.sync(player);
ItemStack stack = player.getMainHandItem();
if (!(stack.getItem() instanceof GunItem gunItem)) return;
var data = GunData.from(stack);
if (!player.isSpectator() if (!player.isSpectator()
&& !data.charging() && !data.charging()