添加A10投弹功能和MK82航弹

This commit is contained in:
Atsuishio 2025-05-09 04:31:03 +08:00 committed by Light_Quanta
parent 9e64acdb23
commit cd71d815ec
No known key found for this signature in database
GPG key ID: 11A39A1B8C890959
40 changed files with 8560 additions and 57 deletions

View file

@ -1,4 +1,4 @@
// 1.21.1 2025-04-28T03:55:32.0625325 Item Models: superbwarfare // 1.21.1 2025-05-09T21:27:11.5373344 Item Models: superbwarfare
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/aa_12_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/aa_12_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_12_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_12_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_47_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_47_blueprint.json
@ -59,6 +59,7 @@ f66c351b4843ad4d4e086ccfb7d4d0221227d196 assets/superbwarfare/models/item/legend
ec76dc1a79f4c0e502fee53be8aa8e04420845fc assets/superbwarfare/models/item/light_armament_module.json ec76dc1a79f4c0e502fee53be8aa8e04420845fc assets/superbwarfare/models/item/light_armament_module.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/m2hb_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/m2hb_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/marlin_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/marlin_blueprint.json
7a0d27d39eefff5d7f69cc0ae21a2681b0aadfd4 assets/superbwarfare/models/item/medium_aerial_bomb.json
0033cd03b0203cd3fa071fb5354c74d33bc1afa8 assets/superbwarfare/models/item/medium_armament_module.json 0033cd03b0203cd3fa071fb5354c74d33bc1afa8 assets/superbwarfare/models/item/medium_armament_module.json
81699ddddb4270261ae10ff812b00e666649ff7c assets/superbwarfare/models/item/medium_battery_pack.json 81699ddddb4270261ae10ff812b00e666649ff7c assets/superbwarfare/models/item/medium_battery_pack.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/minigun_blueprint.json 13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/minigun_blueprint.json

View file

@ -0,0 +1,6 @@
{
"parent": "minecraft:item/generated",
"textures": {
"layer0": "superbwarfare:item/medium_aerial_bomb"
}
}

View file

@ -85,7 +85,7 @@ public abstract class LoudlyEntitySoundInstance extends AbstractTickableSoundIns
@Override @Override
protected float getVolume(Entity entity) { protected float getVolume(Entity entity) {
if (entity instanceof LoudlyEntity loudlyEntity) { if (entity instanceof LoudlyEntity loudlyEntity) {
return loudlyEntity.getVolume(); return (float) Math.min(loudlyEntity.getVolume() * 0.1 * entity.getDeltaMovement().length(), 1.5);
} }
return 0; return 0;
} }
@ -109,7 +109,7 @@ public abstract class LoudlyEntitySoundInstance extends AbstractTickableSoundIns
@Override @Override
protected float getVolume(Entity entity) { protected float getVolume(Entity entity) {
if (entity instanceof LoudlyEntity loudlyEntity) { if (entity instanceof LoudlyEntity loudlyEntity) {
return loudlyEntity.getVolume() * 1.5f; return (float) Math.min(loudlyEntity.getVolume() * 0.1 * entity.getDeltaMovement().length(), 1.5);
} }
return 0; return 0;
} }

View file

@ -0,0 +1,24 @@
package com.atsuishio.superbwarfare.client.model.entity;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.entity.projectile.Mk82Entity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class Mk82Model extends GeoModel<Mk82Entity> {
@Override
public ResourceLocation getAnimationResource(Mk82Entity entity) {
return Mod.loc("animations/mk82.animation.json");
}
@Override
public ResourceLocation getModelResource(Mk82Entity entity) {
return Mod.loc("geo/mk82.geo.json");
}
@Override
public ResourceLocation getTextureResource(Mk82Entity entity) {
return Mod.loc("textures/entity/mk82.png");
}
}

View file

@ -44,9 +44,6 @@ public class AircraftOverlay implements LayeredDraw.Layer {
@Override @Override
public void render(GuiGraphics guiGraphics, @NotNull DeltaTracker deltaTracker) { public void render(GuiGraphics guiGraphics, @NotNull DeltaTracker deltaTracker) {
int screenWidth = guiGraphics.guiWidth();
int screenHeight = guiGraphics.guiHeight();
Minecraft mc = Minecraft.getInstance(); Minecraft mc = Minecraft.getInstance();
Player player = mc.player; Player player = mc.player;
Camera camera = mc.gameRenderer.getMainCamera(); Camera camera = mc.gameRenderer.getMainCamera();
@ -122,7 +119,7 @@ public class AircraftOverlay implements LayeredDraw.Layer {
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), x - 108, y - 64, 0, 0, 36, 12, 36, 12); preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), x - 108, y - 64, 0, 0, 36, 12, 36, 12);
preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), x + 108 - 36, y - 64, 0, 0, 36, 12, 36, 12); preciseBlit(guiGraphics, Mod.loc("textures/screens/helicopter/speed_frame.png"), x + 108 - 36, y - 64, 0, 0, 36, 12, 36, 12);
//垂直速度 //垂直速度
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(lerpVy * 20)), (int) x - 96, (int) y + 60, 0x66FF00, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.DECIMAL_FORMAT_1ZZ.format(lerpVy * 20)), (int) x - 96, (int) y + 60, 0x66FF00, false);
//加速度 //加速度
lerpG = (float) Mth.lerp(0.1f * partialTick, lerpG, mobileVehicle.acceleration / 9.8); lerpG = (float) Mth.lerp(0.1f * partialTick, lerpG, mobileVehicle.acceleration / 9.8);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("M"), (int) x - 105, (int) y + 70, 0x66FF00, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("M"), (int) x - 105, (int) y + 70, 0x66FF00, false);
@ -146,7 +143,7 @@ public class AircraftOverlay implements LayeredDraw.Layer {
String count = InventoryTool.hasCreativeAmmoBox(player) ? "" : String.valueOf(aircraftEntity.getAmmoCount(player)); String count = InventoryTool.hasCreativeAmmoBox(player) ? "" : String.valueOf(aircraftEntity.getAmmoCount(player));
int width2 = Minecraft.getInstance().font.width(count); int width2 = Minecraft.getInstance().font.width(count);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
} else { } else if (weaponVehicle.getWeaponIndex(0) == 1) {
String name = "70MM ROCKET"; String name = "70MM ROCKET";
int width = Minecraft.getInstance().font.width(name); int width = Minecraft.getInstance().font.width(name);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(name), (int) x - width / 2, (int) y + 67, 0x66FF00, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(name), (int) x - width / 2, (int) y + 67, 0x66FF00, false);
@ -154,7 +151,15 @@ public class AircraftOverlay implements LayeredDraw.Layer {
String count = String.valueOf(aircraftEntity.getAmmoCount(player)); String count = String.valueOf(aircraftEntity.getAmmoCount(player));
int width2 = Minecraft.getInstance().font.width(count); int width2 = Minecraft.getInstance().font.width(count);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, 0x66FF00, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, 0x66FF00, false);
} } else if (weaponVehicle.getWeaponIndex(0) == 2) {
String name = "MK82 BOMB";
int width = Minecraft.getInstance().font.width(name);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(name), (int) x - width / 2, (int) y + 67, 0x66FF00, false);
String count = String.valueOf(aircraftEntity.getAmmoCount(player));
int width2 = Minecraft.getInstance().font.width(count);
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(count), (int) x - width2 / 2, (int) y + 76, 0x66FF00, false);
}
} }
//角度 //角度
@ -220,8 +225,10 @@ public class AircraftOverlay implements LayeredDraw.Layer {
if (weaponVehicle.getWeaponIndex(0) == 0) { if (weaponVehicle.getWeaponIndex(0) == 0) {
double heat = a10Entity.getEntityData().get(HEAT) / 100.0F; double heat = a10Entity.getEntityData().get(HEAT) / 100.0F;
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("30MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : aircraftEntity.getAmmoCount(player))), 25, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("30MM CANNON " + (InventoryTool.hasCreativeAmmoBox(player) ? "" : aircraftEntity.getAmmoCount(player))), 25, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
} else { } else if (weaponVehicle.getWeaponIndex(0) == 1) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + aircraftEntity.getAmmoCount(player)), 25, -9, -1, false); guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("70MM ROCKET " + aircraftEntity.getAmmoCount(player)), 25, -9, -1, false);
} else if (weaponVehicle.getWeaponIndex(0) == 2) {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("MK82 BOMB " + aircraftEntity.getAmmoCount(player)), 25, -9, -1, false);
} }
} }

