提取AmmoType

This commit is contained in:
Light_Quanta 2025-04-14 15:38:12 +08:00
parent bf2e574a06
commit aa8e951e51
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
49 changed files with 290 additions and 266 deletions

View file

@ -9,6 +9,7 @@ import com.atsuishio.superbwarfare.init.ModKeyMappings;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.tools.AmmoType;
import com.atsuishio.superbwarfare.tools.InventoryTool;
import com.atsuishio.superbwarfare.tools.NBTTool;
import com.mojang.blaze3d.vertex.PoseStack;
@ -71,22 +72,19 @@ public class AmmoBarOverlay implements LayeredDraw.Layer {
if (stack.is(ModTags.Items.LAUNCHER) || stack.getItem() == ModItems.TASER.get()) {
return "" + data.maxAmmo.get();
}
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
return "" + cap.rifleAmmo;
}
if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
return "" + cap.handgunAmmo;
}
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
return "" + cap.shotgunAmmo;
}
if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
return "" + cap.sniperAmmo;
}
if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
return "" + cap.heavyAmmo;
}
return "";
var ammoTypeInfo = data.ammoTypeInfo();
return switch (ammoTypeInfo.type()) {
case PLAYER_AMMO -> {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
yield type.get(cap) + "";
}
// TODO 正确计算弹药数量
case ITEM, TAG -> "" + data.maxAmmo.get();
default -> "";
};
}
return "";
@ -247,7 +245,7 @@ public class AmmoBarOverlay implements LayeredDraw.Layer {
);
// 渲染弹药类型
String ammoName = gunItem.getAmmoDisplayName(stack);
String ammoName = gunItem.getAmmoDisplayName(data);
guiGraphics.drawString(
Minecraft.getInstance().font,
ammoName,

View file

@ -16,8 +16,10 @@ import com.atsuishio.superbwarfare.tools.InventoryTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.core.Holder;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.effect.MobEffect;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.player.Player;
@ -286,6 +288,7 @@ public class GunEventHandler {
reload.reduce();
// 换弹时额外行为
var behavior = gunItem.reloadTimeBehaviors.get(reload.time());
if (behavior != null) {
behavior.accept(gun);
@ -305,26 +308,20 @@ public class GunEventHandler {
}
}
public static void playGunNormalReload(Player player, GunData gunData) {
var stack = gunData.stack();
var gunItem = gunData.item();
public static void playGunNormalReload(Player player, GunData data) {
var stack = data.stack();
var gunItem = data.item();
if (player.getInventory().hasAnyMatching(item -> item.is(ModItems.CREATIVE_AMMO_BOX.get()))) {
gunData.ammo.set(gunData.magazine() + (gunItem.hasBulletInBarrel(stack) ? 1 : 0));
data.ammo.set(data.magazine() + (gunItem.hasBulletInBarrel(stack) ? 1 : 0));
} else {
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
GunsTool.reload(player, stack, gunData, AmmoType.SHOTGUN, gunItem.hasBulletInBarrel(stack));
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
GunsTool.reload(player, stack, gunData, AmmoType.SNIPER, true);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
GunsTool.reload(player, stack, gunData, AmmoType.HANDGUN, true);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
GunsTool.reload(player, stack, gunData, AmmoType.RIFLE, gunItem.hasBulletInBarrel(stack));
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
GunsTool.reload(player, stack, gunData, AmmoType.HEAVY, gunItem.hasBulletInBarrel(stack));
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
GunsTool.reload(player, stack, data, AmmoType.getType(ammoTypeInfo.value()), gunItem.hasBulletInBarrel(stack));
}
}
gunData.reload.setState(ReloadState.NOT_RELOADING);
data.reload.setState(ReloadState.NOT_RELOADING);
NeoForge.EVENT_BUS.post(new ReloadEvent.Post(player, stack));
}
@ -334,20 +331,25 @@ public class GunEventHandler {
if (player.getInventory().hasAnyMatching(item -> item.is(ModItems.CREATIVE_AMMO_BOX.get()))) {
data.ammo.set(data.magazine());
} else {
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
GunsTool.reload(player, stack, data, AmmoType.SHOTGUN);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
GunsTool.reload(player, stack, data, AmmoType.SNIPER);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
GunsTool.reload(player, stack, data, AmmoType.HANDGUN);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
GunsTool.reload(player, stack, data, AmmoType.RIFLE);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
GunsTool.reload(player, stack, data, AmmoType.HEAVY);
} else if (data.item().getCustomAmmoItem() != null) {
var ammoItem = data.item().getCustomAmmoItem();
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ammoItem, 1, player.inventoryMenu.getCraftSlots());
var ammoTypeInfo = data.ammoTypeInfo();
switch (ammoTypeInfo.type()) {
case PLAYER_AMMO -> GunsTool.reload(player, stack, data, AmmoType.getType(ammoTypeInfo.value()));
case TAG -> {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(
p -> p.is(ItemTags.create(ResourceLocation.parse(ammoTypeInfo.value()))),
1,
player.inventoryMenu.getCraftSlots()
);
}
case ITEM -> {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(
p -> p.getItem().getDescriptionId().equals(ammoTypeInfo.value()),
1,
player.inventoryMenu.getCraftSlots()
);
}
}
}
data.reload.setState(ReloadState.NOT_RELOADING);
@ -449,15 +451,26 @@ public class GunEventHandler {
if ((reload.prepareTimer.get() == 1 || reload.prepareLoadTimer.get() == 1)) {
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var capability = player.getData(ModAttachments.PLAYER_VARIABLE);
var startStage3 = false;
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && capability.shotgunAmmo == 0
|| stack.is(ModTags.Items.USE_SNIPER_AMMO) && capability.sniperAmmo == 0
|| stack.is(ModTags.Items.USE_HANDGUN_AMMO) && capability.handgunAmmo == 0
|| stack.is(ModTags.Items.USE_RIFLE_AMMO) && capability.rifleAmmo == 0
|| stack.is(ModTags.Items.USE_HEAVY_AMMO) && capability.heavyAmmo == 0
|| stack.is(ModTags.Items.LAUNCHER) && data.maxAmmo.get() == 0
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
if (type.get(capability) == 0) {
startStage3 = true;
}
}
// TODO 优化这坨判断
if (stack.is(ModTags.Items.LAUNCHER) && data.maxAmmo.get() == 0
|| stack.is(ModItems.SECONDARY_CATACLYSM.get()) && data.ammo.get() >= data.magazine()
) {
startStage3 = true;
}
if (startStage3) {
reload.stage3Starter.markStart();
} else {
reload.setStage(2);
@ -521,16 +534,14 @@ public class GunEventHandler {
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var capability = player.getData(ModAttachments.PLAYER_VARIABLE);
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && capability.shotgunAmmo == 0) {
reload.setStage(3);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && capability.sniperAmmo == 0) {
reload.setStage(3);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO) && capability.handgunAmmo == 0) {
reload.setStage(3);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && capability.rifleAmmo == 0) {
reload.setStage(3);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && capability.heavyAmmo == 0) {
reload.setStage(3);
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
if (type.get(capability) == 0) {
reload.setStage(3);
}
}
}
@ -577,19 +588,24 @@ public class GunEventHandler {
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var cap = player.getData(ModAttachments.PLAYER_VARIABLE);
ItemStack stack = player.getMainHandItem();
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
AmmoType.SHOTGUN.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
AmmoType.SNIPER.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
AmmoType.HANDGUN.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
AmmoType.RIFLE.add(cap, -1);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
AmmoType.HEAVY.add(cap, -1);
} else if (stack.getItem() == ModItems.SECONDARY_CATACLYSM.get()) {
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == data.item().getCustomAmmoItem(), 1, player.inventoryMenu.getCraftSlots());
var ammoTypeInfo = data.ammoTypeInfo();
switch (ammoTypeInfo.type()) {
case PLAYER_AMMO -> {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
type.add(cap, -1);
}
case ITEM -> player.getInventory().clearOrCountMatchingItems(
p -> p.getItem().getDescriptionId().equals(ammoTypeInfo.value()),
1,
player.inventoryMenu.getCraftSlots()
);
case TAG -> player.getInventory().clearOrCountMatchingItems(
p -> p.is(ItemTags.create(ResourceLocation.parse(ammoTypeInfo.value()))),
1,
player.inventoryMenu.getCraftSlots()
);
}
player.setData(ModAttachments.PLAYER_VARIABLE, cap);

View file

@ -143,6 +143,7 @@ public class LivingEventHandler {
if (DamageTypeTool.isGunDamage(source) && stack.getItem() instanceof GunItem) {
double distance = entity.position().distanceTo(sourceEntity.position());
// TODO 正确计算距离衰减
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
var perk = data.perk.get(Perk.Type.AMMO);
@ -650,45 +651,18 @@ public class LivingEventHandler {
boolean flag = InventoryTool.hasCreativeAmmoBox(player);
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
int ammoFinal = Math.min(cap.rifleAmmo, ammoNeed);
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
int ammoFinal = Math.min(type.get(cap), ammoNeed);
if (flag) {
ammoFinal = ammoNeed;
} else {
cap.rifleAmmo -= ammoFinal;
}
data.ammo.set(Math.min(mag, ammo + ammoFinal));
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
int ammoFinal = Math.min(cap.handgunAmmo, ammoNeed);
if (flag) {
ammoFinal = ammoNeed;
} else {
cap.handgunAmmo -= ammoFinal;
}
data.ammo.set(Math.min(mag, ammo + ammoFinal));
} else if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
int ammoFinal = Math.min(cap.handgunAmmo, ammoNeed);
if (flag) {
ammoFinal = ammoNeed;
} else {
cap.shotgunAmmo -= ammoFinal;
}
data.ammo.set(Math.min(mag, ammo + ammoFinal));
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
int ammoFinal = Math.min(cap.handgunAmmo, ammoNeed);
if (flag) {
ammoFinal = ammoNeed;
} else {
cap.sniperAmmo -= ammoFinal;
}
data.ammo.set(Math.min(mag, ammo + ammoFinal));
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
int ammoFinal = Math.min(cap.heavyAmmo, ammoNeed);
if (flag) {
ammoFinal = ammoNeed;
} else {
cap.heavyAmmo -= ammoFinal;
type.add(cap, -ammoFinal);
}
data.ammo.set(Math.min(mag, ammo + ammoFinal));
}

View file

@ -17,6 +17,7 @@ import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.sounds.SoundSource;
import net.minecraft.tags.ItemTags;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.ai.attributes.AttributeModifier;
import net.minecraft.world.entity.ai.attributes.Attributes;
@ -110,38 +111,38 @@ public class PlayerEventHandler {
if (!InventoryTool.hasCreativeAmmoBox(player)) {
var cap = player.getData(ModAttachments.PLAYER_VARIABLE);
var ammoTypeInfo = data.ammoTypeInfo();
switch (ammoTypeInfo.type()) {
case PLAYER_AMMO -> {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && cap.shotgunAmmo > 0) {
GunsTool.reload(player, stack, data, AmmoType.SHOTGUN);
}
if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && cap.sniperAmmo > 0) {
GunsTool.reload(player, stack, data, AmmoType.SNIPER);
}
if (stack.is(ModTags.Items.USE_HANDGUN_AMMO) && cap.handgunAmmo > 0) {
GunsTool.reload(player, stack, data, AmmoType.HANDGUN);
}
if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && cap.rifleAmmo > 0) {
GunsTool.reload(player, stack, data, AmmoType.RIFLE);
}
if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && cap.heavyAmmo > 0) {
GunsTool.reload(player, stack, data, AmmoType.HEAVY);
}
if (stack.getItem() == ModItems.TASER.get() && data.maxAmmo.get() > 0 && data.ammo.get() == 0) {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.TASER_ELECTRODE.get(), 1, player.inventoryMenu.getCraftSlots());
}
if (stack.getItem() == ModItems.M_79.get() && data.maxAmmo.get() > 0 && data.ammo.get() == 0) {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.GRENADE_40MM.get(), 1, player.inventoryMenu.getCraftSlots());
}
if (stack.getItem() == ModItems.RPG.get() && data.maxAmmo.get() > 0 && data.ammo.get() == 0) {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.ROCKET.get(), 1, player.inventoryMenu.getCraftSlots());
}
if (stack.getItem() == ModItems.JAVELIN.get() && data.maxAmmo.get() > 0 && data.ammo.get() == 0) {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(p -> p.getItem() == ModItems.JAVELIN_MISSILE.get(), 1, player.inventoryMenu.getCraftSlots());
if (type.get(cap) == 0) {
GunsTool.reload(player, stack, data, type);
}
}
case ITEM -> {
// TODO 弃用maxAmmo
if (data.ammo.get() == 0 && data.maxAmmo.get() == 0) {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(
p -> p.getItem().getDescriptionId().equals(ammoTypeInfo.value()),
1,
player.inventoryMenu.getCraftSlots()
);
}
}
case TAG -> {
// TODO 弃用maxAmmo
if (data.ammo.get() == 0 && data.maxAmmo.get() == 0) {
data.ammo.set(1);
player.getInventory().clearOrCountMatchingItems(
p -> p.is(ItemTags.create(ResourceLocation.parse(ammoTypeInfo.value()))),
1,
player.inventoryMenu.getCraftSlots()
);
}
}
}
} else {
data.ammo.set(data.magazine());

View file

@ -6,7 +6,6 @@ import com.atsuishio.superbwarfare.client.tooltip.component.GunImageComponent;
import com.atsuishio.superbwarfare.init.ModAttachments;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModPerks;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.CustomRendererItem;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.item.gun.data.value.AttachmentType;
@ -59,10 +58,7 @@ public abstract class GunItem extends Item implements CustomRendererItem {
@Override
@ParametersAreNonnullByDefault
public void inventoryTick(ItemStack stack, Level level, Entity entity, int slot, boolean selected) {
if (!(entity instanceof LivingEntity)
|| !(stack.getItem() instanceof GunItem)
|| !(stack.getItem() instanceof GunItem gunItem)
) return;
if (!(entity instanceof LivingEntity) || !(stack.getItem() instanceof GunItem gunItem)) return;
var data = GunData.from(stack);
@ -81,19 +77,16 @@ public abstract class GunItem extends Item implements CustomRendererItem {
if ((hasBulletInBarrel && ammoCount > magazine + 1) || (!hasBulletInBarrel && ammoCount > magazine)) {
int count = ammoCount - magazine - (hasBulletInBarrel ? 1 : 0);
var capability = entity.getData(ModAttachments.PLAYER_VARIABLE).watch();
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
AmmoType.SHOTGUN.add(capability, count);
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
AmmoType.SNIPER.add(capability, count);
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
AmmoType.HANDGUN.add(capability, count);
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
AmmoType.RIFLE.add(capability, count);
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
AmmoType.HEAVY.add(capability, count);
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
type.add(capability, count);
}
entity.setData(ModAttachments.PLAYER_VARIABLE, capability);
capability.sync(entity);
data.ammo.set(magazine + (hasBulletInBarrel ? 1 : 0));
@ -465,21 +458,19 @@ public abstract class GunItem extends Item implements CustomRendererItem {
/**
* 右下角弹药显示名称
*/
public String getAmmoDisplayName(ItemStack stack) {
if (stack.is(ModTags.Items.USE_RIFLE_AMMO)) {
return "Rifle Ammo";
}
if (stack.is(ModTags.Items.USE_HANDGUN_AMMO)) {
return "Handgun Ammo";
}
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO)) {
return "Shotgun Ammo";
}
if (stack.is(ModTags.Items.USE_SNIPER_AMMO)) {
return "Sniper Ammo";
}
if (stack.is(ModTags.Items.USE_HEAVY_AMMO)) {
return "Heavy Ammo";
public String getAmmoDisplayName(GunData data) {
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
var type = AmmoType.getType(ammoTypeInfo.value());
assert type != null;
return switch (type) {
case RIFLE -> "Rifle Ammo";
case HANDGUN -> "Handgun Ammo";
case SHOTGUN -> "Shotgun Ammo";
case SNIPER -> "Sniper Ammo";
case HEAVY -> "Heavy Ammo";
};
}
return "";
}
@ -504,10 +495,6 @@ public abstract class GunItem extends Item implements CustomRendererItem {
public void addReloadTimeBehavior(Map<Integer, Consumer<GunData>> behaviors) {
}
public Item getCustomAmmoItem() {
return null;
}
@SubscribeEvent
private static void registerGunExtensions(RegisterClientExtensionsEvent event) {
for (var item : ModItems.GUNS.getEntries()) {

View file

@ -37,6 +37,9 @@ public class DefaultGunData {
@SerializedName("BypassesArmor")
public double bypassArmor;
@SerializedName("AmmoType")
public String ammoType = "";
@SerializedName("NormalReloadTime")
public int normalReloadTime;
@SerializedName("EmptyReloadTime")

View file

@ -5,9 +5,11 @@ import com.atsuishio.superbwarfare.item.gun.data.subdata.*;
import com.atsuishio.superbwarfare.item.gun.data.value.*;
import com.atsuishio.superbwarfare.perk.AmmoPerk;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.tools.AmmoType;
import com.atsuishio.superbwarfare.tools.GunsTool;
import net.minecraft.core.component.DataComponents;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.component.CustomData;
@ -259,10 +261,44 @@ public class GunData {
return defaultGunData().burstAmount;
}
public enum AmmoConsumeType {
PLAYER_AMMO, ITEM, TAG, INVALID,
}
public record AmmoTypeInfo(AmmoConsumeType type, String value) {
}
public AmmoTypeInfo ammoTypeInfo() {
var ammoType = defaultGunData().ammoType;
if (ammoType.isEmpty()) {
return new AmmoTypeInfo(AmmoConsumeType.INVALID, "");
}
// 玩家弹药
if (ammoType.startsWith("@")) {
if (AmmoType.getType(ammoType.substring(1)) == null) {
return new AmmoTypeInfo(AmmoConsumeType.INVALID, ammoType.substring(1));
}
return new AmmoTypeInfo(AmmoConsumeType.PLAYER_AMMO, ammoType.substring(1));
}
// 物品Tag
if (ammoType.startsWith("#")) {
if (ResourceLocation.tryParse(ammoType.substring(1)) == null) {
return new AmmoTypeInfo(AmmoConsumeType.INVALID, ammoType.substring(1));
}
return new AmmoTypeInfo(AmmoConsumeType.TAG, ammoType.substring(1));
}
// 普通物品
if (ResourceLocation.tryParse(ammoType) == null) {
return new AmmoTypeInfo(AmmoConsumeType.INVALID, ammoType);
}
return new AmmoTypeInfo(AmmoConsumeType.ITEM, ammoType);
}
// 可持久化属性开始
public final IntValue ammo;
public final IntValue fireMode;
public final IntValue level;

View file

@ -237,7 +237,7 @@ public class JavelinItem extends GunItem implements GeoItem, SpecialFireWeapon {
}
@Override
public String getAmmoDisplayName(ItemStack stack) {
public String getAmmoDisplayName(GunData data) {
return "Javelin Missile";
}
@ -335,8 +335,4 @@ public class JavelinItem extends GunItem implements GeoItem, SpecialFireWeapon {
tag.putInt("SeekTime", 0);
}
@Override
public Item getCustomAmmoItem() {
return ModItems.JAVELIN_MISSILE.get();
}
}

View file

@ -162,7 +162,7 @@ public class M79Item extends GunItem implements GeoItem, SpecialFireWeapon {
}
@Override
public String getAmmoDisplayName(ItemStack stack) {
public String getAmmoDisplayName(GunData data) {
return "40mm Grenade";
}
@ -221,8 +221,4 @@ public class M79Item extends GunItem implements GeoItem, SpecialFireWeapon {
data.ammo.set(data.ammo.get() - 1);
}
@Override
public Item getCustomAmmoItem() {
return ModItems.GRENADE_40MM.get();
}
}

View file

@ -50,7 +50,7 @@ import java.util.function.Supplier;
public class RpgItem extends GunItem implements GeoItem, SpecialFireWeapon {
@Override
public String getAmmoDisplayName(ItemStack stack) {
public String getAmmoDisplayName(GunData data) {
return "Yassin105 TBG";
}
@ -253,8 +253,4 @@ public class RpgItem extends GunItem implements GeoItem, SpecialFireWeapon {
behaviors.put(9, data -> data.closeHammer.set(false));
}
@Override
public Item getCustomAmmoItem() {
return ModItems.ROCKET.get();
}
}

View file

@ -16,6 +16,7 @@ import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.network.message.receive.ShootClientMessage;
import com.atsuishio.superbwarfare.perk.Perk;
import com.atsuishio.superbwarfare.perk.PerkHelper;
import com.atsuishio.superbwarfare.tools.InventoryTool;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.client.Minecraft;
@ -155,24 +156,18 @@ public class SecondaryCataclysm extends GunItem implements GeoItem, SpecialFireW
}
public static int getAmmoCount(Player player) {
int count = 0;
for (var inv : player.getInventory().items) {
if (inv.is(ModItems.CREATIVE_AMMO_BOX.get())) {
count++;
}
if (InventoryTool.hasCreativeAmmoBox(player)) {
return (int) Double.POSITIVE_INFINITY;
}
if (count == 0) {
int sum = 0;
for (int i = 0; i < player.getInventory().getContainerSize(); ++i) {
ItemStack itemstack = player.getInventory().getItem(i);
if (check(itemstack)) {
sum += itemstack.getCount();
}
int sum = 0;
for (int i = 0; i < player.getInventory().getContainerSize(); ++i) {
ItemStack itemstack = player.getInventory().getItem(i);
if (check(itemstack)) {
sum += itemstack.getCount();
}
return sum;
}
return (int) Double.POSITIVE_INFINITY;
return sum;
}
@Override
@ -264,7 +259,7 @@ public class SecondaryCataclysm extends GunItem implements GeoItem, SpecialFireW
}
@Override
public String getAmmoDisplayName(ItemStack stack) {
public String getAmmoDisplayName(GunData data) {
return "40mm Grenade";
}
@ -347,8 +342,4 @@ public class SecondaryCataclysm extends GunItem implements GeoItem, SpecialFireW
return 24000;
}
@Override
public Item getCustomAmmoItem() {
return ModItems.GRENADE_40MM.get();
}
}

View file

@ -124,6 +124,7 @@ public class BocekItem extends GunItem implements GeoItem, SpecialFireWeapon {
}
}
// TODO 替换硬编码判断
protected static boolean check(ItemStack stack) {
return stack.getItem() == Items.ARROW;
}
@ -158,7 +159,7 @@ public class BocekItem extends GunItem implements GeoItem, SpecialFireWeapon {
}
@Override
public String getAmmoDisplayName(ItemStack stack) {
public String getAmmoDisplayName(GunData data) {
return "Arrow";
}

View file

@ -213,7 +213,7 @@ public class TaserItem extends GunItem implements GeoItem, SpecialFireWeapon, En
}
@Override
public String getAmmoDisplayName(ItemStack stack) {
public String getAmmoDisplayName(GunData data) {
return "Electrode Rod";
}
@ -264,8 +264,4 @@ public class TaserItem extends GunItem implements GeoItem, SpecialFireWeapon, En
return MAX_ENERGY;
}
@Override
public Item getCustomAmmoItem() {
return ModItems.TASER_ELECTRODE.get();
}
}

View file

@ -3,9 +3,9 @@ package com.atsuishio.superbwarfare.network.message.send;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.init.ModAttachments;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModTags;
import com.atsuishio.superbwarfare.item.gun.GunItem;
import com.atsuishio.superbwarfare.item.gun.data.GunData;
import com.atsuishio.superbwarfare.tools.AmmoType;
import io.netty.buffer.ByteBuf;
import net.minecraft.network.codec.ByteBufCodecs;
import net.minecraft.network.codec.StreamCodec;
@ -54,19 +54,17 @@ public record ReloadMessage(int msgType) implements CustomPacketPayload {
boolean hasCreativeAmmoBox = player.getInventory().hasAnyMatching(item -> item.is(ModItems.CREATIVE_AMMO_BOX.get()));
if (!hasCreativeAmmoBox) {
if (stack.is(ModTags.Items.USE_SHOTGUN_AMMO) && cap.shotgunAmmo == 0) {
return;
} else if (stack.is(ModTags.Items.USE_SNIPER_AMMO) && cap.sniperAmmo == 0) {
return;
} else if (stack.is(ModTags.Items.USE_HANDGUN_AMMO) && cap.handgunAmmo == 0) {
return;
} else if (stack.is(ModTags.Items.USE_RIFLE_AMMO) && cap.rifleAmmo == 0) {
return;
} else if (stack.is(ModTags.Items.USE_HEAVY_AMMO) && cap.heavyAmmo == 0) {
return;
} else if (stack.getItem() == ModItems.TASER.get() && data.maxAmmo.get() == 0) {
return;
} else if (stack.is(ModTags.Items.LAUNCHER) && data.maxAmmo.get() == 0) {
var ammoTypeInfo = data.ammoTypeInfo();
if (ammoTypeInfo.type() == GunData.AmmoConsumeType.PLAYER_AMMO) {
var ammoType = AmmoType.getType(ammoTypeInfo.value());
assert ammoType != null;
if (ammoType.get(cap) == 0) return;
} else if ((ammoTypeInfo.type() == GunData.AmmoConsumeType.ITEM || ammoTypeInfo.type() == GunData.AmmoConsumeType.TAG)
// TODO 弃用maxAmmo
&& data.maxAmmo.get() == 0
) {
return;
}
}

View file

@ -13,5 +13,6 @@
"EmptyReloadTime": 85,
"BypassesArmor": 0.05,
"SoundRadius": 18,
"RPM": 360
"RPM": 360,
"AmmoType": "@ShotgunAmmo"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 58,
"BypassesArmor": 0.23,
"SoundRadius": 12,
"RPM": 700
"RPM": 700,
"AmmoType": "@RifleAmmo"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 65,
"BypassesArmor": 0.2,
"SoundRadius": 14,
"RPM": 600
"RPM": 600,
"AmmoType": "@RifleAmmo"
}

View file

@ -4,5 +4,6 @@
"Headshot": 2.5,
"Damage": 48,
"Weight": 3,
"BypassesArmor": 0.25
"BypassesArmor": 0.25,
"AmmoType": "minecraft:arrow"
}

View file

@ -13,5 +13,6 @@
"EmptyReloadTime": 95,
"BypassesArmor": 0.25,
"SoundRadius": 13,
"RPM": 400
"RPM": 400,
"AmmoType": "@RifleAmmo"
}

View file

@ -11,5 +11,6 @@
"EmptyReloadTime": 47,
"BypassesArmor": 0.15,
"SoundRadius": 8,
"RPM": 400
"RPM": 400,
"AmmoType": "@HandgunAmmo"
}

View file

@ -12,5 +12,6 @@
"EmptyReloadTime": 47,
"BypassesArmor": 0.15,
"SoundRadius": 8,
"RPM": 1300
"RPM": 1300,
"AmmoType": "@HandgunAmmo"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 64,
"BypassesArmor": 0.25,
"SoundRadius": 14,
"RPM": 900
"RPM": 900,
"AmmoType": "@RifleAmmo"
}

View file

@ -12,5 +12,6 @@
"EmptyReloadTime": 83,
"BypassesArmor": 0.01,
"SoundRadius": 16,
"RPM": 600
"RPM": 600,
"AmmoType": "@ShotgunAmmo"
}

View file

@ -9,5 +9,6 @@
"Weight": 5,
"EmptyReloadTime": 64,
"BypassesArmor": 0.7,
"SoundRadius": 20
"SoundRadius": 20,
"AmmoType": "@SniperAmmo"
}

View file

@ -12,5 +12,6 @@
"EmptyReloadTime": 56,
"BypassesArmor": 0.4,
"SoundRadius": 12,
"RPM": 900
"RPM": 900,
"AmmoType": "@RifleAmmo"
}

View file

@ -6,5 +6,6 @@
"EmptyReloadTime": 78,
"Damage": 700,
"ExplosionDamage": 60,
"ExplosionRadius": 5
"ExplosionRadius": 5,
"AmmoType": "superbwarfare:javelin_missile"
}

View file

@ -14,5 +14,6 @@
"IterativeTime": 11,
"FinishTime": 18,
"BypassesArmor": 0.5,
"SoundRadius": 18
"SoundRadius": 18,
"AmmoType": "@SniperAmmo"
}

View file

@ -11,5 +11,6 @@
"EmptyReloadTime": 47,
"BypassesArmor": 0.2,
"SoundRadius": 10,
"RPM": 400
"RPM": 400,
"AmmoType": "@HandgunAmmo"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 64,
"BypassesArmor": 0.25,
"SoundRadius": 14,
"RPM": 850
"RPM": 850,
"AmmoType": "@RifleAmmo"
}

View file

@ -12,5 +12,6 @@
"EmptyReloadTime": 133,
"BypassesArmor": 0.25,
"SoundRadius": 15,
"RPM": 600
"RPM": 600,
"AmmoType": "@RifleAmmo"
}

View file

@ -8,5 +8,6 @@
"Velocity": 3.75,
"Magazine": 1,
"Weight": 4,
"EmptyReloadTime": 64
"EmptyReloadTime": 64,
"AmmoType": "superbwarfare:grenade_40mm"
}

View file

@ -14,5 +14,6 @@
"FinishTime": 12,
"BypassesArmor": 0.05,
"SoundRadius": 16,
"BoltActionTime": 11
"BoltActionTime": 11,
"AmmoType": "@ShotgunAmmo"
}

View file

@ -14,5 +14,6 @@
"NormalReloadTime": 60,
"EmptyReloadTime": 78,
"BypassesArmor": 0.6,
"SoundRadius": 18
"SoundRadius": 18,
"AmmoType": "@SniperAmmo"
}

View file

@ -12,5 +12,6 @@
"FinishTime": 19,
"BypassesArmor": 0.3,
"SoundRadius": 15,
"BoltActionTime": 12
"BoltActionTime": 12,
"AmmoType": "@RifleAmmo"
}

View file

@ -8,5 +8,6 @@
"Weight": 10,
"BypassesArmor": 0.3,
"SoundRadius": 14,
"RPM": 1200
"RPM": 1200,
"AmmoType": "@RifleAmmo"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 71,
"BypassesArmor": 0.4,
"SoundRadius": 16,
"RPM": 700
"RPM": 700,
"AmmoType": "@RifleAmmo"
}

View file

@ -14,5 +14,6 @@
"IterativeTime": 11,
"FinishTime": 18,
"BypassesArmor": 0.54,
"SoundRadius": 18
"SoundRadius": 18,
"AmmoType": "@SniperAmmo"
}

View file

@ -11,5 +11,6 @@
"EmptyReloadTime": 47,
"BypassesArmor": 0.15,
"SoundRadius": 8,
"RPM": 400
"RPM": 400,
"AmmoType": "@HandgunAmmo"
}

View file

@ -13,5 +13,6 @@
"NormalReloadTime": 84,
"EmptyReloadTime": 112,
"BypassesArmor": 1,
"SoundRadius": 22
"SoundRadius": 22,
"AmmoType": "@HeavyAmmo"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 74,
"BypassesArmor": 0.28,
"SoundRadius": 13,
"RPM": 650
"RPM": 650,
"AmmoType": "@RifleAmmo"
}

View file

@ -8,5 +8,6 @@
"Velocity": 4,
"Magazine": 1,
"Weight": 7,
"EmptyReloadTime": 103
"EmptyReloadTime": 103,
"AmmoType": "superbwarfare:rocket"
}

View file

@ -14,5 +14,6 @@
"EmptyReloadTime": 65,
"BypassesArmor": 0.23,
"SoundRadius": 14,
"RPM": 600
"RPM": 600,
"AmmoType": "@RifleAmmo"
}

View file

@ -11,5 +11,6 @@
"PrepareLoadTime": 31,
"IterativeTime": 20,
"FinishTime": 19,
"SoundRadius": 8
"SoundRadius": 8,
"AmmoType": "superbwarfare:grenade_40mm"
}

View file

@ -12,5 +12,6 @@
"NormalReloadTime": 59,
"EmptyReloadTime": 89,
"BypassesArmor": 0.8,
"SoundRadius": 20
"SoundRadius": 20,
"AmmoType": "@SniperAmmo"
}

View file

@ -11,5 +11,6 @@
"EmptyReloadTime": 75,
"BypassesArmor": 0.23,
"SoundRadius": 16,
"RPM": 400
"RPM": 400,
"AmmoType": "@RifleAmmo"
}

View file

@ -13,5 +13,6 @@
"EmptyReloadTime": 78,
"BypassesArmor": 0.45,
"SoundRadius": 17,
"RPM": 300
"RPM": 300,
"AmmoType": "@SniperAmmo"
}

View file

@ -6,5 +6,6 @@
"Velocity": 3,
"Magazine": 1,
"Weight": 1,
"EmptyReloadTime": 58
"EmptyReloadTime": 58,
"AmmoType": "superbwarfare:taser_electrode"
}

View file

@ -10,5 +10,6 @@
"EmptyReloadTime": 65,
"BypassesArmor": 0.3,
"SoundRadius": 10,
"RPM": 240
"RPM": 240,
"AmmoType": "@RifleAmmo"
}

View file

@ -13,5 +13,6 @@
"EmptyReloadTime": 64,
"BypassesArmor": 0.15,
"SoundRadius": 11,
"RPM": 1200
"RPM": 1200,
"AmmoType": "@HandgunAmmo"
}