实现DPS发电机发电功能

This commit is contained in:
Light_Quanta 2025-05-10 01:21:27 +08:00
parent 4fbe8a589d
commit 4aa32fabf3
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
5 changed files with 113 additions and 12 deletions

View file

@ -23,12 +23,33 @@ public class SyncedEntityEnergyStorage extends EnergyStorage {
* @param energyDataAccessor 能量的EntityDataAccessor
*/
public SyncedEntityEnergyStorage(int capacity, SynchedEntityData data, EntityDataAccessor<Integer> energyDataAccessor) {
super(capacity, capacity, capacity, 0);
this(capacity, capacity, capacity, data, energyDataAccessor);
}
public SyncedEntityEnergyStorage(int capacity, int maxReceive, int maxExtract, SynchedEntityData data, EntityDataAccessor<Integer> energyDataAccessor) {
super(capacity, maxReceive, maxExtract, 0);
this.entityData = data;
this.energyDataAccessor = energyDataAccessor;
}
public void setEnergy(int energy) {
this.energy = energy;
entityData.set(energyDataAccessor, energy);
}
public void setCapacity(int capacity) {
this.capacity = capacity;
}
public void setMaxExtract(int maxExtract) {
this.maxExtract = maxExtract;
}
public void setMaxReceive(int maxReceive) {
this.maxReceive = maxReceive;
}
@Override
public int receiveEnergy(int maxReceive, boolean simulate) {
var received = super.receiveEnergy(maxReceive, simulate);
@ -62,5 +83,4 @@ public class SyncedEntityEnergyStorage extends EnergyStorage {
super.deserializeNBT(provider, nbt);
entityData.set(energyDataAccessor, energy);
}
}

View file

@ -1,13 +1,16 @@
package com.atsuishio.superbwarfare.entity;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.capability.energy.SyncedEntityEnergyStorage;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.tools.FormatTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import net.minecraft.commands.arguments.EntityAnchorArgument;
import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.NonNullList;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
@ -27,6 +30,8 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.phys.Vec3;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.EventBusSubscriber;
import net.neoforged.neoforge.capabilities.Capabilities;
import net.neoforged.neoforge.energy.IEnergyStorage;
import net.neoforged.neoforge.event.entity.living.LivingDeathEvent;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoEntity;
@ -39,6 +44,8 @@ import software.bernie.geckolib.util.GeckoLibUtil;
public class DPSGeneratorEntity extends LivingEntity implements GeoEntity {
public static final EntityDataAccessor<Integer> DOWN_TIME = SynchedEntityData.defineId(DPSGeneratorEntity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> ENERGY = SynchedEntityData.defineId(DPSGeneratorEntity.class, EntityDataSerializers.INT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public DPSGeneratorEntity(EntityType<DPSGeneratorEntity> type, Level world) {
@ -49,7 +56,9 @@ public class DPSGeneratorEntity extends LivingEntity implements GeoEntity {
@Override
protected void defineSynchedData(SynchedEntityData.@NotNull Builder builder) {
super.defineSynchedData(builder);
builder.define(DOWN_TIME, 0);
builder.define(DOWN_TIME, 0)
.define(ENERGY, 0);
}
@ -110,13 +119,8 @@ public class DPSGeneratorEntity extends LivingEntity implements GeoEntity {
if (entity instanceof DPSGeneratorEntity generatorEntity) {
event.setCanceled(true);
generatorEntity.setHealth(generatorEntity.getMaxHealth());
if (sourceEntity == null) return;
if (sourceEntity instanceof Player player) {
player.displayClientMessage(Component.translatable("tips.superbwarfare.target.down",
FormatTool.format1D(entity.position().distanceTo(sourceEntity.position())), "m"), true);
SoundTool.playLocalSound(player, ModSounds.TARGET_DOWN.get(), 1, 1);
generatorEntity.entityData.set(DOWN_TIME, 40);
}
@ -124,13 +128,28 @@ public class DPSGeneratorEntity extends LivingEntity implements GeoEntity {
}
@Override
public boolean isPickable() {
return this.entityData.get(DOWN_TIME) == 0;
public void addAdditionalSaveData(@NotNull CompoundTag compound) {
super.addAdditionalSaveData(compound);
var entityCap = this.getCapability(Capabilities.EnergyStorage.ENTITY, null);
if (entityCap == null) return;
compound.putInt("Energy", entityCap.getEnergyStored());
}
@Override
public void die(@NotNull DamageSource source) {
super.die(source);
public void readAdditionalSaveData(@NotNull CompoundTag compound) {
super.readAdditionalSaveData(compound);
var entityCap = this.getCapability(Capabilities.EnergyStorage.ENTITY, null);
if (entityCap == null) return;
((SyncedEntityEnergyStorage) entityCap).setEnergy(compound.getInt("Energy"));
}
@Override
public boolean isPickable() {
return this.entityData.get(DOWN_TIME) == 0;
}
@Override
@ -159,6 +178,35 @@ public class DPSGeneratorEntity extends LivingEntity implements GeoEntity {
if (this.entityData.get(DOWN_TIME) > 0) {
this.entityData.set(DOWN_TIME, this.entityData.get(DOWN_TIME) - 1);
}
// 每秒恢复生命并充能下方方块
if (this.tickCount % 20 == 0) {
var damage = this.getMaxHealth() - this.getHealth();
var entityCap = this.getCapability(Capabilities.EnergyStorage.ENTITY, null);
if (damage > 0 && entityCap != null) {
// DPS显示
if (getLastDamageSource() != null) {
var attacker = getLastDamageSource().getEntity();
if (attacker instanceof Player player) {
player.displayClientMessage(Component.translatable("tips.superbwarfare.dps_generator.dps", FormatTool.format1D(damage)), true);
}
}
// 发电
((SyncedEntityEnergyStorage) entityCap).setMaxReceive(entityCap.getMaxEnergyStored());
entityCap.receiveEnergy(Math.round(256 * damage), false);
((SyncedEntityEnergyStorage) entityCap).setMaxReceive(0);
}
// 充能底部方块
chargeBlockBelow();
if (this.getHealth() < 0.01) {
// TODO 升级
}
this.setHealth(this.getMaxHealth());
}
}
@Override
@ -228,9 +276,32 @@ public class DPSGeneratorEntity extends LivingEntity implements GeoEntity {
data.add(new AnimationController<>(this, "movement", 0, this::movementPredicate));
}
protected void chargeBlockBelow() {
var entityCap = this.getCapability(Capabilities.EnergyStorage.ENTITY, null);
if (entityCap == null) return;
if (!entityCap.canExtract() || entityCap.getEnergyStored() <= 0) return;
var blockPos = this.blockPosition().below();
var cap = this.level().getCapability(Capabilities.EnergyStorage.BLOCK, blockPos, Direction.UP);
if (cap == null || !cap.canReceive()) return;
var extract = entityCap.extractEnergy(entityCap.getEnergyStored(), true);
var extracted = cap.receiveEnergy(extract, false);
if (extracted <= 0) return;
this.level().blockEntityChanged(blockPos);
entityCap.extractEnergy(extracted, false);
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
// TODO 发电机升级容量+传输速率实现
protected final SyncedEntityEnergyStorage energyStorage = new SyncedEntityEnergyStorage(5120, 0, 2560, this.entityData, ENERGY);
public IEnergyStorage getEnergyStorage() {
return this.energyStorage;
}
}

View file

@ -96,5 +96,11 @@ public class ModCapabilities {
}
}
// DPS发电机
event.registerEntity(Capabilities.EnergyStorage.ENTITY,
ModEntities.DPS_GENERATOR.get(),
(obj, ctx) -> obj.getEnergyStorage()
);
}
}

View file

@ -438,6 +438,7 @@
"entity.superbwarfare.flare_decoy": "Flare Decoy",
"entity.superbwarfare.mortar": "Mortar",
"entity.superbwarfare.target": "Target",
"entity.superbwarfare.dps_generator": "DPS Generator",
"entity.superbwarfare.claymore": "Claymore",
"entity.superbwarfare.c4": "C4",
"entity.superbwarfare.senpai": "Beast Senpai",
@ -530,6 +531,7 @@
"tips.superbwarfare.annihilator.energy_not_enough": "Insufficient Power!",
"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.mortar.range": "Range: ",
"tips.superbwarfare.mortar.yaw": "Yaw: ",
"tips.superbwarfare.mortar.pitch": "Pitch: ",

View file

@ -436,6 +436,7 @@
"entity.superbwarfare.flare_decoy": "热诱弹",
"entity.superbwarfare.mortar": "迫击炮",
"entity.superbwarfare.target": "标靶",
"entity.superbwarfare.dps_generator": "DPS发电机",
"entity.superbwarfare.claymore": "阔剑地雷",
"entity.superbwarfare.c4": "C4",
"entity.superbwarfare.senpai": "野兽先辈",
@ -528,6 +529,7 @@
"tips.superbwarfare.annihilator.energy_not_enough": "能量不足",
"tips.superbwarfare.target.down": "击倒目标 %1$s",
"tips.superbwarfare.target.damage": "伤害:%1$s 距离:%2$s",
"tips.superbwarfare.dps_generator.dps": "DPS: %1$s",
"tips.superbwarfare.mortar.range": "射程:",
"tips.superbwarfare.mortar.yaw": "水平朝向:",
"tips.superbwarfare.mortar.pitch": "俯仰角度:",