初步添加激光炮的能量系统

This commit is contained in:
Atsuihsio 2024-12-06 03:23:15 +08:00
parent 6a5f7a0f2a
commit 795f812da2
15 changed files with 108 additions and 60 deletions

View file

@ -8,7 +8,6 @@ import com.atsuishio.superbwarfare.entity.ICannonEntity;
import com.atsuishio.superbwarfare.entity.MortarEntity;
import com.atsuishio.superbwarfare.event.ClientEventHandler;
import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.item.common.ammo.CannonShellItem;
import com.atsuishio.superbwarfare.network.ModVariables;
import com.atsuishio.superbwarfare.network.message.*;
import com.atsuishio.superbwarfare.tools.GunsTool;
@ -288,7 +287,7 @@ public class ClickHandler {
ModUtils.PACKET_HANDLER.sendToServer(new DroneFireMessage(0));
}
if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity && player.getMainHandItem().getItem() instanceof CannonShellItem) {
if (player.getVehicle() != null && player.getVehicle() instanceof ICannonEntity) {
ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(0));
return;
}

View file

@ -37,7 +37,11 @@ public class CannonHudOverlay {
public static float maxHealth = 0;
public static float indicatorPosH = 0;
public static float energy = 0;
public static float maxEnergy = 0;
private static final ResourceLocation ARMOR = ModUtils.loc("textures/screens/armor.png");
private static final ResourceLocation ENERGY = ModUtils.loc("textures/screens/energy.png");
private static final ResourceLocation HEALTH = ModUtils.loc("textures/screens/armor_value.png");
private static final ResourceLocation HEALTH_FRAME = ModUtils.loc("textures/screens/armor_value_frame.png");
@ -58,6 +62,7 @@ public class CannonHudOverlay {
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.blendFuncSeparate(GlStateManager.SourceFactor.SRC_ALPHA, GlStateManager.DestFactor.ONE_MINUS_SRC_ALPHA, GlStateManager.SourceFactor.ONE, GlStateManager.DestFactor.ZERO);
RenderSystem.setShaderColor(1, 1, 1, 1);
GuiGraphics guiGraphics = event.getGuiGraphics();
if (cannon instanceof Mk42Entity) {
health = cannon.getEntityData().get(Mk42Entity.HEALTH);
@ -74,9 +79,23 @@ public class CannonHudOverlay {
if (cannon instanceof AnnihilatorEntity) {
health = cannon.getEntityData().get(AnnihilatorEntity.HEALTH);
maxHealth = CannonConfig.ANNIHILATOR_HP.get();
energy = cannon.getEntityData().get(AnnihilatorEntity.ENERGY);
maxEnergy = CannonConfig.ANNIHILATOR_MAX_ENERGY.get().floatValue();
indicatorPosH = 0.2f;
guiGraphics.pose().pushPose();
guiGraphics.blit(ENERGY, w - 96, h - 28, 0, 0, 12, 12, 12, 12);
guiGraphics.blit(HEALTH_FRAME, w - 83, h - 26, 0, 0, 80, 8, 80, 8);
guiGraphics.blit(HEALTH, w - 83, h - 26, 0, 0, (int) (80 * energy / maxEnergy), 8, 80, 8);
guiGraphics.pose().popPose();
}
guiGraphics.pose().pushPose();
guiGraphics.blit(ARMOR, w - 96, h - 14, 0, 0, 12, 12, 12, 12);
guiGraphics.blit(HEALTH_FRAME, w - 83, h - 12, 0, 0, 80, 8, 80, 8);
guiGraphics.blit(HEALTH, w - 83, h - 12, 0, 0, (int) (80 * health / maxHealth), 8, 80, 8);
guiGraphics.pose().popPose();
float yRotOffset = Mth.lerp(event.getPartialTick(), player.yRotO, player.getYRot());
float xRotOffset = Mth.lerp(event.getPartialTick(), player.xRotO, player.getXRot());
float diffY = cannon.getViewYRot(event.getPartialTick()) - yRotOffset;
@ -94,7 +113,7 @@ public class CannonHudOverlay {
int k = (w - i) / 2;
int l = (h - j) / 2;
if (ClientEventHandler.zoom) {
Entity lookingEntity = TraceTool.cannonFindLookingEntity(player, 512);
Entity lookingEntity = TraceTool.findLookingEntity(player, 512);
boolean lookAtEntity = false;
double block_range = player.position().distanceTo((Vec3.atLowerCornerOf(player.level().clip(
new ClipContext(new Vec3(player.getX(), player.getEyeY() + 1, player.getZ()), new Vec3(player.getX(), player.getEyeY() + 1, player.getZ()).add(player.getLookAngle().scale(512)),
@ -120,7 +139,11 @@ public class CannonHudOverlay {
w / 2 + 14, h / 2 - 20, -1, false);
}
}
if (cannon instanceof AnnihilatorEntity) {
RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/laser_cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
} else {
RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair.png"), k, l, 0, 0.0F, i, j, i, j);
}
RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/indicator.png"), k + (float) Math.tan(Mth.clamp(Mth.DEG_TO_RAD * diffY, -1.5, 1.5)) * 5 * i / 1.4f * (90 - Math.abs(player.getXRot())) / 90, l + (float) Math.tan(Mth.clamp(Mth.DEG_TO_RAD * diffX, -1.5, 1.5)) * 5 * j / 1.4f, 0, 0.0F, i, j, i, j);
} else {
RenderHelper.preciseBlit(event.getGuiGraphics(), ModUtils.loc("textures/screens/cannon/cannon_crosshair_notzoom.png"), k, l, 0, 0.0F, i, j, i, j);
@ -130,18 +153,7 @@ public class CannonHudOverlay {
.append(Component.literal(new DecimalFormat("##.#").format(-cannon.getXRot()) + "°")),
w / 2 + 14, h / 2 - 29, -1, false);
GuiGraphics guiGraphics = event.getGuiGraphics();
guiGraphics.pose().pushPose();
guiGraphics.blit(ARMOR, w - 96, h - 14, 0, 0, 12, 12, 12, 12);
guiGraphics.blit(HEALTH_FRAME, w - 83, h - 12, 0, 0, 80, 8, 80, 8);
guiGraphics.blit(HEALTH, w - 83, h - 12, 0, 0, (int) (80 * health / maxHealth), 8, 80, 8);
guiGraphics.pose().popPose();
RenderSystem.depthMask(true);
RenderSystem.defaultBlendFunc();
RenderSystem.enableDepthTest();
RenderSystem.disableBlend();
RenderSystem.setShaderColor(1, 1, 1, 1);
}
private static boolean shouldRenderCrossHair(Player player) {

View file

@ -21,6 +21,8 @@ public class CannonConfig {
public static ForgeConfigSpec.IntValue MLE1934_HE_EXPLOSION_RADIUS;
public static ForgeConfigSpec.IntValue ANNIHILATOR_HP;
public static ForgeConfigSpec.DoubleValue ANNIHILATOR_SHOOT_COST;
public static ForgeConfigSpec.DoubleValue ANNIHILATOR_MAX_ENERGY;
public static void init(ForgeConfigSpec.Builder builder) {
builder.push("mk_42");
@ -75,8 +77,15 @@ public class CannonConfig {
builder.push("annihilator");
builder.comment("The HealthPoint of ANNIHILATOR");
builder.comment("The HealthPoint of Annihilator");
ANNIHILATOR_HP = builder.defineInRange("annihilator_hp", 4000, 1, 10000000);
builder.comment("The energy cost of Annihilator per shoot");
ANNIHILATOR_SHOOT_COST = builder.defineInRange("annihilator_shoot_cost", 2000000d, 0d, Double.POSITIVE_INFINITY);
builder.comment("The max energy storage of Annihilator");
ANNIHILATOR_MAX_ENERGY = builder.defineInRange("annihilator_max_energy", 20000000d, 0d, Double.POSITIVE_INFINITY);
builder.pop();
}

View file

@ -13,6 +13,7 @@ import net.minecraft.core.BlockPos;
import net.minecraft.core.Direction;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.chat.Component;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
@ -58,11 +59,12 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
public static final EntityDataAccessor<Float> LASER_LEFT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> LASER_MIDDLE_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> LASER_RIGHT_LENGTH = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> ENERGY = SynchedEntityData.defineId(AnnihilatorEntity.class, EntityDataSerializers.FLOAT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public static final float MAX_HEALTH = CannonConfig.ANNIHILATOR_HP.get();
public static final float SHOOT_COST = CannonConfig.ANNIHILATOR_SHOOT_COST.get().floatValue();
protected int interpolationSteps;
protected double serverYRot;
protected double serverXRot;
@ -83,17 +85,20 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
this.entityData.define(LASER_LEFT_LENGTH, 0f);
this.entityData.define(LASER_MIDDLE_LENGTH, 0f);
this.entityData.define(LASER_RIGHT_LENGTH, 0f);
this.entityData.define(ENERGY, 0f);
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
compound.putInt("CoolDown", this.entityData.get(COOL_DOWN));
compound.putFloat("Health", this.entityData.get(HEALTH));
compound.putFloat("Energy", this.entityData.get(ENERGY));
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
this.entityData.set(COOL_DOWN, compound.getInt("CoolDown"));
this.entityData.set(ENERGY, compound.getFloat("Energy"));
if (compound.contains("Health")) {
this.entityData.set(HEALTH, compound.getFloat("Health"));
} else {
@ -101,12 +106,12 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
}
}
// TODO 修改乘客的位置
@Override
protected void positionRider(Entity pPassenger, MoveFunction pCallback) {
if (this.hasPassenger(pPassenger)) {
double d0 = this.getY() + this.getPassengersRidingOffset() + pPassenger.getMyRidingOffset();
pCallback.accept(pPassenger, this.getX(), d0, this.getZ());
float f1 = (float)((this.isRemoved() ? 0.009999999776482582 : this.getPassengersRidingOffset()) + pPassenger.getMyRidingOffset());
Vec3 vec3 = (new Vec3(1, 0.0, 0.0)).yRot(-this.getYRot() * 0.017453292F - 1.5707964F);
pCallback.accept(pPassenger, this.getX() + vec3.x, this.getY() + (double)f1, this.getZ() + vec3.z);
}
}
@ -187,6 +192,11 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
this.discard();
return InteractionResult.sidedSuccess(this.level().isClientSide());
}
if (player.getMainHandItem().is(ModItems.SHIELD_CELL.get())) {
this.entityData.set(ENERGY, (float)Mth.clamp(this.entityData.get(ENERGY) + 1000000 , 0, CannonConfig.ANNIHILATOR_MAX_ENERGY.get()));
player.displayClientMessage(Component.literal("Energy:" + new java.text.DecimalFormat("##").format(this.entityData.get(ENERGY))), true);
return InteractionResult.sidedSuccess(this.level().isClientSide());
}
return InteractionResult.PASS;
} else {
if (this.getFirstPassenger() == null) {
@ -196,7 +206,6 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
return InteractionResult.sidedSuccess(this.level().isClientSide());
}
}
return InteractionResult.PASS;
}
@ -296,6 +305,13 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
}
travel();
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
if (passenger instanceof ServerPlayer serverPlayer && this.entityData.get(COOL_DOWN) == 20) {
SoundTool.playLocalSound(serverPlayer, ModSounds.ANNIHILATOR_RELOAD.get(), 1, 1);
}
this.refreshDimensions();
}
@ -379,21 +395,25 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
return;
}
Level level = player.level();
if (level instanceof ServerLevel server) {
ItemStack stack = player.getMainHandItem();
if (this.entityData.get(ENERGY) < SHOOT_COST) {
player.displayClientMessage(Component.literal("Not Enough Energy!"), true);
return;
}
Level level = player.level();
if (level instanceof ServerLevel) {
if (player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.ANNIHILATOR_FIRE_1P.get(), 1, 1);
// SoundTool.playLocalSound(serverPlayer, ModSounds.MK_42_RELOAD.get(), 2, 1);
// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MK_42_FIRE_3P.get(), SoundSource.PLAYERS, 6, 1);
// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MK_42_FAR.get(), SoundSource.PLAYERS, 16, 1);
// serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.MK_42_VERYFAR.get(), SoundSource.PLAYERS, 32, 1);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.ANNIHILATOR_FIRE_3P.get(), SoundSource.PLAYERS, 6, 1);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.ANNIHILATOR_FAR.get(), SoundSource.PLAYERS, 16, 1);
serverPlayer.level().playSound(null, serverPlayer.getOnPos(), ModSounds.ANNIHILATOR_VERYFAR.get(), SoundSource.PLAYERS, 32, 1);
}
this.entityData.set(COOL_DOWN, 100);
this.entityData.set(ENERGY, this.entityData.get(ENERGY) - SHOOT_COST);
final Vec3 center = new Vec3(this.getX(), this.getEyeY(), this.getZ());
for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(20), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) {
@ -415,6 +435,7 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
public void travel() {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
if (!(passenger instanceof LivingEntity entity)) return;
if (this.entityData.get(ENERGY) == 0) return;
float passengerY = entity.getYHeadRot();
@ -452,7 +473,7 @@ public class AnnihilatorEntity extends Entity implements GeoEntity, ICannonEntit
}
private PlayState movementPredicate(AnimationState<AnnihilatorEntity> event) {
if (this.entityData.get(COOL_DOWN) > 88) {
if (this.entityData.get(COOL_DOWN) > 80) {
return event.setAndContinue(RawAnimation.begin().thenPlay("animation.annihilator.fire"));
}
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.annihilator.idle"));

View file

@ -338,5 +338,9 @@ public class ModSounds {
public static final RegistryObject<SoundEvent> CHARGE_RIFLE_FIRE_BOOM_3P = REGISTRY.register("charge_rifle_fire_boom_3p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "charge_rifle_fire_boom_3p")));
public static final RegistryObject<SoundEvent> ANNIHILATOR_FIRE_1P = REGISTRY.register("annihilator_fire_1p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_fire_1p")));
public static final RegistryObject<SoundEvent> ANNIHILATOR_FIRE_3P = REGISTRY.register("annihilator_fire_3p", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_fire_3p")));
public static final RegistryObject<SoundEvent> ANNIHILATOR_FAR = REGISTRY.register("annihilator_far", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_far")));
public static final RegistryObject<SoundEvent> ANNIHILATOR_VERYFAR = REGISTRY.register("annihilator_veryfar", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_veryfar")));
public static final RegistryObject<SoundEvent> ANNIHILATOR_RELOAD = REGISTRY.register("annihilator_reload", () -> SoundEvent.createVariableRangeEvent(new ResourceLocation(ModUtils.MODID, "annihilator_reload")));
}

View file

@ -90,35 +90,4 @@ public class TraceTool {
return null;
}
public static Entity cannonFindLookingEntity(Entity player, double entityReach) {
double distance = entityReach * entityReach;
Vec3 eyePos = new Vec3(player.getX(), player.getEyeY() + 1, player.getZ());
HitResult hitResult = player.pick(entityReach, 1.0f, false);
if (hitResult.getType() != HitResult.Type.MISS) {
distance = hitResult.getLocation().distanceToSqr(eyePos);
double blockReach = 5;
if (distance > blockReach * blockReach) {
Vec3 pos = hitResult.getLocation();
hitResult = BlockHitResult.miss(pos, Direction.getNearest(eyePos.x, eyePos.y, eyePos.z), BlockPos.containing(pos));
}
}
Vec3 viewVec = player.getViewVector(1.0F);
Vec3 toVec = eyePos.add(viewVec.x * entityReach, viewVec.y * entityReach, viewVec.z * entityReach);
AABB aabb = player.getBoundingBox().expandTowards(viewVec.scale(entityReach)).inflate(1.0D, 1.0D, 1.0D);
EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(player, eyePos, toVec, aabb, p -> !p.isSpectator(), distance);
if (entityhitresult != null) {
Vec3 targetPos = entityhitresult.getLocation();
double distanceToTarget = eyePos.distanceToSqr(targetPos);
if (distanceToTarget > distance || distanceToTarget > entityReach * entityReach) {
hitResult = BlockHitResult.miss(targetPos, Direction.getNearest(viewVec.x, viewVec.y, viewVec.z), BlockPos.containing(targetPos));
} else if (distanceToTarget < distance) {
hitResult = entityhitresult;
}
}
if (hitResult.getType() == HitResult.Type.ENTITY) {
return ((EntityHitResult) hitResult).getEntity();
}
return null;
}
}

View file

@ -351,6 +351,7 @@
"entity.superbwarfare.mk_42": "5''/54 Mk42",
"entity.superbwarfare.mle_1934": "138.6mm50 Mle1934 R1938",
"entity.superbwarfare.drone": "Drone",
"entity.superbwarfare.annihilator": "Annihilator Energy Gun",
"key.categories.superbwarfare": "Superb Warfare",
"key.superbwarfare.hold_zoom": "Zoom(Hold)",

View file

@ -351,6 +351,7 @@
"entity.superbwarfare.mk_42": "5''/54 Mk42",
"entity.superbwarfare.mle_1934": "138.6mm50 Mle1934 R1938",
"entity.superbwarfare.drone": "无人机",
"entity.superbwarfare.annihilator": "歼灭者能量炮",
"key.categories.superbwarfare": "卓越前线",
"key.superbwarfare.hold_zoom": "瞄准(按住)",

View file

@ -2397,5 +2397,37 @@
"stream": false
}
]
},
"annihilator_fire_3p": {
"sounds": [
{
"name": "superbwarfare:annihilator/annihilator_fire_3p",
"stream": false
}
]
},
"annihilator_far": {
"sounds": [
{
"name": "superbwarfare:annihilator/annihilator_far",
"stream": false
}
]
},
"annihilator_veryfar": {
"sounds": [
{
"name": "superbwarfare:annihilator/annihilator_veryfar",
"stream": false
}
]
},
"annihilator_reload": {
"sounds": [
{
"name": "superbwarfare:annihilator/annihilator_reload",
"stream": false
}
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 134 B