View file

@ -15,6 +15,7 @@ import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.cache.object.GeoBone; import software.bernie.geckolib.cache.object.GeoBone;
import software.bernie.geckolib.renderer.GeoEntityRenderer; import software.bernie.geckolib.renderer.GeoEntityRenderer;
import static com.atsuishio.superbwarfare.entity.vehicle.A10Entity.LOADED_BOMB;
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.GEAR_ROT; import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.GEAR_ROT;
public class A10Renderer extends GeoEntityRenderer<A10Entity> { public class A10Renderer extends GeoEntityRenderer<A10Entity> {
@ -72,6 +73,15 @@ public class A10Renderer extends GeoEntityRenderer<A10Entity> {
if (name.equals("qianzhou") || name.equals("qianzhou2")) { if (name.equals("qianzhou") || name.equals("qianzhou2")) {
bone.setRotZ(Mth.lerp(partialTick, animatable.propellerRotO, animatable.getPropellerRot())); bone.setRotZ(Mth.lerp(partialTick, animatable.propellerRotO, animatable.getPropellerRot()));
} }
if (name.equals("bomb1")) {
bone.setHidden(animatable.getEntityData().get(LOADED_BOMB) < 3);
}
if (name.equals("bomb2")) {
bone.setHidden(animatable.getEntityData().get(LOADED_BOMB) < 2);
}
if (name.equals("bomb3")) {
bone.setHidden(animatable.getEntityData().get(LOADED_BOMB) < 1);
}
super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color); super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color);
} }
} }

View file

@ -0,0 +1,42 @@
package com.atsuishio.superbwarfare.client.renderer.entity;
import com.atsuishio.superbwarfare.client.model.entity.Mk82Model;
import com.atsuishio.superbwarfare.entity.projectile.Mk82Entity;
import com.mojang.blaze3d.vertex.PoseStack;
import com.mojang.blaze3d.vertex.VertexConsumer;
import com.mojang.math.Axis;
import net.minecraft.client.renderer.MultiBufferSource;
import net.minecraft.client.renderer.RenderType;
import net.minecraft.client.renderer.entity.EntityRendererProvider;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import software.bernie.geckolib.cache.object.BakedGeoModel;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class Mk82Renderer extends GeoEntityRenderer<Mk82Entity> {
public Mk82Renderer(EntityRendererProvider.Context renderManager) {
super(renderManager, new Mk82Model());
}
@Override
public RenderType getRenderType(Mk82Entity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
@Override
public void preRender(PoseStack poseStack, Mk82Entity entity, BakedGeoModel model, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, int color) {
float scale = 1f;
this.scaleHeight = scale;
this.scaleWidth = scale;
super.preRender(poseStack, entity, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, color);
}
@Override
public void render(Mk82Entity entityIn, float entityYaw, float partialTicks, PoseStack poseStack, MultiBufferSource bufferIn, int packedLightIn) {
poseStack.pushPose();
poseStack.mulPose(Axis.YP.rotationDegrees(Mth.lerp(partialTicks, entityIn.yRotO, entityIn.getYRot()) - 90));
poseStack.mulPose(Axis.ZP.rotationDegrees(90 + Mth.lerp(partialTicks, entityIn.xRotO, entityIn.getXRot())));
super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
poseStack.popPose();
}
}

View file

@ -82,6 +82,7 @@ public class ModItemModelProvider extends ItemModelProvider {
simpleItem(ModItems.WIRE_GUIDE_MISSILE); simpleItem(ModItems.WIRE_GUIDE_MISSILE);
simpleItem(ModItems.SMALL_SHELL); simpleItem(ModItems.SMALL_SHELL);
simpleItem(ModItems.SWARM_DRONE); simpleItem(ModItems.SWARM_DRONE);
simpleItem(ModItems.MEDIUM_AERIAL_BOMB);
simpleItem(ModItems.SMALL_BATTERY_PACK); simpleItem(ModItems.SMALL_BATTERY_PACK);
simpleItem(ModItems.MEDIUM_BATTERY_PACK); simpleItem(ModItems.MEDIUM_BATTERY_PACK);
simpleItem(ModItems.LARGE_BATTERY_PACK); simpleItem(ModItems.LARGE_BATTERY_PACK);

View file

@ -0,0 +1,4 @@
package com.atsuishio.superbwarfare.entity.projectile;
public interface AerialBombEntity {
}

View file

@ -19,7 +19,7 @@ import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
public class MelonBombEntity extends FastThrowableProjectile implements DestroyableProjectileEntity { public class MelonBombEntity extends FastThrowableProjectile implements DestroyableProjectileEntity, AerialBombEntity {
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(MelonBombEntity.class, EntityDataSerializers.FLOAT); public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(MelonBombEntity.class, EntityDataSerializers.FLOAT);
public MelonBombEntity(EntityType<? extends MelonBombEntity> type, Level world) { public MelonBombEntity(EntityType<? extends MelonBombEntity> type, Level world) {

View file

@ -0,0 +1,169 @@
package com.atsuishio.superbwarfare.entity.projectile;
import com.atsuishio.superbwarfare.entity.LoudlyEntity;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModItems;
import com.atsuishio.superbwarfare.init.ModSounds;
import com.atsuishio.superbwarfare.tools.ProjectileTool;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.sounds.SoundEvents;
import net.minecraft.world.damagesource.DamageSource;
import net.minecraft.world.damagesource.DamageTypes;
import net.minecraft.world.entity.AreaEffectCloud;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.ThrowableItemProjectile;
import net.minecraft.world.entity.projectile.ThrownPotion;
import net.minecraft.world.item.Item;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import org.jetbrains.annotations.NotNull;
import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.animation.*;
import software.bernie.geckolib.util.GeckoLibUtil;
public class Mk82Entity extends FastThrowableProjectile implements GeoEntity, DestroyableProjectileEntity, LoudlyEntity, AerialBombEntity {
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(Mk82Entity.class, EntityDataSerializers.FLOAT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private float explosion_damage = 500f;
private float explosion_radius = 12f;
public Mk82Entity(EntityType<? extends Mk82Entity> type, Level world) {
super(type, world);
this.noCulling = true;
}
public Mk82Entity(LivingEntity entity, Level level, float explosion_damage, float explosion_radius) {
super(ModEntities.MK_82.get(), entity, level);
this.explosion_damage = explosion_damage;
this.explosion_radius = explosion_radius;
}
public Mk82Entity(EntityType<? extends ThrowableItemProjectile> pEntityType, double pX, double pY, double pZ, Level pLevel) {
super(pEntityType, pX, pY, pZ, pLevel);
this.noCulling = true;
}
@Override
protected @NotNull Item getDefaultItem() {
return ModItems.JAVELIN_MISSILE.get();
}
@Override
public boolean hurt(DamageSource source, float amount) {
if (source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud)
return false;
if (source.is(DamageTypes.FALL))
return false;
if (source.is(DamageTypes.CACTUS))
return false;
if (source.is(DamageTypes.DROWN))
return false;
if (source.is(DamageTypes.DRAGON_BREATH))
return false;
if (source.is(DamageTypes.WITHER))
return false;
if (source.is(DamageTypes.WITHER_SKULL))
return false;
if (source.getDirectEntity() instanceof Mk82Entity)
return false;
this.entityData.set(HEALTH, this.entityData.get(HEALTH) - amount);
return super.hurt(source, amount);
}
@Override
protected void defineSynchedData(SynchedEntityData.@NotNull Builder builder) {
super.defineSynchedData(builder);
builder.define(HEALTH, 50f);
}
@Override
public boolean isPickable() {
return !this.isRemoved();
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
if (compound.contains("Health")) {
this.entityData.set(HEALTH, compound.getFloat("Health"));
}
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
compound.putFloat("Health", this.entityData.get(HEALTH));
}
@Override
public boolean shouldRenderAtSqrDistance(double pDistance) {
return true;
}
@Override
public void onHitBlock(BlockHitResult blockHitResult) {
super.onHitBlock(blockHitResult);
ProjectileTool.causeCustomExplode(this, explosion_damage, explosion_radius, 1.2f);
this.discard();
}
@Override
public void tick() {
super.tick();
// this.setDeltaMovement(this.getDeltaMovement().multiply(0.98, 0.98, 0.98));
if (tickCount > 600 || this.entityData.get(HEALTH) <= 0) {
if (!this.level().isClientSide) {
ProjectileTool.causeCustomExplode(this, explosion_damage, explosion_radius, 1.2f);
}
this.discard();
}
}
private PlayState movementPredicate(AnimationState<Mk82Entity> event) {
return event.setAndContinue(RawAnimation.begin().thenPlayAndHold("animation.mk_82.start"));
}
@Override
protected double getDefaultGravity() {
return 0.06F;
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) {
data.add(new AnimationController<>(this, "movement", 0, this::movementPredicate));
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
@Override
public @NotNull SoundEvent getCloseSound() {
return SoundEvents.EMPTY;
}
@Override
public @NotNull SoundEvent getSound() {
return ModSounds.SHELL_FLY.get();
}
@Override
public float getVolume() {
return 0.7f;
}
@Override
public boolean shouldSyncMotion() {
return true;
}
}

View file

@ -3,12 +3,13 @@ package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.AerialBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity; import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.*; import com.atsuishio.superbwarfare.entity.vehicle.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.HeliRocketWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.Mk82Weapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.SmallCannonShellWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.SmallCannonShellWeapon;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.VehicleWeapon;
import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModDamageTypes;
@ -61,12 +62,14 @@ import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity, WeaponVehicleEntity, AircraftEntity { public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity, WeaponVehicleEntity, AircraftEntity {
public static final EntityDataAccessor<Integer> LOADED_ROCKET = SynchedEntityData.defineId(A10Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> LOADED_ROCKET = SynchedEntityData.defineId(A10Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> LOADED_BOMB = SynchedEntityData.defineId(A10Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> FIRE_TIME = SynchedEntityData.defineId(A10Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor<Integer> FIRE_TIME = SynchedEntityData.defineId(A10Entity.class, EntityDataSerializers.INT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
private float yRotSync; private float yRotSync;
private boolean fly; private boolean fly;
private int flyTime; private int flyTime;
public int fireIndex; public int fireIndex;
public int reloadCoolDownBomb;
public A10Entity(EntityType<A10Entity> type, Level world) { public A10Entity(EntityType<A10Entity> type, Level world) {
super(type, world); super(type, world);
@ -92,6 +95,10 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
.explosionDamage(VehicleConfig.AH_6_ROCKET_EXPLOSION_DAMAGE.get()) .explosionDamage(VehicleConfig.AH_6_ROCKET_EXPLOSION_DAMAGE.get())
.explosionRadius(VehicleConfig.AH_6_ROCKET_EXPLOSION_RADIUS.get()) .explosionRadius(VehicleConfig.AH_6_ROCKET_EXPLOSION_RADIUS.get())
.sound(ModSounds.INTO_MISSILE.get()), .sound(ModSounds.INTO_MISSILE.get()),
new Mk82Weapon()
.explosionDamage(500)
.explosionRadius(12)
.sound(ModSounds.INTO_MISSILE.get()),
} }
}; };
} }
@ -105,6 +112,7 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
protected void defineSynchedData(SynchedEntityData.Builder builder) { protected void defineSynchedData(SynchedEntityData.Builder builder) {
super.defineSynchedData(builder); super.defineSynchedData(builder);
builder.define(LOADED_ROCKET, 0) builder.define(LOADED_ROCKET, 0)
.define(LOADED_BOMB, 0)
.define(FIRE_TIME, 0); .define(FIRE_TIME, 0);
} }
@ -112,12 +120,14 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
public void addAdditionalSaveData(CompoundTag compound) { public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound); super.addAdditionalSaveData(compound);
compound.putInt("LoadedRocket", this.entityData.get(LOADED_ROCKET)); compound.putInt("LoadedRocket", this.entityData.get(LOADED_ROCKET));
compound.putInt("LoadedBomb", this.entityData.get(LOADED_BOMB));
} }
@Override @Override
public void readAdditionalSaveData(CompoundTag compound) { public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound); super.readAdditionalSaveData(compound);
this.entityData.set(LOADED_ROCKET, compound.getInt("LoadedRocket")); this.entityData.set(LOADED_ROCKET, compound.getInt("LoadedRocket"));
this.entityData.set(LOADED_BOMB, compound.getInt("LoadedBomb"));
} }
@Override @Override
@ -151,7 +161,7 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
.multiply(15f, ModDamageTypes.VEHICLE_STRIKE) .multiply(15f, ModDamageTypes.VEHICLE_STRIKE)
.custom((source, damage) -> getSourceAngle(source, 0.25f) * damage) .custom((source, damage) -> getSourceAngle(source, 0.25f) * damage)
.custom((source, damage) -> { .custom((source, damage) -> {
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 3f * damage; return 3f * damage;
} }
if (source.getDirectEntity() instanceof MortarShellEntity) { if (source.getDirectEntity() instanceof MortarShellEntity) {
@ -188,6 +198,9 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
if (reloadCoolDown > 0) { if (reloadCoolDown > 0) {
reloadCoolDown--; reloadCoolDown--;
} }
if (reloadCoolDownBomb > 0) {
reloadCoolDownBomb--;
}
handleAmmo(); handleAmmo();
} }
@ -196,7 +209,7 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
if ((this.entityData.get(AMMO) > 0 || InventoryTool.hasCreativeAmmoBox(player)) && !cannotFire) { if ((this.entityData.get(AMMO) > 0 || InventoryTool.hasCreativeAmmoBox(player)) && !cannotFire) {
vehicleShoot(player, 0); vehicleShoot(player, 0);
} }
} else { } else if (this.getWeaponIndex(0) == 1) {
if (this.entityData.get(AMMO) > 0) { if (this.entityData.get(AMMO) > 0) {
vehicleShoot(player, 0); vehicleShoot(player, 0);
} }
@ -215,23 +228,34 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
} }
private void handleAmmo() { private void handleAmmo() {
if (!(this.getFirstPassenger() instanceof Player player)) return; boolean hasCreativeAmmoBox = this.getFirstPassenger() instanceof Player player && InventoryTool.hasCreativeAmmoBox(player);
int ammoCount = countItem(ModItems.SMALL_SHELL.get()); int ammoCount = countItem(ModItems.SMALL_SHELL.get());
if ((hasItem(ModItems.ROCKET_70.get()) || InventoryTool.hasCreativeAmmoBox(player)) && reloadCoolDown == 0 && this.getEntityData().get(LOADED_ROCKET) < 28) { if ((hasItem(ModItems.ROCKET_70.get()) || hasCreativeAmmoBox) && reloadCoolDown == 0 && this.getEntityData().get(LOADED_ROCKET) < 28) {
this.entityData.set(LOADED_ROCKET, this.getEntityData().get(LOADED_ROCKET) + 1); this.entityData.set(LOADED_ROCKET, this.getEntityData().get(LOADED_ROCKET) + 1);
reloadCoolDown = 15; reloadCoolDown = 15;
if (!InventoryTool.hasCreativeAmmoBox(player)) { if (!hasCreativeAmmoBox) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.ROCKET_70.get())).findFirst().ifPresent(stack -> stack.shrink(1)); this.getItemStacks().stream().filter(stack -> stack.is(ModItems.ROCKET_70.get())).findFirst().ifPresent(stack -> stack.shrink(1));
} }
this.level().playSound(null, this, ModSounds.MISSILE_RELOAD.get(), this.getSoundSource(), 1, 1); this.level().playSound(null, this, ModSounds.MISSILE_RELOAD.get(), this.getSoundSource(), 2, 1);
}
if ((hasItem(ModItems.MEDIUM_AERIAL_BOMB.get()) || hasCreativeAmmoBox) && reloadCoolDownBomb == 0 && this.getEntityData().get(LOADED_BOMB) < 3) {
this.entityData.set(LOADED_BOMB, this.getEntityData().get(LOADED_BOMB) + 1);
reloadCoolDownBomb = 200;
if (!hasCreativeAmmoBox) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.MEDIUM_AERIAL_BOMB.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
this.level().playSound(null, this, ModSounds.BOMB_RELOAD.get(), this.getSoundSource(), 2, 1);
} }
if (this.getWeaponIndex(0) == 0) { if (this.getWeaponIndex(0) == 0) {
this.entityData.set(AMMO, ammoCount); this.entityData.set(AMMO, ammoCount);
} else { } else if (this.getWeaponIndex(0) == 1) {
this.entityData.set(AMMO, this.getEntityData().get(LOADED_ROCKET)); this.entityData.set(AMMO, this.getEntityData().get(LOADED_ROCKET));
} else {
this.entityData.set(AMMO, this.getEntityData().get(LOADED_BOMB));
} }
} }
@ -449,6 +473,25 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
copyEntityData(passenger); copyEntityData(passenger);
} }
public Vec3 driverPos(float ticks) {
Matrix4f transform = getVehicleTransform(ticks);
Vector4f worldPosition = transformPosition(transform, 0, 1.35f, 4f);
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
}
@Override
public Vec3 driverZoomPos(float ticks) {
if (getWeaponIndex(0) == 2) {
Matrix4f transform = getVehicleTransform(ticks);
Vector4f worldPosition = transformPosition(transform, 0, -0.75f, 7f);
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
} else {
Matrix4f transform = getVehicleTransform(ticks);
Vector4f worldPosition = transformPosition(transform, 0, 1.35f, 4.15f);
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
}
}
public void copyEntityData(Entity entity) { public void copyEntityData(Entity entity) {
float i = getXRot() / 90; float i = getXRot() / 90;
@ -511,7 +554,7 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
@Override @Override
public ResourceLocation getVehicleIcon() { public ResourceLocation getVehicleIcon() {
return Mod.loc("textures/vehicle_icon/tom_6_icon.png"); return Mod.loc("textures/vehicle_icon/a10_icon.png");
} }
@Override @Override
@ -525,8 +568,10 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
Vector4f worldPosition; Vector4f worldPosition;
if (getWeaponIndex(0) == 0) { if (getWeaponIndex(0) == 0) {
worldPosition = transformPosition(transform, 0.1321625f, -0.56446875f, 7.85210625f); worldPosition = transformPosition(transform, 0.1321625f, -0.56446875f, 7.85210625f);
} else { } else if (getWeaponIndex(0) == 1) {
worldPosition = transformPosition(transform, 0f, -1.76f, 1.87f); worldPosition = transformPosition(transform, 0f, -1.76f, 1.87f);
} else {
worldPosition = transformPosition(transform, 0f, -1.203125f, 0.0625f);
} }
return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z); return new Vec3(worldPosition.x, worldPosition.y, worldPosition.z);
} }
@ -554,21 +599,11 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
var entityToSpawn = ((SmallCannonShellWeapon) getWeapon(0)).create(player); var entityToSpawn = ((SmallCannonShellWeapon) getWeapon(0)).create(player);
entityToSpawn.setPos(worldPosition.x, worldPosition.y, worldPosition.z); entityToSpawn.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
entityToSpawn.shoot(getLookAngle().x, getLookAngle().y - 0.057, getLookAngle().z, 20, 0.5f); entityToSpawn.shoot(getLookAngle().x, getLookAngle().y - 0.07, getLookAngle().z, 30, 0.5f);
level().addFreshEntity(entityToSpawn); level().addFreshEntity(entityToSpawn);
sendParticle((ServerLevel) this.level(), ParticleTypes.LARGE_SMOKE, worldPosition.x, worldPosition.y, worldPosition.z, 1, 0, 0, 0, 0, false); sendParticle((ServerLevel) this.level(), ParticleTypes.LARGE_SMOKE, worldPosition.x, worldPosition.y, worldPosition.z, 1, 0, 0, 0, 0, false);
// BlockPos pos = BlockPos.containing(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z));
// if (!player.level().isClientSide) {
// if (player instanceof ServerPlayer serverPlayer) {
// serverPlayer.level().playSound(null, pos, ModSounds.HPJ_11_FIRE_3P.get(), SoundSource.PLAYERS, 6, random.nextFloat() * 0.05f + 1);
// serverPlayer.level().playSound(null, pos, ModSounds.HPJ_11_FAR.get(), SoundSource.PLAYERS, 12, random.nextFloat() * 0.05f + 1);
// serverPlayer.level().playSound(null, pos, ModSounds.HPJ_11_VERYFAR.get(), SoundSource.PLAYERS, 24, random.nextFloat() * 0.05f + 1);
// }
// }
if (!hasCreativeAmmo) { if (!hasCreativeAmmo) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.SMALL_SHELL.get())).findFirst().ifPresent(stack -> stack.shrink(1)); this.getItemStacks().stream().filter(stack -> stack.is(ModItems.SMALL_SHELL.get())).findFirst().ifPresent(stack -> stack.shrink(1));
} }
@ -615,12 +650,12 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
shootAngle = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).vectorTo(new Vec3(worldPosition2.x, worldPosition2.y, worldPosition2.z)).normalize(); shootAngle = new Vec3(worldPosition.x, worldPosition.y, worldPosition.z).vectorTo(new Vec3(worldPosition2.x, worldPosition2.y, worldPosition2.z)).normalize();
heliRocketEntity.setPos(worldPosition.x, worldPosition.y, worldPosition.z); heliRocketEntity.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
heliRocketEntity.shoot(shootAngle.x, shootAngle.y - 0.08, shootAngle.z, 8, 0.5f); heliRocketEntity.shoot(shootAngle.x, shootAngle.y - 0.075, shootAngle.z, 8, 0.5f);
player.level().addFreshEntity(heliRocketEntity); player.level().addFreshEntity(heliRocketEntity);
BlockPos pos = BlockPos.containing(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z)); BlockPos pos = BlockPos.containing(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z));
this.level().playSound(null, pos, ModSounds.HELICOPTER_ROCKET_FIRE_3P.get(), SoundSource.PLAYERS, 5, 1); this.level().playSound(null, pos, ModSounds.HELICOPTER_ROCKET_FIRE_3P.get(), SoundSource.PLAYERS, 4, 1);
this.entityData.set(LOADED_ROCKET, this.getEntityData().get(LOADED_ROCKET) - 1); this.entityData.set(LOADED_ROCKET, this.getEntityData().get(LOADED_ROCKET) - 1);
@ -634,6 +669,33 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
} }
reloadCoolDown = 15; reloadCoolDown = 15;
} else if (getWeaponIndex(0) == 2 && this.getEntityData().get(LOADED_BOMB) > 0) {
var Mk82Entity = ((Mk82Weapon) getWeapon(0)).create(player);
Vector4f worldPosition;
if (this.getEntityData().get(LOADED_BOMB) == 3) {
worldPosition = transformPosition(transform, -0.55625f, -1.203125f, 0.0625f);
} else if (this.getEntityData().get(LOADED_BOMB) == 2) {
worldPosition = transformPosition(transform, 0f, -1.203125f, 0.0625f);
} else {
worldPosition = transformPosition(transform, 0.55625f, -1.203125f, 0.0625f);
}
Mk82Entity.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
Mk82Entity.shoot(getDeltaMovement().x, getDeltaMovement().y, getDeltaMovement().z, (float) getDeltaMovement().length(), 10);
player.level().addFreshEntity(Mk82Entity);
BlockPos pos = BlockPos.containing(new Vec3(worldPosition.x, worldPosition.y, worldPosition.z));
this.level().playSound(null, pos, ModSounds.BOMB_RELEASE.get(), SoundSource.PLAYERS, 3, 1);
if (this.getEntityData().get(LOADED_BOMB) == 3) {
reloadCoolDownBomb = 200;
}
this.entityData.set(LOADED_BOMB, this.getEntityData().get(LOADED_BOMB) - 1);
} }
} }
@ -647,14 +709,15 @@ public class A10Entity extends ContainerMobileVehicleEntity implements GeoEntity
@Override @Override
public int mainGunRpm(Player player) { public int mainGunRpm(Player player) {
if (getWeaponIndex(0) == 2) {
return 600;
}
return 0; return 0;
} }
@Override @Override
public boolean canShoot(Player player) { public boolean canShoot(Player player) {
if (getWeaponIndex(0) == 0) { if (getWeaponIndex(0) == 2) {
return false;
} else if (getWeaponIndex(0) == 1) {
return this.entityData.get(AMMO) > 0; return this.entityData.get(AMMO) > 0;
} }
return false; return false;

View file

@ -151,7 +151,7 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
if (source.getDirectEntity() instanceof GunGrenadeEntity) { if (source.getDirectEntity() instanceof GunGrenadeEntity) {
return 2.2f * damage; return 2.2f * damage;
} }
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 2f * damage; return 2f * damage;
} }
if (source.getDirectEntity() instanceof RgoGrenadeEntity) { if (source.getDirectEntity() instanceof RgoGrenadeEntity) {

View file

@ -4,10 +4,10 @@ import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.component.ModDataComponents; import com.atsuishio.superbwarfare.component.ModDataComponents;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.AerialBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.C4Entity; import com.atsuishio.superbwarfare.entity.projectile.C4Entity;
import com.atsuishio.superbwarfare.entity.projectile.CannonShellEntity; import com.atsuishio.superbwarfare.entity.projectile.CannonShellEntity;
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.EnergyVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.EnergyVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition; import com.atsuishio.superbwarfare.entity.vehicle.base.ThirdPersonCameraPosition;
@ -216,12 +216,20 @@ public class AnnihilatorEntity extends EnergyVehicleEntity implements GeoEntity,
.multiply(0.3f, ModDamageTypes.CANNON_FIRE) .multiply(0.3f, ModDamageTypes.CANNON_FIRE)
.multiply(0.04f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) .multiply(0.04f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE)
.custom((source, damage) -> getSourceAngle(source, 3) * damage) .custom((source, damage) -> getSourceAngle(source, 3) * damage)
.custom((source, damage) -> switch (source.getDirectEntity()) { .custom((source, damage) -> {
case C4Entity ignored -> 10f * damage; if (source.getDirectEntity() instanceof C4Entity) {
case MelonBombEntity ignored -> 8f * damage; return 10f * damage;
case GunGrenadeEntity ignored -> 3f * damage; }
case CannonShellEntity ignored -> 3f * damage; if (source.getDirectEntity() instanceof AerialBombEntity) {
case null, default -> damage; return 8f * damage;
}
if (source.getDirectEntity() instanceof GunGrenadeEntity) {
return 3f * damage;
}
if (source.getDirectEntity() instanceof CannonShellEntity) {
return 3f * damage;
}
return damage;
}) })
.reduce(12); .reduce(12);
} }

