添加车载烟雾诱饵
This commit is contained in:
parent
cc78351b2f
commit
fefc2303aa
30 changed files with 342 additions and 63 deletions
|
@ -47,6 +47,7 @@ import java.util.concurrent.atomic.AtomicReference;
|
|||
|
||||
import static com.atsuishio.superbwarfare.client.RenderHelper.preciseBlit;
|
||||
import static com.atsuishio.superbwarfare.client.overlay.CrossHairOverlay.*;
|
||||
import static com.atsuishio.superbwarfare.entity.vehicle.base.MobileVehicleEntity.DECOY_COUNT;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class VehicleHudOverlay implements LayeredDraw.Layer {
|
||||
|
@ -233,6 +234,9 @@ public class VehicleHudOverlay implements LayeredDraw.Layer {
|
|||
double heal = mobileVehicle.getHealth() / mobileVehicle.getMaxHealth();
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal(FormatTool.format0D(100 * heal)), w / 2 - 165, h / 2 - 46, Mth.hsvToRgb((float) heal / 3.745318352059925F, 1.0F, 1.0F), false);
|
||||
|
||||
// 诱饵
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("SMOKE " + mobileVehicle.getEntityData().get(DECOY_COUNT)), w / 2 - 165, h / 2 - 36, 0x66FF00, false);
|
||||
|
||||
renderKillIndicator(guiGraphics, w, h);
|
||||
} else if (Minecraft.getInstance().options.getCameraType() == CameraType.THIRD_PERSON_BACK && !ClientEventHandler.zoomVehicle) {
|
||||
Vec3 p = RenderHelper.worldToScreen(new Vec3(Mth.lerp(deltaTracker.getGameTimeDeltaPartialTick(true), player.xo, player.getX()), Mth.lerp(deltaTracker.getGameTimeDeltaPartialTick(true), player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(deltaTracker.getGameTimeDeltaPartialTick(true), player.zo, player.getZ())).add(iLand.getBarrelVec(deltaTracker.getGameTimeDeltaPartialTick(true)).scale(192)), cameraPos);
|
||||
|
@ -258,6 +262,10 @@ public class VehicleHudOverlay implements LayeredDraw.Layer {
|
|||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("HP " +
|
||||
FormatTool.format0D(100 * mobileVehicle.getHealth() / mobileVehicle.getMaxHealth())), 30, 1, Mth.hsvToRgb(0F, (float) health, 1.0F), false);
|
||||
|
||||
if (mobileVehicle.hasDecoy()) {
|
||||
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("SMOKE " + mobileVehicle.getEntityData().get(DECOY_COUNT)), 30, 11, -1, false);
|
||||
}
|
||||
|
||||
poseStack.popPose();
|
||||
poseStack.popPose();
|
||||
}
|
||||
|
|
|
@ -9,14 +9,14 @@ import org.jetbrains.annotations.NotNull;
|
|||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CustomCloudParticle extends TextureSheetParticle {
|
||||
public static FireStarParticleProvider provider(SpriteSet spriteSet) {
|
||||
return new FireStarParticleProvider(spriteSet);
|
||||
public static CustomCloudParticleProvider provider(SpriteSet spriteSet) {
|
||||
return new CustomCloudParticleProvider(spriteSet);
|
||||
}
|
||||
|
||||
public static class FireStarParticleProvider implements ParticleProvider<SimpleParticleType> {
|
||||
public static class CustomCloudParticleProvider implements ParticleProvider<SimpleParticleType> {
|
||||
private final SpriteSet spriteSet;
|
||||
|
||||
public FireStarParticleProvider(SpriteSet spriteSet) {
|
||||
public CustomCloudParticleProvider(SpriteSet spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
package com.atsuishio.superbwarfare.client.particle;
|
||||
|
||||
import net.minecraft.client.multiplayer.ClientLevel;
|
||||
import net.minecraft.client.particle.*;
|
||||
import net.minecraft.core.particles.SimpleParticleType;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.api.distmarker.OnlyIn;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class CustomSmokeParticle extends TextureSheetParticle {
|
||||
public static FireStarParticleProvider provider(SpriteSet spriteSet) {
|
||||
return new FireStarParticleProvider(spriteSet);
|
||||
}
|
||||
|
||||
public static class FireStarParticleProvider implements ParticleProvider<SimpleParticleType> {
|
||||
private final SpriteSet spriteSet;
|
||||
|
||||
public FireStarParticleProvider(SpriteSet spriteSet) {
|
||||
this.spriteSet = spriteSet;
|
||||
}
|
||||
|
||||
public Particle createParticle(@NotNull SimpleParticleType typeIn, @NotNull ClientLevel worldIn, double x, double y, double z, double xSpeed, double ySpeed, double zSpeed) {
|
||||
return new CustomSmokeParticle(worldIn, x, y, z, xSpeed, ySpeed, zSpeed, this.spriteSet);
|
||||
}
|
||||
}
|
||||
|
||||
private final SpriteSet spriteSet;
|
||||
|
||||
protected CustomSmokeParticle(ClientLevel world, double x, double y, double z, double vx, double vy, double vz, SpriteSet spriteSet) {
|
||||
super(world, x, y, z);
|
||||
this.spriteSet = spriteSet;
|
||||
this.setSize(0.4f, 0.4f);
|
||||
this.quadSize *= 10f;
|
||||
this.lifetime = this.random.nextInt(200) + 600;
|
||||
this.gravity = 0.001f;
|
||||
this.hasPhysics = false;
|
||||
this.xd = vx * 0.9;
|
||||
this.yd = vy * 0.9;
|
||||
this.zd = vz * 0.9;
|
||||
this.setSpriteFromAge(spriteSet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getLightColor(float partialTick) {
|
||||
return 15728880;
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NotNull ParticleRenderType getRenderType() {
|
||||
return ParticleRenderType.PARTICLE_SHEET_TRANSLUCENT;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
if (!this.removed) {
|
||||
this.setSprite(this.spriteSet.get(Math.min((this.age / 8) + 1, 8), 8));
|
||||
}
|
||||
if (this.age++ < this.lifetime && !(this.alpha <= 0.0F)) {
|
||||
if (this.age >= this.lifetime - 60 && this.alpha > 0.01F) {
|
||||
this.alpha -= 0.015F;
|
||||
}
|
||||
} else {
|
||||
this.remove();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.atsuishio.superbwarfare.client.renderer.entity;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.projectile.SmokeDecoyEntity;
|
||||
import com.mojang.blaze3d.vertex.PoseStack;
|
||||
import net.minecraft.client.renderer.MultiBufferSource;
|
||||
import net.minecraft.client.renderer.entity.EntityRenderer;
|
||||
import net.minecraft.client.renderer.entity.EntityRendererProvider;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
public class SmokeDecoyEntityRenderer extends EntityRenderer<SmokeDecoyEntity> {
|
||||
public SmokeDecoyEntityRenderer(EntityRendererProvider.Context pContext) {
|
||||
super(pContext);
|
||||
}
|
||||
|
||||
@ParametersAreNonnullByDefault
|
||||
public void render(SmokeDecoyEntity pEntity, float pEntityYaw, float pPartialTicks, PoseStack pMatrixStack, MultiBufferSource pBuffer, int pPackedLight) {
|
||||
super.render(pEntity, pEntityYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureLocation(@NotNull SmokeDecoyEntity flareDecoy) {
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package com.atsuishio.superbwarfare.entity.projectile;
|
||||
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
|
||||
public interface DecoyEntity {
|
||||
String getStringUUID();
|
||||
|
||||
Vec3 getPosition();
|
||||
}
|
|
@ -9,19 +9,18 @@ import net.minecraft.server.level.ServerLevel;
|
|||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.LivingEntity;
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class FlareDecoyEntity extends Entity {
|
||||
public class FlareDecoyEntity extends Entity implements DecoyEntity {
|
||||
|
||||
public FlareDecoyEntity(EntityType<? extends FlareDecoyEntity> type, Level world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
public FlareDecoyEntity(LivingEntity entity, Level level) {
|
||||
public FlareDecoyEntity(Level level) {
|
||||
super(ModEntities.FLARE_DECOY.get(), level);
|
||||
}
|
||||
|
||||
|
@ -54,7 +53,7 @@ public class FlareDecoyEntity extends Entity {
|
|||
}
|
||||
|
||||
public void decoyShoot(Entity entity, Vec3 shootVec, float pVelocity, float pInaccuracy) {
|
||||
Vec3 vec3 = shootVec.normalize().add(this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy)).scale((double) pVelocity);
|
||||
Vec3 vec3 = shootVec.normalize().add(this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy)).scale(pVelocity);
|
||||
this.setDeltaMovement(entity.getDeltaMovement().scale(0.75).add(vec3));
|
||||
double d0 = vec3.horizontalDistance();
|
||||
this.setYRot((float) (Mth.atan2(vec3.x, vec3.z) * 57.2957763671875));
|
||||
|
@ -62,4 +61,9 @@ public class FlareDecoyEntity extends Entity {
|
|||
this.yRotO = this.getYRot();
|
||||
this.xRotO = this.getXRot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getPosition() {
|
||||
return position();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -215,11 +215,11 @@ public class JavelinMissileEntity extends FastThrowableProjectile implements Geo
|
|||
public void tick() {
|
||||
super.tick();
|
||||
Entity entity = EntityFindUtil.findEntity(this.level(), entityData.get(TARGET_UUID));
|
||||
List<Entity> decoy = SeekTool.seekLivingEntities(this, this.level(), 48, 160);
|
||||
List<Entity> decoy = SeekTool.seekLivingEntities(this, this.level(), 32, 90);
|
||||
|
||||
for (var e : decoy) {
|
||||
if (e instanceof FlareDecoyEntity flareDecoy && !distracted) {
|
||||
this.entityData.set(TARGET_UUID, flareDecoy.getStringUUID());
|
||||
if (e instanceof DecoyEntity decoyEntity && !distracted) {
|
||||
this.entityData.set(TARGET_UUID, decoyEntity.getStringUUID());
|
||||
distracted = true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,72 @@
|
|||
package com.atsuishio.superbwarfare.entity.projectile;
|
||||
|
||||
import com.atsuishio.superbwarfare.init.ModEntities;
|
||||
import com.atsuishio.superbwarfare.init.ModParticleTypes;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
import net.minecraft.network.syncher.SynchedEntityData;
|
||||
import net.minecraft.server.level.ServerLevel;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraft.world.phys.Vec3;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class SmokeDecoyEntity extends Entity implements DecoyEntity {
|
||||
|
||||
public SmokeDecoyEntity(EntityType<? extends SmokeDecoyEntity> type, Level world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
public SmokeDecoyEntity(Level level) {
|
||||
super(ModEntities.SMOKE_DECOY.get(), level);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(@NotNull CompoundTag compoundTag) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addAdditionalSaveData(@NotNull CompoundTag compoundTag) {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void defineSynchedData(SynchedEntityData.@NotNull Builder builder) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tick() {
|
||||
super.tick();
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
if (tickCount == 4) {
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
ParticleTool.sendParticle(serverLevel, ModParticleTypes.CUSTOM_SMOKE.get(), this.xo, this.yo, this.zo,
|
||||
100, 0, 0, 0, 0.07, true);
|
||||
}
|
||||
this.level().playSound(null, this, ModSounds.SMOKE_FIRE.get(), this.getSoundSource(), 1, random.nextFloat() * 0.05f + 1);
|
||||
this.setDeltaMovement(Vec3.ZERO);
|
||||
}
|
||||
|
||||
if (this.tickCount > 400) {
|
||||
this.discard();
|
||||
}
|
||||
}
|
||||
|
||||
public void decoyShoot(Entity entity, Vec3 shootVec, float pVelocity, float pInaccuracy) {
|
||||
Vec3 vec3 = shootVec.normalize().add(this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double) pInaccuracy)).scale((double) pVelocity);
|
||||
this.setDeltaMovement(entity.getDeltaMovement().scale(0.75).add(vec3));
|
||||
double d0 = vec3.horizontalDistance();
|
||||
this.setYRot((float) (Mth.atan2(vec3.x, vec3.z) * 57.2957763671875));
|
||||
this.setXRot((float) (Mth.atan2(vec3.y, d0) * 57.2957763671875));
|
||||
this.yRotO = this.getYRot();
|
||||
this.xRotO = this.getXRot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Vec3 getPosition() {
|
||||
return position();
|
||||
}
|
||||
}
|
|
@ -178,7 +178,7 @@ public class WgMissileEntity extends FastThrowableProjectile implements GeoEntit
|
|||
Entity lookingEntity = TraceTool.vehiclefFindLookingEntity(vehicle, vehicle.getNewEyePos(1), 512);
|
||||
Vec3 toVec;
|
||||
|
||||
if (lookingEntity != null) {
|
||||
if (lookingEntity != null && lookingEntity != this) {
|
||||
toVec = this.position().vectorTo(lookingEntity.getEyePosition()).normalize();
|
||||
} else {
|
||||
BlockHitResult result = level().clip(new ClipContext(vehicle.getNewEyePos(1), vehicle.getNewEyePos(1).add(lookVec.scale(512)),
|
||||
|
|
|
@ -67,13 +67,11 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
|
|||
|
||||
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
||||
public static final EntityDataAccessor<Float> PROPELLER_ROT = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.FLOAT);
|
||||
public static final EntityDataAccessor<Integer> DECOY_COUNT = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.INT);
|
||||
public static final EntityDataAccessor<Integer> LOADED_ROCKET = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.INT);
|
||||
public boolean engineStart;
|
||||
public boolean engineStartOver;
|
||||
|
||||
public double velocity;
|
||||
public int decoyReloadCoolDown;
|
||||
public int fireIndex;
|
||||
public int holdTick;
|
||||
public int holdPowerTick;
|
||||
|
@ -117,8 +115,7 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
|
|||
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
||||
super.defineSynchedData(builder);
|
||||
builder.define(LOADED_ROCKET, 0)
|
||||
.define(PROPELLER_ROT, 0f)
|
||||
.define(DECOY_COUNT, 3);
|
||||
.define(PROPELLER_ROT, 0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -126,7 +123,6 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
|
|||
super.addAdditionalSaveData(compound);
|
||||
compound.putInt("LoadedRocket", this.entityData.get(LOADED_ROCKET));
|
||||
compound.putFloat("PropellerRot", this.entityData.get(PROPELLER_ROT));
|
||||
compound.putInt("DecoyCount", this.entityData.get(DECOY_COUNT));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -134,7 +130,6 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
|
|||
super.readAdditionalSaveData(compound);
|
||||
this.entityData.set(LOADED_ROCKET, compound.getInt("LoadedRocket"));
|
||||
this.entityData.set(PROPELLER_ROT, compound.getFloat("PropellerRot"));
|
||||
this.entityData.set(DECOY_COUNT, compound.getInt("DecoyCount"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -189,9 +184,6 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
|
|||
if (reloadCoolDown > 0) {
|
||||
reloadCoolDown--;
|
||||
}
|
||||
if (decoyReloadCoolDown > 0) {
|
||||
decoyReloadCoolDown--;
|
||||
}
|
||||
handleAmmo();
|
||||
}
|
||||
|
||||
|
@ -242,31 +234,6 @@ public class Ah6Entity extends ContainerMobileVehicleEntity implements GeoEntity
|
|||
}
|
||||
}
|
||||
|
||||
public void releaseDecoy() {
|
||||
if (decoyInputDown) {
|
||||
if (this.entityData.get(DECOY_COUNT) > 0 && this.level() instanceof ServerLevel) {
|
||||
Entity passenger = getFirstPassenger();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
FlareDecoyEntity flareDecoyEntity = new FlareDecoyEntity((LivingEntity) passenger, this.level());
|
||||
flareDecoyEntity.setPos(this.getX() + this.getDeltaMovement().x, this.getY() + 0.5 + this.getDeltaMovement().y, this.getZ() + this.getDeltaMovement().z);
|
||||
flareDecoyEntity.decoyShoot(this, this.getViewVector(1).yRot((45 + 90 * i) * Mth.DEG_TO_RAD), 0.8f, 8);
|
||||
this.level().addFreshEntity(flareDecoyEntity);
|
||||
}
|
||||
this.level().playSound(null, this, ModSounds.DECOY_FIRE.get(), this.getSoundSource(), 1, 1);
|
||||
if (this.getEntityData().get(DECOY_COUNT) == 3) {
|
||||
decoyReloadCoolDown = 300;
|
||||
}
|
||||
this.getEntityData().set(DECOY_COUNT, this.getEntityData().get(DECOY_COUNT) - 1);
|
||||
}
|
||||
decoyInputDown = false;
|
||||
}
|
||||
if (this.entityData.get(DECOY_COUNT) < 3 && decoyReloadCoolDown == 0 && this.level() instanceof ServerLevel) {
|
||||
this.entityData.set(DECOY_COUNT, this.entityData.get(DECOY_COUNT) + 1);
|
||||
this.level().playSound(null, this, ModSounds.DECOY_RELOAD.get(), this.getSoundSource(), 1, 1);
|
||||
decoyReloadCoolDown = 300;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void travel() {
|
||||
Entity passenger = getFirstPassenger();
|
||||
|
|
|
@ -235,6 +235,8 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
|
|||
this.terrainCompat(4f, 5f);
|
||||
inertiaRotate(1);
|
||||
|
||||
releaseSmokeDecoy();
|
||||
|
||||
lowHealthWarning();
|
||||
this.refreshDimensions();
|
||||
}
|
||||
|
@ -716,4 +718,9 @@ public class Bmp2Entity extends ContainerMobileVehicleEntity implements GeoEntit
|
|||
guiGraphics.drawString(font, Component.literal("9M113 " + this.getEntityData().get(LOADED_MISSILE) + " " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : this.getEntityData().get(MISSILE_COUNT))), 30, -9, -1, false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDecoy() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -454,7 +454,7 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity {
|
|||
final Vec3 center = new Vec3(this.getX(), this.getY(), this.getZ());
|
||||
for (Entity target : level.getEntitiesOfClass(Entity.class, aabb, e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) {
|
||||
if (this != target && target != null
|
||||
&& !(target instanceof ItemEntity || target instanceof Projectile || target instanceof ProjectileEntity || target instanceof LaserEntity || target instanceof FlareDecoyEntity || target instanceof AreaEffectCloud || target instanceof C4Entity)) {
|
||||
&& !(target instanceof ItemEntity || target instanceof Projectile || target instanceof ProjectileEntity || target instanceof LaserEntity || target instanceof DecoyEntity || target instanceof AreaEffectCloud || target instanceof C4Entity)) {
|
||||
hitEntityCrash(controller, target);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -191,6 +191,8 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt
|
|||
this.terrainCompat(2.7f, 3.61f);
|
||||
inertiaRotate(1.25f);
|
||||
|
||||
releaseSmokeDecoy();
|
||||
|
||||
this.refreshDimensions();
|
||||
}
|
||||
|
||||
|
@ -621,4 +623,9 @@ public class Lav150Entity extends ContainerMobileVehicleEntity implements GeoEnt
|
|||
guiGraphics.drawString(font, Component.literal("7.62MM COAX " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : this.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDecoy() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,6 +219,8 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo
|
|||
this.terrainCompat(4.6375f, 5.171875f);
|
||||
inertiaRotate(1);
|
||||
|
||||
releaseSmokeDecoy();
|
||||
|
||||
lowHealthWarning();
|
||||
this.refreshDimensions();
|
||||
}
|
||||
|
@ -760,4 +762,9 @@ public class PrismTankEntity extends ContainerMobileVehicleEntity implements Geo
|
|||
double heat = this.getEntityData().get(HEAT) / 100.0F;
|
||||
guiGraphics.drawString(font, Component.literal("LASER " + (this.getEntityData().get(HEAT) + 25) + " ℃"), 30, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDecoy() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -332,6 +332,8 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
|
|||
this.terrainCompat(4.6f, 6.7f);
|
||||
inertiaRotate(1.2f);
|
||||
|
||||
releaseSmokeDecoy();
|
||||
|
||||
this.refreshDimensions();
|
||||
}
|
||||
|
||||
|
@ -1219,4 +1221,9 @@ public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEnti
|
|||
guiGraphics.drawString(font, Component.literal("12.7MM HMG " + (InventoryTool.hasCreativeAmmoBox(player) ? "∞" : this.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasDecoy() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@ package com.atsuishio.superbwarfare.entity.vehicle.base;
|
|||
|
||||
import com.atsuishio.superbwarfare.config.server.VehicleConfig;
|
||||
import com.atsuishio.superbwarfare.entity.TargetEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.SmokeDecoyEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.DroneEntity;
|
||||
import com.atsuishio.superbwarfare.init.ModDamageTypes;
|
||||
import com.atsuishio.superbwarfare.init.ModSounds;
|
||||
|
@ -52,7 +54,9 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements
|
|||
public static final EntityDataAccessor<Integer> COAX_HEAT = SynchedEntityData.defineId(MobileVehicleEntity.class, EntityDataSerializers.INT);
|
||||
|
||||
public static final EntityDataAccessor<Integer> AMMO = SynchedEntityData.defineId(MobileVehicleEntity.class, EntityDataSerializers.INT);
|
||||
public static final EntityDataAccessor<Integer> DECOY_COUNT = SynchedEntityData.defineId(MobileVehicleEntity.class, EntityDataSerializers.INT);
|
||||
|
||||
public int decoyReloadCoolDown;
|
||||
public static boolean IGNORE_ENTITY_GROUND_CHECK_STEPPING = false;
|
||||
public boolean leftInputDown;
|
||||
public boolean rightInputDown;
|
||||
|
@ -193,6 +197,10 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements
|
|||
cannotFireCoax = false;
|
||||
}
|
||||
|
||||
if (decoyReloadCoolDown > 0) {
|
||||
decoyReloadCoolDown--;
|
||||
}
|
||||
|
||||
if (this.entityData.get(HEAT) > 100 && !cannotFire) {
|
||||
cannotFire = true;
|
||||
this.level().playSound(null, this.getOnPos(), ModSounds.MINIGUN_OVERHEAT.get(), SoundSource.PLAYERS, 1, 1);
|
||||
|
@ -220,6 +228,56 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements
|
|||
this.refreshDimensions();
|
||||
}
|
||||
|
||||
//烟雾诱饵
|
||||
public void releaseSmokeDecoy() {
|
||||
if (decoyInputDown) {
|
||||
if (this.entityData.get(DECOY_COUNT) > 0 && this.level() instanceof ServerLevel) {
|
||||
Entity passenger = getFirstPassenger();
|
||||
for (int i = 0; i < 16; i++) {
|
||||
SmokeDecoyEntity smokeDecoyEntity = new SmokeDecoyEntity(this.level());
|
||||
smokeDecoyEntity.setPos(this.getX(), this.getY() + 2, this.getZ());
|
||||
smokeDecoyEntity.decoyShoot(this, this.getViewVector(1).yRot((11.25F + 22.5F * i) * Mth.DEG_TO_RAD), 3.2f, 8);
|
||||
this.level().addFreshEntity(smokeDecoyEntity);
|
||||
}
|
||||
this.level().playSound(null, this, ModSounds.DECOY_FIRE.get(), this.getSoundSource(), 1, 1);
|
||||
decoyReloadCoolDown = 400;
|
||||
this.getEntityData().set(DECOY_COUNT, this.getEntityData().get(DECOY_COUNT) - 1);
|
||||
}
|
||||
decoyInputDown = false;
|
||||
}
|
||||
if (this.entityData.get(DECOY_COUNT) < 1 && decoyReloadCoolDown == 0 && this.level() instanceof ServerLevel) {
|
||||
this.entityData.set(DECOY_COUNT, this.entityData.get(DECOY_COUNT) + 1);
|
||||
this.level().playSound(null, this, ModSounds.DECOY_RELOAD.get(), this.getSoundSource(), 1, 1);
|
||||
decoyReloadCoolDown = 400;
|
||||
}
|
||||
}
|
||||
|
||||
//热诱弹诱饵
|
||||
public void releaseDecoy() {
|
||||
if (decoyInputDown) {
|
||||
if (this.entityData.get(DECOY_COUNT) > 0 && this.level() instanceof ServerLevel) {
|
||||
Entity passenger = getFirstPassenger();
|
||||
for (int i = 0; i < 4; i++) {
|
||||
FlareDecoyEntity flareDecoyEntity = new FlareDecoyEntity(this.level());
|
||||
flareDecoyEntity.setPos(this.getX() + this.getDeltaMovement().x, this.getY() + 0.5 + this.getDeltaMovement().y, this.getZ() + this.getDeltaMovement().z);
|
||||
flareDecoyEntity.decoyShoot(this, this.getViewVector(1).yRot((45 + 90 * i) * Mth.DEG_TO_RAD), 0.8f, 8);
|
||||
this.level().addFreshEntity(flareDecoyEntity);
|
||||
}
|
||||
this.level().playSound(null, this, ModSounds.DECOY_FIRE.get(), this.getSoundSource(), 1, 1);
|
||||
if (this.getEntityData().get(DECOY_COUNT) == 3) {
|
||||
decoyReloadCoolDown = 300;
|
||||
}
|
||||
this.getEntityData().set(DECOY_COUNT, this.getEntityData().get(DECOY_COUNT) - 1);
|
||||
}
|
||||
decoyInputDown = false;
|
||||
}
|
||||
if (this.entityData.get(DECOY_COUNT) < 3 && decoyReloadCoolDown == 0 && this.level() instanceof ServerLevel) {
|
||||
this.entityData.set(DECOY_COUNT, this.entityData.get(DECOY_COUNT) + 1);
|
||||
this.level().playSound(null, this, ModSounds.DECOY_RELOAD.get(), this.getSoundSource(), 1, 1);
|
||||
decoyReloadCoolDown = 300;
|
||||
}
|
||||
}
|
||||
|
||||
// 惯性倾斜
|
||||
|
||||
public void inertiaRotate(float multiple) {
|
||||
|
@ -646,28 +704,35 @@ public abstract class MobileVehicleEntity extends EnergyVehicleEntity implements
|
|||
this.recoilShake = pRecoilShake;
|
||||
}
|
||||
|
||||
public boolean hasDecoy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void defineSynchedData(SynchedEntityData.Builder builder) {
|
||||
super.defineSynchedData(builder);
|
||||
builder.define(CANNON_RECOIL_TIME, 0);
|
||||
builder.define(POWER, 0f);
|
||||
builder.define(YAW, 0f);
|
||||
builder.define(AMMO, 0);
|
||||
builder.define(FIRE_ANIM, 0);
|
||||
builder.define(HEAT, 0);
|
||||
builder.define(COAX_HEAT, 0);
|
||||
builder.define(CANNON_RECOIL_TIME, 0)
|
||||
.define(POWER, 0f)
|
||||
.define(YAW, 0f)
|
||||
.define(AMMO, 0)
|
||||
.define(FIRE_ANIM, 0)
|
||||
.define(HEAT, 0)
|
||||
.define(COAX_HEAT, 0)
|
||||
.define(DECOY_COUNT, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readAdditionalSaveData(CompoundTag compound) {
|
||||
super.readAdditionalSaveData(compound);
|
||||
this.entityData.set(POWER, compound.getFloat("Power"));
|
||||
this.entityData.set(DECOY_COUNT, compound.getInt("DecoyCount"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag compound) {
|
||||
super.addAdditionalSaveData(compound);
|
||||
compound.putFloat("Power", this.entityData.get(POWER));
|
||||
compound.putInt("DecoyCount", this.entityData.get(DECOY_COUNT));
|
||||
}
|
||||
|
||||
public boolean canCrushEntities() {
|
||||
|
|
|
@ -36,6 +36,8 @@ public class ModEntities {
|
|||
EntityType.Builder.<LaserEntity>of(LaserEntity::new, MobCategory.MISC).sized(0.1f, 0.1f).fireImmune().setUpdateInterval(1));
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<FlareDecoyEntity>> FLARE_DECOY = register("flare_decoy",
|
||||
EntityType.Builder.<FlareDecoyEntity>of(FlareDecoyEntity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).sized(0.5f, 0.5f));
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<SmokeDecoyEntity>> SMOKE_DECOY = register("smoke_decoy",
|
||||
EntityType.Builder.<SmokeDecoyEntity>of(SmokeDecoyEntity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).noSave().sized(3f, 3f));
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<ClaymoreEntity>> CLAYMORE = register("claymore",
|
||||
EntityType.Builder.<ClaymoreEntity>of(ClaymoreEntity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).sized(0.5f, 0.5f));
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<C4Entity>> C_4 = register("c4",
|
||||
|
@ -101,7 +103,7 @@ public class ModEntities {
|
|||
EntityType.Builder.of(Yx100Entity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).fireImmune().sized(5.5f, 3.25f));
|
||||
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<DroneEntity>> DRONE = register("drone",
|
||||
EntityType.Builder.<DroneEntity>of(DroneEntity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).sized(0.6f, 0.2f));
|
||||
EntityType.Builder.of(DroneEntity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).sized(0.6f, 0.2f));
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<LaserTowerEntity>> LASER_TOWER = register("laser_tower",
|
||||
EntityType.Builder.<LaserTowerEntity>of(LaserTowerEntity::new, MobCategory.MISC).setTrackingRange(64).setUpdateInterval(1).fireImmune().sized(0.9f, 1.65f));
|
||||
public static final DeferredHolder<EntityType<?>, EntityType<PrismTankEntity>> PRISM_TANK = register("prism_tank",
|
||||
|
|
|
@ -36,6 +36,7 @@ public class ModEntityRenderers {
|
|||
event.registerEntityRenderer(ModEntities.WHEEL_CHAIR.get(), WheelChairRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.AH_6.get(), Ah6Renderer::new);
|
||||
event.registerEntityRenderer(ModEntities.FLARE_DECOY.get(), FlareDecoyEntityRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.SMOKE_DECOY.get(), SmokeDecoyEntityRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.LAV_150.get(), Lav150Renderer::new);
|
||||
event.registerEntityRenderer(ModEntities.SMALL_CANNON_SHELL.get(), SmallCannonShellRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.TOM_6.get(), Tom6Renderer::new);
|
||||
|
|
|
@ -13,5 +13,6 @@ public class ModParticleTypes {
|
|||
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> FIRE_STAR = REGISTRY.register("fire_star", () -> new SimpleParticleType(false));
|
||||
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> BULLET_HOLE = REGISTRY.register("bullet_hole", () -> new SimpleParticleType(false));
|
||||
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> CUSTOM_CLOUD = REGISTRY.register("custom_cloud", () -> new SimpleParticleType(false));
|
||||
public static final DeferredHolder<ParticleType<?>, SimpleParticleType> CUSTOM_SMOKE = REGISTRY.register("custom_smoke", () -> new SimpleParticleType(false));
|
||||
}
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.atsuishio.superbwarfare.init;
|
|||
|
||||
import com.atsuishio.superbwarfare.client.particle.BulletHoleParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.CustomCloudParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.CustomSmokeParticle;
|
||||
import com.atsuishio.superbwarfare.client.particle.FireStarParticle;
|
||||
import net.neoforged.api.distmarker.Dist;
|
||||
import net.neoforged.bus.api.SubscribeEvent;
|
||||
|
@ -15,6 +16,7 @@ public class ModParticles {
|
|||
event.registerSpriteSet(ModParticleTypes.FIRE_STAR.get(), FireStarParticle::provider);
|
||||
event.registerSpriteSet(ModParticleTypes.BULLET_HOLE.get(), BulletHoleParticle::provider);
|
||||
event.registerSpriteSet(ModParticleTypes.CUSTOM_CLOUD.get(), CustomCloudParticle::provider);
|
||||
event.registerSpriteSet(ModParticleTypes.CUSTOM_SMOKE.get(), CustomSmokeParticle::provider);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -438,6 +438,7 @@ public class ModSounds {
|
|||
public static final DeferredHolder<SoundEvent, SoundEvent> INSIDIOUS_FAR = REGISTRY.register("insidious_far", () -> SoundEvent.createVariableRangeEvent(Mod.loc("insidious_far")));
|
||||
public static final DeferredHolder<SoundEvent, SoundEvent> INSIDIOUS_VERYFAR = REGISTRY.register("insidious_veryfar", () -> SoundEvent.createVariableRangeEvent(Mod.loc("insidious_veryfar")));
|
||||
public static final DeferredHolder<SoundEvent, SoundEvent> INSIDIOUS_RELOAD_EMPTY = REGISTRY.register("insidious_reload_empty", () -> SoundEvent.createVariableRangeEvent(Mod.loc("insidious_reload_empty")));
|
||||
public static final DeferredHolder<SoundEvent, SoundEvent> SMOKE_FIRE = REGISTRY.register("smoke_fire", () -> SoundEvent.createVariableRangeEvent(Mod.loc("smoke_fire")));
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.item.gun.launcher;
|
|||
import com.atsuishio.superbwarfare.Mod;
|
||||
import com.atsuishio.superbwarfare.client.renderer.item.JavelinItemRenderer;
|
||||
import com.atsuishio.superbwarfare.client.tooltip.component.LauncherImageComponent;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.DecoyEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.JavelinMissileEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import com.atsuishio.superbwarfare.event.ClientEventHandler;
|
||||
|
@ -143,11 +143,11 @@ public class JavelinItem extends GunItem implements GeoItem, SpecialFireWeapon {
|
|||
|
||||
List<Entity> decoy = SeekTool.seekLivingEntities(player, player.level(), 512, 8);
|
||||
for (var e : decoy) {
|
||||
if (e instanceof FlareDecoyEntity flareDecoy) {
|
||||
tag.putString("TargetEntity", flareDecoy.getStringUUID());
|
||||
tag.putDouble("TargetPosX", flareDecoy.getX());
|
||||
tag.putDouble("TargetPosY", flareDecoy.getEyeY());
|
||||
tag.putDouble("TargetPosZ", flareDecoy.getZ());
|
||||
if (e instanceof DecoyEntity decoyEntity) {
|
||||
tag.putString("TargetEntity", decoyEntity.getStringUUID());
|
||||
tag.putDouble("TargetPosX", decoyEntity.getPosition().x);
|
||||
tag.putDouble("TargetPosY", decoyEntity.getPosition().y);
|
||||
tag.putDouble("TargetPosZ", decoyEntity.getPosition().z);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import net.neoforged.neoforge.network.handling.IPayloadContext;
|
|||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public record TacticalSprintMessage(boolean sprint) implements CustomPacketPayload {
|
||||
public static final Type<TacticalSprintMessage> TYPE = new Type<>(Mod.loc("vehicle_fire"));
|
||||
public static final Type<TacticalSprintMessage> TYPE = new Type<>(Mod.loc("tactical_sprint"));
|
||||
|
||||
public static final StreamCodec<ByteBuf, TacticalSprintMessage> STREAM_CODEC = StreamCodec.composite(
|
||||
ByteBufCodecs.BOOL,
|
||||
|
|
|
@ -48,6 +48,7 @@ public class ParticleTool {
|
|||
sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, x, y, z, 3, 0.1, 0.1, 0.1, 0.02, true);
|
||||
sendParticle(serverLevel, ParticleTypes.LARGE_SMOKE, x, y, z, 4, 0.2, 0.2, 0.2, 0.02, true);
|
||||
sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), x, y, z, 6, 0, 0, 0, 0.2, true);
|
||||
sendParticle(serverLevel, ModParticleTypes.CUSTOM_SMOKE.get(), x, y, z, 400, 0.2, 0.2, 0.2, 0.05, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
package com.atsuishio.superbwarfare.tools;
|
||||
|
||||
import com.atsuishio.superbwarfare.entity.projectile.DecoyEntity;
|
||||
import com.atsuishio.superbwarfare.entity.projectile.DestroyableProjectileEntity;
|
||||
import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity;
|
||||
import net.minecraft.core.BlockPos;
|
||||
|
@ -105,7 +106,7 @@ public class TraceTool {
|
|||
Vec3 viewVec = vehicle.getBarrelVector(1);
|
||||
Vec3 toVec = eye.add(viewVec.x * entityReach, viewVec.y * entityReach, viewVec.z * entityReach);
|
||||
AABB aabb = vehicle.getBoundingBox().expandTowards(viewVec.scale(entityReach)).inflate(1.0D, 1.0D, 1.0D);
|
||||
EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(vehicle, eye, toVec, aabb, p -> !p.isSpectator() && p.isAlive() && !(p instanceof Projectile && !(p instanceof DestroyableProjectileEntity)), distance);
|
||||
EntityHitResult entityhitresult = ProjectileUtil.getEntityHitResult(vehicle, eye, toVec, aabb, p -> !p.isSpectator() && p.isAlive() && !(p instanceof Projectile && !(p instanceof DestroyableProjectileEntity)) && SeekTool.baseFilter(p) && !(p instanceof DecoyEntity), distance);
|
||||
if (entityhitresult != null) {
|
||||
hitResult = entityhitresult;
|
||||
|
||||
|
|
|
@ -443,6 +443,7 @@
|
|||
"entity.superbwarfare.laser_tower": "Laser Defense Tower",
|
||||
"entity.superbwarfare.prism_tank": "Prism Tank",
|
||||
"entity.superbwarfare.swarm_drone": "Swarm Drone",
|
||||
"entity.superbwarfare.smoke_decoy": "Smoke",
|
||||
|
||||
"key.categories.superbwarfare": "Superb Warfare",
|
||||
"key.superbwarfare.hold_zoom": "Zoom (Hold)",
|
||||
|
|
|
@ -441,6 +441,7 @@
|
|||
"entity.superbwarfare.laser_tower": "激光防御塔",
|
||||
"entity.superbwarfare.prism_tank": "光棱坦克",
|
||||
"entity.superbwarfare.swarm_drone": "蜂群无人机",
|
||||
"entity.superbwarfare.smoke_decoy": "烟雾",
|
||||
|
||||
"key.categories.superbwarfare": "卓越前线",
|
||||
"key.superbwarfare.hold_zoom": "瞄准(按住)",
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"textures": [
|
||||
"minecraft:generic_0",
|
||||
"minecraft:generic_1",
|
||||
"minecraft:generic_2",
|
||||
"minecraft:generic_3",
|
||||
"minecraft:generic_4",
|
||||
"minecraft:generic_5",
|
||||
"minecraft:generic_6",
|
||||
"minecraft:generic_7"
|
||||
]
|
||||
}
|
|
@ -3035,5 +3035,13 @@
|
|||
"stream": false
|
||||
}
|
||||
]
|
||||
},
|
||||
"smoke_fire": {
|
||||
"sounds": [
|
||||
{
|
||||
"name": "superbwarfare:smoke_fire",
|
||||
"stream": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
BIN
src/main/resources/assets/superbwarfare/sounds/smoke_fire.ogg
Normal file
BIN
src/main/resources/assets/superbwarfare/sounds/smoke_fire.ogg
Normal file
Binary file not shown.
Loading…
Add table
Reference in a new issue