From 76456c5a937900d5674b71e66f23f1e8818d3a74 Mon Sep 17 00:00:00 2001 From: Light_Quanta Date: Wed, 19 Feb 2025 14:23:19 +0800 Subject: [PATCH] =?UTF-8?q?=E6=AD=A3=E7=A1=AE=E5=AE=9E=E7=8E=B0=E5=AE=9E?= =?UTF-8?q?=E4=BD=93=E8=83=BD=E9=87=8F=E5=AD=98=E5=82=A8=E8=83=BD=E5=8A=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../energy/SyncedEntityEnergyStorage.java | 64 +++++++++++++++++++ .../compat/jade/SbwJadePlugin.java | 5 +- .../jade/providers/VehicleEnergyProvider.java | 49 -------------- .../entity/vehicle/AnnihilatorEntity.java | 2 +- .../entity/vehicle/EnergyVehicleEntity.java | 39 +++++++++-- .../entity/vehicle/LaserTowerEntity.java | 5 +- 6 files changed, 103 insertions(+), 61 deletions(-) create mode 100644 src/main/java/com/atsuishio/superbwarfare/capability/energy/SyncedEntityEnergyStorage.java delete mode 100644 src/main/java/com/atsuishio/superbwarfare/compat/jade/providers/VehicleEnergyProvider.java diff --git a/src/main/java/com/atsuishio/superbwarfare/capability/energy/SyncedEntityEnergyStorage.java b/src/main/java/com/atsuishio/superbwarfare/capability/energy/SyncedEntityEnergyStorage.java new file mode 100644 index 000000000..f82a82e30 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/capability/energy/SyncedEntityEnergyStorage.java @@ -0,0 +1,64 @@ +package com.atsuishio.superbwarfare.capability.energy; + +import net.minecraft.nbt.Tag; +import net.minecraft.network.syncher.EntityDataAccessor; +import net.minecraft.network.syncher.SynchedEntityData; +import net.minecraftforge.energy.EnergyStorage; + +/** + * 自动同步的实体能量存储能力,会和客户端自动同步实体的当前能量值 + */ +public class SyncedEntityEnergyStorage extends EnergyStorage { + + protected SynchedEntityData entityData; + protected EntityDataAccessor energyDataAccessor; + + /** + * 自动同步的实体能量存储能力 + * + * @param capacity 能量上限 + * @param data 实体的entityData + * @param energyDataAccessor 能量的EntityDataAccessor + */ + public SyncedEntityEnergyStorage(int capacity, SynchedEntityData data, EntityDataAccessor energyDataAccessor) { + super(capacity, capacity, capacity, 0); + + this.entityData = data; + this.energyDataAccessor = energyDataAccessor; + } + + @Override + public int receiveEnergy(int maxReceive, boolean simulate) { + var received = super.receiveEnergy(maxReceive, simulate); + + if (!simulate) { + entityData.set(energyDataAccessor, this.energy); + } + + return received; + } + + @Override + public int extractEnergy(int maxExtract, boolean simulate) { + var extracted = super.extractEnergy(maxExtract, simulate); + + if (!simulate) { + entityData.set(energyDataAccessor, energy); + } + + return extracted; + } + + @Override + public int getEnergyStored() { + // 获取同步数据,保证客户端能正确获得能量值 + return entityData.get(energyDataAccessor); + } + + @Override + public void deserializeNBT(Tag nbt) { + super.deserializeNBT(nbt); + entityData.set(energyDataAccessor, energy); + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/compat/jade/SbwJadePlugin.java b/src/main/java/com/atsuishio/superbwarfare/compat/jade/SbwJadePlugin.java index 6c82efbf7..39750813b 100644 --- a/src/main/java/com/atsuishio/superbwarfare/compat/jade/SbwJadePlugin.java +++ b/src/main/java/com/atsuishio/superbwarfare/compat/jade/SbwJadePlugin.java @@ -1,8 +1,6 @@ package com.atsuishio.superbwarfare.compat.jade; -import com.atsuishio.superbwarfare.compat.jade.providers.VehicleEnergyProvider; import com.atsuishio.superbwarfare.compat.jade.providers.VehicleHealthProvider; -import com.atsuishio.superbwarfare.entity.vehicle.EnergyVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.VehicleEntity; import snownee.jade.api.IWailaClientRegistration; import snownee.jade.api.IWailaCommonRegistration; @@ -14,12 +12,11 @@ public class SbwJadePlugin implements IWailaPlugin { @Override public void register(IWailaCommonRegistration registration) { - registration.registerEntityDataProvider(VehicleEnergyProvider.INSTANCE, EnergyVehicleEntity.class); + } @Override public void registerClient(IWailaClientRegistration registration) { registration.registerEntityComponent(VehicleHealthProvider.INSTANCE, VehicleEntity.class); - registration.registerEntityComponent(VehicleEnergyProvider.INSTANCE, EnergyVehicleEntity.class); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/compat/jade/providers/VehicleEnergyProvider.java b/src/main/java/com/atsuishio/superbwarfare/compat/jade/providers/VehicleEnergyProvider.java deleted file mode 100644 index c2eebd4dc..000000000 --- a/src/main/java/com/atsuishio/superbwarfare/compat/jade/providers/VehicleEnergyProvider.java +++ /dev/null @@ -1,49 +0,0 @@ -package com.atsuishio.superbwarfare.compat.jade.providers; - -import com.atsuishio.superbwarfare.ModUtils; -import com.atsuishio.superbwarfare.entity.vehicle.EnergyVehicleEntity; -import net.minecraft.nbt.CompoundTag; -import net.minecraft.network.chat.Component; -import net.minecraft.resources.ResourceLocation; -import snownee.jade.api.EntityAccessor; -import snownee.jade.api.IEntityComponentProvider; -import snownee.jade.api.IServerDataProvider; -import snownee.jade.api.ITooltip; -import snownee.jade.api.config.IPluginConfig; - -public enum VehicleEnergyProvider implements IEntityComponentProvider, - IServerDataProvider { - INSTANCE; - - private static final ResourceLocation ID = ModUtils.loc("vehicle_energy"); - - @Override - public void appendTooltip( - ITooltip tooltip, - EntityAccessor accessor, - IPluginConfig config - ) { - // TODO 正确实现能量显示 - if (!accessor.getServerData().contains("Energy")) return; - - tooltip.add( - Component.translatable( - accessor.getServerData().getInt("Energy") - + " / " - + accessor.getServerData().getInt("MaxEnergy") - ) - ); - } - - @Override - public void appendServerData(CompoundTag data, EntityAccessor accessor) { - var vehicle = (EnergyVehicleEntity) accessor.getEntity(); - data.putInt("Energy", vehicle.getEnergy()); - data.putInt("MaxEnergy", vehicle.getMaxEnergy()); - } - - @Override - public ResourceLocation getUid() { - return ID; - } -} \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java index e31874527..5c9d23f26 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/AnnihilatorEntity.java @@ -469,7 +469,7 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity, } public void autoAim() { - if (this.entityData.get(ENERGY) <= 0) return; + if (this.getEnergy() <= 0) return; Entity target = SeekTool.seekLivingEntity(this, this.level(), 64, 30); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/EnergyVehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/EnergyVehicleEntity.java index 214d0bd70..307698747 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/EnergyVehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/EnergyVehicleEntity.java @@ -1,18 +1,28 @@ package com.atsuishio.superbwarfare.entity.vehicle; +import com.atsuishio.superbwarfare.capability.energy.SyncedEntityEnergyStorage; import net.minecraft.nbt.CompoundTag; +import net.minecraft.nbt.IntTag; import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.util.Mth; import net.minecraft.world.entity.EntityType; import net.minecraft.world.level.Level; +import net.minecraftforge.common.capabilities.Capability; +import net.minecraftforge.common.capabilities.ForgeCapabilities; +import net.minecraftforge.common.util.LazyOptional; +import net.minecraftforge.energy.IEnergyStorage; +import org.jetbrains.annotations.NotNull; import org.joml.Math; public class EnergyVehicleEntity extends VehicleEntity implements IChargeEntity { public static final EntityDataAccessor ENERGY = SynchedEntityData.defineId(EnergyVehicleEntity.class, EntityDataSerializers.INT); + protected final SyncedEntityEnergyStorage energyStorage = new SyncedEntityEnergyStorage(this.getMaxEnergy(), this.entityData, ENERGY); + protected final LazyOptional energy = LazyOptional.of(() -> energyStorage); + public EnergyVehicleEntity(EntityType pEntityType, Level pLevel) { super(pEntityType, pLevel); this.setEnergy(0); @@ -27,13 +37,21 @@ public class EnergyVehicleEntity extends VehicleEntity implements IChargeEntity @Override protected void readAdditionalSaveData(CompoundTag compound) { super.readAdditionalSaveData(compound); - this.entityData.set(ENERGY, compound.getInt("Energy")); + if (compound.get("Energy") instanceof IntTag energyNBT) { + energyStorage.deserializeNBT(energyNBT); + } + } + + @Override + public void invalidateCaps() { + super.invalidateCaps(); + energy.invalidate(); } @Override public void addAdditionalSaveData(CompoundTag compound) { super.addAdditionalSaveData(compound); - compound.putInt("Energy", this.entityData.get(ENERGY)); + compound.put("Energy", energyStorage.serializeNBT()); } /** @@ -42,7 +60,7 @@ public class EnergyVehicleEntity extends VehicleEntity implements IChargeEntity * @param amount 要消耗的电量 */ public void consumeEnergy(int amount) { - this.setEnergy(Math.max(0, this.getEnergy() - amount)); + this.energyStorage.extractEnergy(amount, false); } public boolean canConsume(int amount) { @@ -50,11 +68,17 @@ public class EnergyVehicleEntity extends VehicleEntity implements IChargeEntity } public int getEnergy() { - return this.entityData.get(ENERGY); + return this.energyStorage.getEnergyStored(); } public void setEnergy(int pEnergy) { - this.entityData.set(ENERGY, Mth.clamp(pEnergy, 0, this.getMaxEnergy())); + int targetEnergy = Mth.clamp(pEnergy, 0, this.getMaxEnergy()); + + if (targetEnergy > energyStorage.getEnergyStored()) { + energyStorage.receiveEnergy(targetEnergy - energyStorage.getEnergyStored(), false); + } else { + energyStorage.extractEnergy(energyStorage.getEnergyStored() - targetEnergy, false); + } } public int getMaxEnergy() { @@ -72,4 +96,9 @@ public class EnergyVehicleEntity extends VehicleEntity implements IChargeEntity public boolean canCharge() { return this.getEnergy() < this.getMaxEnergy(); } + + @Override + public @NotNull LazyOptional getCapability(@NotNull Capability cap) { + return ForgeCapabilities.ENERGY.orEmpty(cap, energy); + } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java index 73dc6beac..3afc71377 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/LaserTowerEntity.java @@ -291,9 +291,10 @@ public class LaserTowerEntity extends EnergyVehicleEntity implements GeoEntity, } public void autoAim() { - if (this.entityData.get(ENERGY) <= 0 || !entityData.get(ACTIVE) || this.entityData.get(COOL_DOWN) > 30) return; + if (this.getEnergy() <= 0 || !entityData.get(ACTIVE) || this.entityData.get(COOL_DOWN) > 30) + return; - if (entityData.get(TARGET_UUID).equals("none") && tickCount %10 == 0) { + if (entityData.get(TARGET_UUID).equals("none") && tickCount % 10 == 0) { Entity naerestEntity = seekNearLivingEntity(72); if (naerestEntity != null) { entityData.set(TARGET_UUID, naerestEntity.getStringUUID());