View file

@ -3,8 +3,8 @@ package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.AerialBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity; import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.*; import com.atsuishio.superbwarfare.entity.vehicle.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
@ -167,7 +167,7 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
.multiply(8.5f, ModDamageTypes.VEHICLE_STRIKE) .multiply(8.5f, ModDamageTypes.VEHICLE_STRIKE)
.custom((source, damage) -> getSourceAngle(source, 0.4f) * damage) .custom((source, damage) -> getSourceAngle(source, 0.4f) * damage)
.custom((source, damage) -> { .custom((source, damage) -> {
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 2f * damage; return 2f * damage;
} }
if (source.getDirectEntity() instanceof MortarShellEntity) { if (source.getDirectEntity() instanceof MortarShellEntity) {

View file

@ -3,8 +3,8 @@ package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.AerialBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity; import com.atsuishio.superbwarfare.entity.projectile.MortarShellEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.ContainerMobileVehicleEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.LandArmorEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.LandArmorEntity;
@ -146,7 +146,7 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt
.multiply(10f, ModDamageTypes.VEHICLE_STRIKE) .multiply(10f, ModDamageTypes.VEHICLE_STRIKE)
.custom((source, damage) -> getSourceAngle(source, 0.25f) * damage) .custom((source, damage) -> getSourceAngle(source, 0.25f) * damage)
.custom((source, damage) -> { .custom((source, damage) -> {
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 3f * damage; return 3f * damage;
} }
if (source.getDirectEntity() instanceof MortarShellEntity) { if (source.getDirectEntity() instanceof MortarShellEntity) {

View file

@ -3,8 +3,8 @@ package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.Mod; import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig; import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
import com.atsuishio.superbwarfare.config.server.VehicleConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig;
import com.atsuishio.superbwarfare.entity.projectile.AerialBombEntity;
import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity;
import com.atsuishio.superbwarfare.entity.projectile.MelonBombEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.*; import com.atsuishio.superbwarfare.entity.vehicle.base.*;
import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier; import com.atsuishio.superbwarfare.entity.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.entity.vehicle.weapon.LaserWeapon; import com.atsuishio.superbwarfare.entity.vehicle.weapon.LaserWeapon;
@ -148,7 +148,7 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo
.multiply(4.5f, ModDamageTypes.VEHICLE_STRIKE) .multiply(4.5f, ModDamageTypes.VEHICLE_STRIKE)
.custom((source, damage) -> getSourceAngle(source, 0.4f) * damage) .custom((source, damage) -> getSourceAngle(source, 0.4f) * damage)
.custom((source, damage) -> { .custom((source, damage) -> {
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 2f * damage; return 2f * damage;
} }
if (source.getDirectEntity() instanceof GunGrenadeEntity) { if (source.getDirectEntity() instanceof GunGrenadeEntity) {

View file

@ -120,7 +120,7 @@ public class SpeedboatEntity extends ContainerMobileVehicleEntity implements Geo
if (source.getDirectEntity() instanceof GunGrenadeEntity) { if (source.getDirectEntity() instanceof GunGrenadeEntity) {
return 2.2f * damage; return 2.2f * damage;
} }
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 2f * damage; return 2f * damage;
} }
if (source.getDirectEntity() instanceof RgoGrenadeEntity) { if (source.getDirectEntity() instanceof RgoGrenadeEntity) {

View file

@ -233,7 +233,7 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
.multiply(0.15f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE) .multiply(0.15f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE)
.custom((source, damage) -> getSourceAngle(source, 1f) * damage) .custom((source, damage) -> getSourceAngle(source, 1f) * damage)
.custom((source, damage) -> { .custom((source, damage) -> {
if (source.getDirectEntity() instanceof MelonBombEntity) { if (source.getDirectEntity() instanceof AerialBombEntity) {
return 3f * damage; return 3f * damage;
} }
if (source.getDirectEntity() instanceof SmallCannonShellEntity) { if (source.getDirectEntity() instanceof SmallCannonShellEntity) {

View file

@ -0,0 +1,27 @@
package com.atsuishio.superbwarfare.entity.vehicle.weapon;
import com.atsuishio.superbwarfare.Mod;
import com.atsuishio.superbwarfare.entity.projectile.Mk82Entity;
import net.minecraft.world.entity.LivingEntity;
public class Mk82Weapon extends VehicleWeapon {
public float explosionDamage = 500, explosionRadius = 12;
public Mk82Weapon() {
this.icon = Mod.loc("textures/screens/vehicle_weapon/mk_82.png");
}
public Mk82Weapon explosionDamage(float explosionDamage) {
this.explosionDamage = explosionDamage;
return this;
}
public Mk82Weapon explosionRadius(float explosionRadius) {
this.explosionRadius = explosionRadius;
return this;
}
public Mk82Entity create(LivingEntity entity) {
return new Mk82Entity(entity, entity.level(), explosionDamage, explosionRadius);
}
}

View file

@ -78,6 +78,8 @@ public class ModEntities {
EntityType.Builder.<WgMissileEntity>of(WgMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).noSave().setTrackingRange(64).setUpdateInterval(3).fireImmune().sized(0.5f, 0.5f)); EntityType.Builder.<WgMissileEntity>of(WgMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).noSave().setTrackingRange(64).setUpdateInterval(3).fireImmune().sized(0.5f, 0.5f));
public static final DeferredHolder<EntityType<?>, EntityType<SwarmDroneEntity>> SWARM_DRONE = register("swarm_drone", public static final DeferredHolder<EntityType<?>, EntityType<SwarmDroneEntity>> SWARM_DRONE = register("swarm_drone",
EntityType.Builder.<SwarmDroneEntity>of(SwarmDroneEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).noSave().setTrackingRange(64).setUpdateInterval(1).fireImmune().sized(0.5f, 0.5f)); EntityType.Builder.<SwarmDroneEntity>of(SwarmDroneEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).noSave().setTrackingRange(64).setUpdateInterval(1).fireImmune().sized(0.5f, 0.5f));
public static final DeferredHolder<EntityType<?>, EntityType<Mk82Entity>> MK_82 = register("mk_82",
EntityType.Builder.<Mk82Entity>of(Mk82Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(false).noSave().setTrackingRange(64).setUpdateInterval(1).fireImmune().sized(0.5f, 0.5f));
// Vehicles // Vehicles
public static final DeferredHolder<EntityType<?>, EntityType<Mk42Entity>> MK_42 = register("mk_42", public static final DeferredHolder<EntityType<?>, EntityType<Mk42Entity>> MK_42 = register("mk_42",

View file

@ -50,5 +50,6 @@ public class ModEntityRenderers {
event.registerEntityRenderer(ModEntities.SWARM_DRONE.get(), SwarmDroneRenderer::new); event.registerEntityRenderer(ModEntities.SWARM_DRONE.get(), SwarmDroneRenderer::new);
event.registerEntityRenderer(ModEntities.HPJ_11.get(), Hpj11Renderer::new); event.registerEntityRenderer(ModEntities.HPJ_11.get(), Hpj11Renderer::new);
event.registerEntityRenderer(ModEntities.A_10A.get(), A10Renderer::new); event.registerEntityRenderer(ModEntities.A_10A.get(), A10Renderer::new);
event.registerEntityRenderer(ModEntities.MK_82.get(), Mk82Renderer::new);
} }
} }

View file

@ -119,6 +119,7 @@ public class ModItems {
public static final DeferredHolder<Item, Item> ROCKET_70 = AMMO.register("rocket_70", Rocket70::new); public static final DeferredHolder<Item, Item> ROCKET_70 = AMMO.register("rocket_70", Rocket70::new);
public static final DeferredHolder<Item, Item> WIRE_GUIDE_MISSILE = AMMO.register("wire_guide_missile", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> WIRE_GUIDE_MISSILE = AMMO.register("wire_guide_missile", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, Item> SWARM_DRONE = AMMO.register("swarm_drone", () -> new Item(new Item.Properties())); public static final DeferredHolder<Item, Item> SWARM_DRONE = AMMO.register("swarm_drone", () -> new Item(new Item.Properties()));
public static final DeferredHolder<Item, MediumAerialBomb> MEDIUM_AERIAL_BOMB = AMMO.register("medium_aerial_bomb", MediumAerialBomb::new);
public static final DeferredHolder<Item, BeamTest> BEAM_TEST = AMMO.register("beam_test", BeamTest::new); public static final DeferredHolder<Item, BeamTest> BEAM_TEST = AMMO.register("beam_test", BeamTest::new);
/** /**

View file

@ -445,5 +445,7 @@ public class ModSounds {
public static final DeferredHolder<SoundEvent, SoundEvent> VEHICLE_SWIM = REGISTRY.register("vehicle_swim", () -> SoundEvent.createVariableRangeEvent(Mod.loc("vehicle_swim"))); public static final DeferredHolder<SoundEvent, SoundEvent> VEHICLE_SWIM = REGISTRY.register("vehicle_swim", () -> SoundEvent.createVariableRangeEvent(Mod.loc("vehicle_swim")));
public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE = REGISTRY.register("a10_engine", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine"))); public static final DeferredHolder<SoundEvent, SoundEvent> A_10_ENGINE = REGISTRY.register("a10_engine", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_engine")));
public static final DeferredHolder<SoundEvent, SoundEvent> A_10_FIRE = REGISTRY.register("a10_fire", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_fire"))); public static final DeferredHolder<SoundEvent, SoundEvent> A_10_FIRE = REGISTRY.register("a10_fire", () -> SoundEvent.createVariableRangeEvent(Mod.loc("a10_fire")));
public static final DeferredHolder<SoundEvent, SoundEvent> BOMB_RELEASE = REGISTRY.register("bomb_release", () -> SoundEvent.createVariableRangeEvent(Mod.loc("bomb_release")));
public static final DeferredHolder<SoundEvent, SoundEvent> BOMB_RELOAD = REGISTRY.register("bomb_reload", () -> SoundEvent.createVariableRangeEvent(Mod.loc("bomb_reload")));
} }

View file

@ -0,0 +1,46 @@
package com.atsuishio.superbwarfare.item;
import com.atsuishio.superbwarfare.entity.projectile.Mk82Entity;
import com.atsuishio.superbwarfare.init.ModEntities;
import net.minecraft.ChatFormatting;
import net.minecraft.core.Direction;
import net.minecraft.core.Position;
import net.minecraft.network.chat.Component;
import net.minecraft.world.entity.projectile.Projectile;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.ProjectileItem;
import net.minecraft.world.item.TooltipFlag;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
import javax.annotation.ParametersAreNonnullByDefault;
import java.util.List;
public class MediumAerialBomb extends Item implements ProjectileItem {
public MediumAerialBomb() {
super(new Properties().stacksTo(2));
}
@Override
@ParametersAreNonnullByDefault
public void appendHoverText(ItemStack stack, TooltipContext context, List<Component> tooltipComponents, TooltipFlag tooltipFlag) {
tooltipComponents.add(Component.translatable("des.superbwarfare.medium_aerial_bomb").withStyle(ChatFormatting.GRAY));
}
// TODO 发射音效
@Override
public @NotNull DispenseConfig createDispenseConfig() {
return DispenseConfig.builder()
.power(0.5F)
.uncertainty(1)
.build();
}
@Override
@ParametersAreNonnullByDefault
public @NotNull Projectile asProjectile(Level level, Position pos, ItemStack stack, Direction direction) {
return new Mk82Entity(ModEntities.MK_82.get(), pos.x(), pos.y(), pos.z(), level);
}
}

View file

@ -152,6 +152,17 @@ public abstract class CameraMixin {
return; return;
} }
if (player.getVehicle() instanceof A10Entity a10Entity && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON)) {
setRotation(Mth.lerp(partialTicks, player.yRotO, player.getYRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot()));
if (ClientEventHandler.zoomVehicle) {
setPosition(a10Entity.driverZoomPos(partialTicks).x, a10Entity.driverZoomPos(partialTicks).y, a10Entity.driverZoomPos(partialTicks).z);
} else {
setPosition(a10Entity.driverPos(partialTicks).x, a10Entity.driverPos(partialTicks).y, a10Entity.driverPos(partialTicks).z);
}
info.cancel();
return;
}
if (player.getVehicle() instanceof VehicleEntity vehicle && vehicle instanceof CannonEntity cannon && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) { if (player.getVehicle() instanceof VehicleEntity vehicle && vehicle instanceof CannonEntity cannon && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) {
setRotation(Mth.lerp(partialTicks, player.yRotO, player.getYRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot())); setRotation(Mth.lerp(partialTicks, player.yRotO, player.getYRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot()));
if (!(cannon instanceof AnnihilatorEntity) && ClientEventHandler.zoomVehicle) { if (!(cannon instanceof AnnihilatorEntity) && ClientEventHandler.zoomVehicle) {

View file

@ -1,5 +1,6 @@
package com.atsuishio.superbwarfare.mixins; package com.atsuishio.superbwarfare.mixins;
import com.atsuishio.superbwarfare.entity.vehicle.A10Entity;
import com.atsuishio.superbwarfare.entity.vehicle.PrismTankEntity; import com.atsuishio.superbwarfare.entity.vehicle.PrismTankEntity;
import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity; import com.atsuishio.superbwarfare.entity.vehicle.SpeedboatEntity;
import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity; import com.atsuishio.superbwarfare.entity.vehicle.base.CannonEntity;
@ -68,10 +69,9 @@ public class GameRendererMixin {
poseStack.mulPose(Axis.ZP.rotationDegrees(-r * vehicle.getRoll(partialTicks) + r2 * vehicle.getViewXRot(partialTicks))); poseStack.mulPose(Axis.ZP.rotationDegrees(-r * vehicle.getRoll(partialTicks) + r2 * vehicle.getViewXRot(partialTicks)));
if ( if (!(vehicle instanceof SpeedboatEntity speedboat && entity == speedboat.getFirstPassenger()) &&
!(vehicle instanceof SpeedboatEntity speedboat && entity == speedboat.getFirstPassenger()) && !(vehicle instanceof PrismTankEntity prismTank && entity == prismTank.getFirstPassenger()) &&
!(vehicle instanceof PrismTankEntity prismTank && entity == prismTank.getFirstPassenger()) && !(vehicle instanceof CannonEntity) && !(vehicle instanceof A10Entity)
!(vehicle instanceof CannonEntity)
) { ) {
// fetch eye offset // fetch eye offset
float eye = entity.getEyeHeight(); float eye = entity.getEyeHeight();

View file

@ -0,0 +1,65 @@
{
"format_version": "1.8.0",
"animations": {
"animation.mk_82.start": {
"loop": "hold_on_last_frame",
"animation_length": 0.5,
"bones": {
"wing": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [-67.5, 0, 0]
}
},
"wing2": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [67.5, 0, 0]
}
},
"wing3": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [-67.5, 0, 0]
}
},
"wing4": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [-67.5, 0, 0]
}
},
"move": {
"position": {
"0.25": [0, 0, 0],
"0.5": [0, 0, 5]
}
},
"gan": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [35, 0, 0]
}
},
"gan2": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [-35, 0, 0]
}
},
"gan3": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [0, 35, 0]
}
},
"gan4": {
"rotation": {
"0.25": [0, 0, 0],
"0.5": [0, -35, 0]
}
}
}
}
}
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -167,6 +167,8 @@
"des.superbwarfare.small_shell": "Suitable for 20mm ~ 40mm caliber weapons", "des.superbwarfare.small_shell": "Suitable for 20mm ~ 40mm caliber weapons",
"item.superbwarfare.wire_guide_missile": "Wire Guide Missile", "item.superbwarfare.wire_guide_missile": "Wire Guide Missile",
"item.superbwarfare.swarm_drone": "Swarm Drone", "item.superbwarfare.swarm_drone": "Swarm Drone",
"item.superbwarfare.medium_aerial_bomb": "Medium Aerial Bomb",
"des.superbwarfare.medium_aerial_bomb": "Suitable for A-10 Thunderbolt II",
"item.superbwarfare.firing_parameters": "Firing Parameters", "item.superbwarfare.firing_parameters": "Firing Parameters",
"item.superbwarfare.ancient_cpu": "Ancient CPU", "item.superbwarfare.ancient_cpu": "Ancient CPU",
@ -455,6 +457,7 @@
"entity.superbwarfare.smoke_decoy": "Smoke", "entity.superbwarfare.smoke_decoy": "Smoke",
"entity.superbwarfare.hpj_11": "H/PJ-11 CIWS", "entity.superbwarfare.hpj_11": "H/PJ-11 CIWS",
"entity.superbwarfare.a_10a": "A-10 Thunderbolt II", "entity.superbwarfare.a_10a": "A-10 Thunderbolt II",
"entity.superbwarfare.mk_82": "MK-82 Aerial Bomb",
"key.categories.superbwarfare": "Superb Warfare", "key.categories.superbwarfare": "Superb Warfare",
"key.superbwarfare.hold_zoom": "Zoom (Hold)", "key.superbwarfare.hold_zoom": "Zoom (Hold)",

View file

@ -167,6 +167,8 @@
"des.superbwarfare.small_shell": "适配20mm ~ 40mm口径武器", "des.superbwarfare.small_shell": "适配20mm ~ 40mm口径武器",
"item.superbwarfare.wire_guide_missile": "线控导弹", "item.superbwarfare.wire_guide_missile": "线控导弹",
"item.superbwarfare.swarm_drone": "蜂群无人机", "item.superbwarfare.swarm_drone": "蜂群无人机",
"item.superbwarfare.medium_aerial_bomb": "中型航空炸弹",
"des.superbwarfare.medium_aerial_bomb": "适配A-10攻击机",
"item.superbwarfare.firing_parameters": "射击诸元", "item.superbwarfare.firing_parameters": "射击诸元",
"item.superbwarfare.ancient_cpu": "古代处理器", "item.superbwarfare.ancient_cpu": "古代处理器",
@ -453,6 +455,7 @@
"entity.superbwarfare.smoke_decoy": "烟雾", "entity.superbwarfare.smoke_decoy": "烟雾",
"entity.superbwarfare.hpj_11": "H/PJ-11近防炮", "entity.superbwarfare.hpj_11": "H/PJ-11近防炮",
"entity.superbwarfare.a_10a": "A-10 “雷电II” 攻击机", "entity.superbwarfare.a_10a": "A-10 “雷电II” 攻击机",
"entity.superbwarfare.mk_82": "MK-82 航空炸弹",
"key.categories.superbwarfare": "卓越前线", "key.categories.superbwarfare": "卓越前线",
"key.superbwarfare.hold_zoom": "瞄准(按住)", "key.superbwarfare.hold_zoom": "瞄准(按住)",

View file

@ -3112,5 +3112,23 @@
"name": "superbwarfare:a10/a10_fire" "name": "superbwarfare:a10/a10_fire"
} }
] ]
},
"bomb_release": {
"sounds": [
{
"attenuation_distance": 32,
"stream": true,
"name": "superbwarfare:bomb_release"
}
]
},
"bomb_reload": {
"sounds": [
{
"attenuation_distance": 16,
"stream": true,
"name": "superbwarfare:bomb_reload"
}
]
} }
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB