正确实现弹药盒掉落逻辑,修复弹药盒数据同步问题
This commit is contained in:
parent
24479e203f
commit
ddf078b41b
5 changed files with 82 additions and 58 deletions
|
@ -3,6 +3,7 @@ package com.atsuishio.superbwarfare.client.overlay;
|
||||||
import com.atsuishio.superbwarfare.Mod;
|
import com.atsuishio.superbwarfare.Mod;
|
||||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||||
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
import com.atsuishio.superbwarfare.config.client.DisplayConfig;
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.ArmedVehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.init.ModItems;
|
import com.atsuishio.superbwarfare.init.ModItems;
|
||||||
|
@ -290,8 +291,9 @@ public class AmmoBarOverlay {
|
||||||
boolean boxAmmoSelected = false;
|
boolean boxAmmoSelected = false;
|
||||||
|
|
||||||
if (isAmmoBox) {
|
if (isAmmoBox) {
|
||||||
var tag = NBTTool.getTag(stack);
|
var data = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
||||||
var ammoBoxType = tag.getString("Type");
|
var ammoBoxType = data == null ? "All" : data.type();
|
||||||
|
|
||||||
boxAmmoCount = type.get(stack);
|
boxAmmoCount = type.get(stack);
|
||||||
if (ammoBoxType.equals("All") || ammoBoxType.equals(type.name)) {
|
if (ammoBoxType.equals("All") || ammoBoxType.equals(type.name)) {
|
||||||
boxAnimator.forward(currentTime);
|
boxAnimator.forward(currentTime);
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class ModDataComponents {
|
||||||
);
|
);
|
||||||
|
|
||||||
public static final DeferredHolder<DataComponentType<?>, DataComponentType<AmmoBoxInfo>> AMMO_BOX_INFO = register(
|
public static final DeferredHolder<DataComponentType<?>, DataComponentType<AmmoBoxInfo>> AMMO_BOX_INFO = register(
|
||||||
"ammo_box_type",
|
"ammo_box_info",
|
||||||
builder -> builder.persistent(AmmoBoxInfo.CODEC)
|
builder -> builder.persistent(AmmoBoxInfo.CODEC)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.event;
|
||||||
|
|
||||||
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
import com.atsuishio.superbwarfare.capability.ModCapabilities;
|
||||||
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
import com.atsuishio.superbwarfare.capability.player.PlayerVariable;
|
||||||
|
import com.atsuishio.superbwarfare.component.ModDataComponents;
|
||||||
import com.atsuishio.superbwarfare.config.common.GameplayConfig;
|
import com.atsuishio.superbwarfare.config.common.GameplayConfig;
|
||||||
import com.atsuishio.superbwarfare.config.server.MiscConfig;
|
import com.atsuishio.superbwarfare.config.server.MiscConfig;
|
||||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||||
|
@ -14,6 +15,7 @@ import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEnt
|
||||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||||
import com.atsuishio.superbwarfare.event.events.PreKillEvent;
|
import com.atsuishio.superbwarfare.event.events.PreKillEvent;
|
||||||
import com.atsuishio.superbwarfare.init.*;
|
import com.atsuishio.superbwarfare.init.*;
|
||||||
|
import com.atsuishio.superbwarfare.item.common.ammo.box.AmmoBoxInfo;
|
||||||
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
import com.atsuishio.superbwarfare.item.gun.GunItem;
|
||||||
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
import com.atsuishio.superbwarfare.item.gun.data.GunData;
|
||||||
import com.atsuishio.superbwarfare.item.gun.data.ReloadState;
|
import com.atsuishio.superbwarfare.item.gun.data.ReloadState;
|
||||||
|
@ -24,7 +26,6 @@ import com.atsuishio.superbwarfare.perk.AmmoPerk;
|
||||||
import com.atsuishio.superbwarfare.perk.Perk;
|
import com.atsuishio.superbwarfare.perk.Perk;
|
||||||
import com.atsuishio.superbwarfare.perk.PerkHelper;
|
import com.atsuishio.superbwarfare.perk.PerkHelper;
|
||||||
import com.atsuishio.superbwarfare.tools.*;
|
import com.atsuishio.superbwarfare.tools.*;
|
||||||
import net.minecraft.nbt.CompoundTag;
|
|
||||||
import net.minecraft.network.chat.Component;
|
import net.minecraft.network.chat.Component;
|
||||||
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
|
import net.minecraft.network.protocol.game.ClientboundStopSoundPacket;
|
||||||
import net.minecraft.resources.ResourceKey;
|
import net.minecraft.resources.ResourceKey;
|
||||||
|
@ -51,6 +52,7 @@ import net.neoforged.neoforge.event.entity.living.*;
|
||||||
import net.neoforged.neoforge.event.entity.player.ItemEntityPickupEvent;
|
import net.neoforged.neoforge.event.entity.player.ItemEntityPickupEvent;
|
||||||
import net.neoforged.neoforge.network.PacketDistributor;
|
import net.neoforged.neoforge.network.PacketDistributor;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@EventBusSubscriber
|
@EventBusSubscriber
|
||||||
|
@ -91,7 +93,6 @@ public class LivingEventHandler {
|
||||||
killIndication(event);
|
killIndication(event);
|
||||||
handleGunPerksWhenDeath(event);
|
handleGunPerksWhenDeath(event);
|
||||||
handlePlayerKillEntity(event);
|
handlePlayerKillEntity(event);
|
||||||
handlePlayerDeathDropAmmo(event.getEntity());
|
|
||||||
giveKillExpToWeapon(event);
|
giveKillExpToWeapon(event);
|
||||||
|
|
||||||
if (event.getEntity() instanceof Player player) {
|
if (event.getEntity() instanceof Player player) {
|
||||||
|
@ -737,37 +738,6 @@ public class LivingEventHandler {
|
||||||
data.save();
|
data.save();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 开启死亡掉落时掉落一个弹药盒
|
|
||||||
*/
|
|
||||||
private static void handlePlayerDeathDropAmmo(LivingEntity entity) {
|
|
||||||
if (!entity.level().getLevelData().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY) && entity instanceof Player player) {
|
|
||||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
|
||||||
if (cap == null) cap = new PlayerVariable();
|
|
||||||
|
|
||||||
boolean drop = cap.rifleAmmo + cap.handgunAmmo + cap.shotgunAmmo + cap.sniperAmmo + cap.heavyAmmo > 0;
|
|
||||||
|
|
||||||
if (drop) {
|
|
||||||
ItemStack stack = new ItemStack(ModItems.AMMO_BOX.get());
|
|
||||||
CompoundTag tag = NBTTool.getTag(stack);
|
|
||||||
|
|
||||||
for (var type : AmmoType.values()) {
|
|
||||||
type.set(tag, type.get(cap));
|
|
||||||
type.set(cap, 0);
|
|
||||||
}
|
|
||||||
tag.putBoolean("IsDrop", true);
|
|
||||||
NBTTool.saveTag(stack, tag);
|
|
||||||
cap.syncPlayerVariables(player);
|
|
||||||
|
|
||||||
if (player.level() instanceof ServerLevel level) {
|
|
||||||
ItemEntity itemEntity = new ItemEntity(level, player.getX(), player.getY() + 1, player.getZ(), stack);
|
|
||||||
itemEntity.setPickUpDelay(10);
|
|
||||||
level.addFreshEntity(itemEntity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onPickup(ItemEntityPickupEvent.Pre event) {
|
public static void onPickup(ItemEntityPickupEvent.Pre event) {
|
||||||
if (!VehicleConfig.VEHICLE_ITEM_PICKUP.get()) return;
|
if (!VehicleConfig.VEHICLE_ITEM_PICKUP.get()) return;
|
||||||
|
@ -782,26 +752,58 @@ public class LivingEventHandler {
|
||||||
|
|
||||||
@SubscribeEvent
|
@SubscribeEvent
|
||||||
public static void onLivingDrops(LivingDropsEvent event) {
|
public static void onLivingDrops(LivingDropsEvent event) {
|
||||||
|
// 死亡掉落弹药盒
|
||||||
|
if (event.getEntity() instanceof Player player && !player.level().getLevelData().getGameRules().getBoolean(GameRules.RULE_KEEPINVENTORY)) {
|
||||||
|
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE);
|
||||||
|
if (cap == null) cap = new PlayerVariable();
|
||||||
|
|
||||||
|
boolean drop = cap.rifleAmmo + cap.handgunAmmo + cap.shotgunAmmo + cap.sniperAmmo + cap.heavyAmmo > 0;
|
||||||
|
|
||||||
|
if (drop) {
|
||||||
|
var stack = new ItemStack(ModItems.AMMO_BOX.get());
|
||||||
|
|
||||||
|
for (var type : AmmoType.values()) {
|
||||||
|
type.set(stack, type.get(cap));
|
||||||
|
type.set(cap, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = new AmmoBoxInfo("All", true);
|
||||||
|
stack.set(ModDataComponents.AMMO_BOX_INFO, info);
|
||||||
|
|
||||||
|
cap.syncPlayerVariables(player);
|
||||||
|
|
||||||
|
event.getDrops().add(new ItemEntity(player.level(), player.getX(), player.getY() + 1, player.getZ(), stack));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
DamageSource source = event.getSource();
|
DamageSource source = event.getSource();
|
||||||
Entity sourceEntity = source.getEntity();
|
Entity sourceEntity = source.getEntity();
|
||||||
if (!(sourceEntity instanceof Player player)) return;
|
if (!(sourceEntity instanceof Player player)) return;
|
||||||
ItemStack stack = player.getMainHandItem();
|
ItemStack mainHandItem = player.getMainHandItem();
|
||||||
|
|
||||||
|
// 创生物收集掉落物
|
||||||
if (player.getVehicle() instanceof ContainerMobileVehicleEntity containerMobileVehicleEntity && source.is(ModDamageTypes.VEHICLE_STRIKE)) {
|
if (player.getVehicle() instanceof ContainerMobileVehicleEntity containerMobileVehicleEntity && source.is(ModDamageTypes.VEHICLE_STRIKE)) {
|
||||||
var drops = event.getDrops();
|
var drops = event.getDrops();
|
||||||
|
var removed = new ArrayList<ItemEntity>();
|
||||||
|
|
||||||
drops.forEach(itemEntity -> {
|
drops.forEach(itemEntity -> {
|
||||||
ItemStack item = itemEntity.getItem();
|
ItemStack stack = itemEntity.getItem();
|
||||||
if (!HopperBlockEntity.addItem(containerMobileVehicleEntity, itemEntity)) {
|
|
||||||
player.drop(item, false);
|
InventoryTool.insertItem(containerMobileVehicleEntity.getItemStacks(), stack);
|
||||||
|
|
||||||
|
if (stack.getCount() <= 0) {
|
||||||
|
player.drop(stack, false);
|
||||||
|
removed.add(itemEntity);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
event.setCanceled(true);
|
|
||||||
|
drops.removeAll(removed);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 磁吸Perk
|
||||||
final var tag = NBTTool.getTag(stack);
|
final var mainHandTag = NBTTool.getTag(mainHandItem);
|
||||||
if (stack.is(ModTags.Items.GUN) && PerkHelper.getItemPerkLevel(ModPerks.POWERFUL_ATTRACTION.get(), tag) > 0 && (DamageTypeTool.isGunDamage(source) || DamageTypeTool.isExplosionDamage(source))) {
|
if (mainHandItem.is(ModTags.Items.GUN) && PerkHelper.getItemPerkLevel(ModPerks.POWERFUL_ATTRACTION.get(), mainHandTag) > 0 && (DamageTypeTool.isGunDamage(source) || DamageTypeTool.isExplosionDamage(source))) {
|
||||||
var drops = event.getDrops();
|
var drops = event.getDrops();
|
||||||
drops.forEach(itemEntity -> {
|
drops.forEach(itemEntity -> {
|
||||||
ItemStack item = itemEntity.getItem();
|
ItemStack item = itemEntity.getItem();
|
||||||
|
|
|
@ -37,32 +37,30 @@ public class AmmoBox extends Item {
|
||||||
if (hand == InteractionHand.OFF_HAND) return InteractionResultHolder.fail(stack);
|
if (hand == InteractionHand.OFF_HAND) return InteractionResultHolder.fail(stack);
|
||||||
|
|
||||||
player.getCooldowns().addCooldown(this, 10);
|
player.getCooldowns().addCooldown(this, 10);
|
||||||
|
|
||||||
var info = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
var info = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
||||||
if (info == null) info = new AmmoBoxInfo("All", false);
|
if (info == null) info = new AmmoBoxInfo("All", false);
|
||||||
String type = info.type();
|
String selectedType = info.type();
|
||||||
|
|
||||||
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE, null);
|
var cap = player.getCapability(ModCapabilities.PLAYER_VARIABLE, null);
|
||||||
if (cap != null) {
|
if (cap != null && !level.isClientSide()) {
|
||||||
var types = type.equals("All") ? AmmoType.values() : new AmmoType[]{AmmoType.getType(type)};
|
var types = selectedType.equals("All") ? AmmoType.values() : new AmmoType[]{AmmoType.getType(selectedType)};
|
||||||
|
|
||||||
for (var ammoType : types) {
|
for (var type : types) {
|
||||||
if (ammoType == null) continue;
|
if (type == null) continue;
|
||||||
|
|
||||||
if (player.isCrouching()) {
|
if (player.isCrouching()) {
|
||||||
// 存入弹药
|
// 存入弹药
|
||||||
ammoType.add(stack, ammoType.get(cap));
|
type.add(stack, type.get(cap));
|
||||||
ammoType.set(cap, 0);
|
type.set(cap, 0);
|
||||||
} else {
|
} else {
|
||||||
// 取出弹药
|
// 取出弹药
|
||||||
ammoType.add(cap, ammoType.get(stack));
|
type.add(cap, type.get(stack));
|
||||||
ammoType.set(stack, 0);
|
type.set(stack, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cap.syncPlayerVariables(player);
|
cap.syncPlayerVariables(player);
|
||||||
|
|
||||||
if (!level.isClientSide()) {
|
|
||||||
level.playSound(null, player.blockPosition(), SoundEvents.ARROW_HIT_PLAYER, SoundSource.PLAYERS, 1, 1);
|
level.playSound(null, player.blockPosition(), SoundEvents.ARROW_HIT_PLAYER, SoundSource.PLAYERS, 1, 1);
|
||||||
}
|
|
||||||
|
|
||||||
// 取出弹药时,若弹药盒为掉落物版本,则移除弹药盒物品
|
// 取出弹药时,若弹药盒为掉落物版本,则移除弹药盒物品
|
||||||
if (!player.isCrouching() && info.isDrop()) {
|
if (!player.isCrouching() && info.isDrop()) {
|
||||||
|
@ -122,7 +120,7 @@ public class AmmoBox extends Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void appendHoverText(ItemStack stack, @NotNull TooltipContext context, List<Component> tooltipComponents, @NotNull TooltipFlag tooltipFlag) {
|
public void appendHoverText(ItemStack stack, @NotNull TooltipContext context, @NotNull List<Component> tooltipComponents, @NotNull TooltipFlag tooltipFlag) {
|
||||||
var info = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
var info = stack.get(ModDataComponents.AMMO_BOX_INFO);
|
||||||
if (info == null) info = new AmmoBoxInfo("All", false);
|
if (info == null) info = new AmmoBoxInfo("All", false);
|
||||||
var type = AmmoType.getType(info.type());
|
var type = AmmoType.getType(info.type());
|
||||||
|
|
|
@ -119,4 +119,26 @@ public class InventoryTool {
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int insertItem(NonNullList<ItemStack> itemList, ItemStack stack) {
|
||||||
|
var maxStackSize = stack.getItem().getMaxStackSize(stack);
|
||||||
|
var originalCount = stack.getCount();
|
||||||
|
|
||||||
|
for (int i = 0; i < itemList.size(); i++) {
|
||||||
|
var currentStack = itemList.get(i);
|
||||||
|
|
||||||
|
if (ItemStack.isSameItemSameComponents(stack, currentStack) && currentStack.getCount() < maxStackSize) {
|
||||||
|
var countToAdd = Math.min(maxStackSize - currentStack.getCount(), stack.getCount());
|
||||||
|
currentStack.grow(countToAdd);
|
||||||
|
stack.setCount(stack.getCount() - countToAdd);
|
||||||
|
} else if (currentStack.isEmpty()) {
|
||||||
|
itemList.set(i, stack);
|
||||||
|
return stack.getCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stack.getCount() <= 0) break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return originalCount - stack.getCount();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue