diff --git a/src/main/java/com/atsuishio/superbwarfare/client/layer/Lav150Layer.java b/src/main/java/com/atsuishio/superbwarfare/client/layer/Lav150Layer.java new file mode 100644 index 000000000..15fbc8c21 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/layer/Lav150Layer.java @@ -0,0 +1,28 @@ +package com.atsuishio.superbwarfare.client.layer; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.entity.vehicle.Lav150Entity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.cache.object.BakedGeoModel; +import software.bernie.geckolib.renderer.GeoRenderer; +import software.bernie.geckolib.renderer.layer.GeoRenderLayer; + +public class Lav150Layer extends GeoRenderLayer { + + private static final ResourceLocation LAYER = ModUtils.loc("textures/entity/speedboat_e.png"); + + public Lav150Layer(GeoRenderer entityRenderer) { + super(entityRenderer); + } + + @Override + public void render(PoseStack poseStack, Lav150Entity animatable, BakedGeoModel bakedModel, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, float partialTick, int packedLight, int packedOverlay) { + RenderType glowRenderType = RenderType.energySwirl(LAYER,1,1); + getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, glowRenderType, bufferSource.getBuffer(glowRenderType), partialTick, packedLight, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/layer/SmallCannonShellLayer.java b/src/main/java/com/atsuishio/superbwarfare/client/layer/SmallCannonShellLayer.java new file mode 100644 index 000000000..c85ad6e0d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/layer/SmallCannonShellLayer.java @@ -0,0 +1,27 @@ +package com.atsuishio.superbwarfare.client.layer; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.cache.object.BakedGeoModel; +import software.bernie.geckolib.renderer.GeoRenderer; +import software.bernie.geckolib.renderer.layer.GeoRenderLayer; + +public class SmallCannonShellLayer extends GeoRenderLayer { + private static final ResourceLocation LAYER = new ResourceLocation(ModUtils.MODID, "textures/entity/cannon_shell_e.png"); + + public SmallCannonShellLayer(GeoRenderer entityRenderer) { + super(entityRenderer); + } + + @Override + public void render(PoseStack poseStack, SmallCannonShellEntity animatable, BakedGeoModel bakedModel, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, float partialTick, int packedLight, int packedOverlay) { + RenderType glowRenderType = RenderType.eyes(LAYER); + getRenderer().reRender(getDefaultBakedModel(animatable), poseStack, bufferSource, animatable, glowRenderType, bufferSource.getBuffer(glowRenderType), partialTick, packedLight, OverlayTexture.NO_OVERLAY, 1, 1, 1, 1); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/Lav150Model.java b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/Lav150Model.java index c2354efea..d5c2b2766 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/Lav150Model.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/Lav150Model.java @@ -9,7 +9,7 @@ public class Lav150Model extends GeoModel { @Override public ResourceLocation getAnimationResource(Lav150Entity entity) { - return null; + return ModUtils.loc("animations/lav.animation.json"); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/client/model/entity/SmallCannonShellModel.java b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/SmallCannonShellModel.java new file mode 100644 index 000000000..2a1458c1d --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/model/entity/SmallCannonShellModel.java @@ -0,0 +1,34 @@ +package com.atsuishio.superbwarfare.client.model.entity; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; +import net.minecraft.resources.ResourceLocation; +import software.bernie.geckolib.core.animatable.model.CoreGeoBone; +import software.bernie.geckolib.core.animation.AnimationState; +import software.bernie.geckolib.model.GeoModel; + +public class SmallCannonShellModel extends GeoModel { + + @Override + public ResourceLocation getAnimationResource(SmallCannonShellEntity entity) { + return ModUtils.loc("animations/cannon_shell.animation.json"); + } + + @Override + public ResourceLocation getModelResource(SmallCannonShellEntity entity) { + return ModUtils.loc("geo/cannon_shell.geo.json"); + } + + @Override + public ResourceLocation getTextureResource(SmallCannonShellEntity entity) { + return ModUtils.loc("textures/entity/cannon_shell.png"); + } + + @Override + public void setCustomAnimations(SmallCannonShellEntity animatable, long instanceId, AnimationState animationState) { + CoreGeoBone bone = getAnimationProcessor().getBone("bone"); + bone.setScaleX(0.17f); + bone.setScaleY(0.17f); + bone.setScaleZ(0.17f); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/Lav150Renderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/Lav150Renderer.java index 3f346199f..2bcbb1d6c 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/Lav150Renderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/Lav150Renderer.java @@ -1,5 +1,6 @@ package com.atsuishio.superbwarfare.client.renderer.entity; +import com.atsuishio.superbwarfare.client.layer.Lav150Layer; import com.atsuishio.superbwarfare.client.model.entity.Lav150Model; import com.atsuishio.superbwarfare.entity.vehicle.Lav150Entity; import com.mojang.blaze3d.vertex.PoseStack; @@ -18,6 +19,7 @@ public class Lav150Renderer extends GeoEntityRenderer { public Lav150Renderer(EntityRendererProvider.Context renderManager) { super(renderManager, new Lav150Model()); + this.addRenderLayer(new Lav150Layer(this)); } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/SmallCannonShellRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/SmallCannonShellRenderer.java new file mode 100644 index 000000000..2296ff010 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/SmallCannonShellRenderer.java @@ -0,0 +1,45 @@ +package com.atsuishio.superbwarfare.client.renderer.entity; + +import com.atsuishio.superbwarfare.client.layer.SmallCannonShellLayer; +import com.atsuishio.superbwarfare.client.model.entity.SmallCannonShellModel; +import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; +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 SmallCannonShellRenderer extends GeoEntityRenderer { + public SmallCannonShellRenderer(EntityRendererProvider.Context renderManager) { + super(renderManager, new SmallCannonShellModel()); + this.addRenderLayer(new SmallCannonShellLayer(this)); + } + + @Override + public RenderType getRenderType(SmallCannonShellEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) { + return RenderType.entityTranslucent(getTextureLocation(animatable)); + } + + @Override + public void preRender(PoseStack poseStack, SmallCannonShellEntity entity, BakedGeoModel model, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, + float blue, float alpha) { + float scale = 1f; + this.scaleHeight = scale; + this.scaleWidth = scale; + super.preRender(poseStack, entity, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha); + } + + @Override + public void render(SmallCannonShellEntity 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(); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java index 9dbe5303e..1db24dddd 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java @@ -81,8 +81,6 @@ public class GunGrenadeEntity extends ThrowableItemProjectile implements GeoEnti float damageMultiplier = 1 + this.monsterMultiplier; Entity entity = result.getEntity(); - if (entity == this.getOwner() || entity == this.getVehicle()) return; - if (this.getOwner() instanceof LivingEntity living) { if (!living.level().isClientSide() && living instanceof ServerPlayer player) { living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java index 86b18dcb3..ca4a1b006 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/ProjectileEntity.java @@ -588,7 +588,7 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(projectile.level(), explosion); explosion.finalizeExplosion(false); - ParticleTool.spawnSmallExplosionParticles(this.level(), hitVec); + ParticleTool.spawnMiniExplosionParticles(this.level(), hitVec); } protected void explosionBulletEntity(Entity projectile, Entity target, float damage, int heLevel, float monsterMultiple) { @@ -598,7 +598,7 @@ public class ProjectileEntity extends Entity implements IEntityAdditionalSpawnDa explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(projectile.level(), explosion); explosion.finalizeExplosion(false); - ParticleTool.spawnSmallExplosionParticles(target.level(), target.position()); + ParticleTool.spawnMiniExplosionParticles(target.level(), target.position()); } public void setDamage(float damage) { diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java index e3eff10a6..bc248e042 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/RgoGrenadeEntity.java @@ -93,7 +93,6 @@ public class RgoGrenadeEntity extends ThrowableItemProjectile implements GeoEnti case ENTITY: EntityHitResult entityResult = (EntityHitResult) result; Entity entity = entityResult.getEntity(); - if (entity == this.getOwner() || entity == this.getVehicle()) return; if (this.getOwner() instanceof LivingEntity living) { if (!living.level().isClientSide() && living instanceof ServerPlayer player) { living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java new file mode 100644 index 000000000..ebd1439f7 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/SmallCannonShellEntity.java @@ -0,0 +1,150 @@ +package com.atsuishio.superbwarfare.entity.projectile; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.init.ModDamageTypes; +import com.atsuishio.superbwarfare.init.ModEntities; +import com.atsuishio.superbwarfare.init.ModItems; +import com.atsuishio.superbwarfare.init.ModSounds; +import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage; +import com.atsuishio.superbwarfare.tools.ParticleTool; +import com.atsuishio.superbwarfare.tools.ProjectileTool; +import net.minecraft.core.BlockPos; +import net.minecraft.core.particles.ParticleTypes; +import net.minecraft.network.protocol.Packet; +import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.server.level.ServerLevel; +import net.minecraft.server.level.ServerPlayer; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.projectile.ThrowableItemProjectile; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.BellBlock; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.BlockHitResult; +import net.minecraft.world.phys.EntityHitResult; +import net.minecraftforge.network.NetworkHooks; +import net.minecraftforge.network.PacketDistributor; +import net.minecraftforge.network.PlayMessages; +import software.bernie.geckolib.animatable.GeoEntity; +import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; +import software.bernie.geckolib.core.animation.AnimatableManager; +import software.bernie.geckolib.util.GeckoLibUtil; + +public class SmallCannonShellEntity extends ThrowableItemProjectile implements GeoEntity { + private float damage = 40.0f; + private float explosionDamage = 80f; + private float explosionRadius = 5f; + private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + + public SmallCannonShellEntity(EntityType type, Level world) { + super(type, world); + this.noCulling = true; + } + + public SmallCannonShellEntity(LivingEntity entity, Level level, float damage, float explosionDamage, float explosionRadius) { + super(ModEntities.GUN_GRENADE.get(), entity, level); + this.damage = damage; + this.explosionDamage = explosionDamage; + this.explosionRadius = explosionRadius; + } + + public SmallCannonShellEntity(PlayMessages.SpawnEntity spawnEntity, Level level) { + this(ModEntities.SMALL_CANNON_SHELL.get(), level); + } + + @Override + public Packet getAddEntityPacket() { + return NetworkHooks.getEntitySpawningPacket(this); + } + + @Override + protected Item getDefaultItem() { + return ModItems.GRENADE_40MM.get(); + } + + @Override + public boolean shouldRenderAtSqrDistance(double pDistance) { + return true; + } + + @Override + protected void onHitEntity(EntityHitResult result) { + Entity entity = result.getEntity(); + if (this.getOwner() instanceof LivingEntity living) { + if (!living.level().isClientSide() && living instanceof ServerPlayer player) { + living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5)); + } + } + + entity.hurt(ModDamageTypes.causeGunFireHeadshotDamage(this.level().registryAccess(), this, this.getOwner()), damage); + + if (entity instanceof LivingEntity) { + entity.invulnerableTime = 0; + } + + if (this.tickCount > 1) { + if (this.level() instanceof ServerLevel) { + ProjectileTool.causeCustomExplode(this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), + entity, this.explosionDamage, this.explosionRadius, 1.25f); + } + } + this.discard(); + } + + @Override + public void onHitBlock(BlockHitResult blockHitResult) { + super.onHitBlock(blockHitResult); + BlockPos resultPos = blockHitResult.getBlockPos(); + BlockState state = this.level().getBlockState(resultPos); + if (state.getBlock() instanceof BellBlock bell) { + bell.attemptToRing(this.level(), resultPos, blockHitResult.getDirection()); + } + + if (this.tickCount > 1) { + if (this.level() instanceof ServerLevel) { + ProjectileTool.causeCustomExplode(this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), + this, this.explosionDamage, this.explosionRadius, 1.25f); + } + this.discard(); + } + } + + @Override + public void tick() { + super.tick(); + + if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { + ParticleTool.sendParticle(serverLevel, ParticleTypes.SMOKE, this.xo, this.yo, this.zo, + 1, 0, 0, 0, 0.02, true); + } + + if (onGround()) { + this.setDeltaMovement(0,0,0); + } + + if (this.tickCount > 200 || this.isInWater()) { + if (this.level() instanceof ServerLevel && !onGround()) { + ProjectileTool.causeCustomExplode(this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), + this, this.explosionDamage, this.explosionRadius, 1.25f); + } + this.discard(); + } + } + + @Override + public void registerControllers(AnimatableManager.ControllerRegistrar data) { + } + + @Override + public AnimatableInstanceCache getAnimatableInstanceCache() { + return this.cache; + } + +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java index 5b784dde1..c83549cce 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Lav150Entity.java @@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionDestroyConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; -import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; +import com.atsuishio.superbwarfare.entity.projectile.SmallCannonShellEntity; import com.atsuishio.superbwarfare.init.*; import com.atsuishio.superbwarfare.network.ModVariables; import com.atsuishio.superbwarfare.network.message.ShakeClientMessage; @@ -48,6 +48,10 @@ import org.joml.Vector4f; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animation.AnimatableManager; +import software.bernie.geckolib.core.animation.AnimationController; +import software.bernie.geckolib.core.animation.AnimationState; +import software.bernie.geckolib.core.animation.RawAnimation; +import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; import java.util.Comparator; @@ -231,9 +235,6 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IC return false; } - /** - * 机枪塔开火 - */ @Override public void vehicleShoot(Player player) { if (this.cannotFire) return; @@ -246,17 +247,29 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IC Vector4f worldPosition = transformPosition(transform, x, y, z); - ProjectileEntity projectile = new ProjectileEntity(player.level()) - .shooter(player) - .damage(VehicleConfig.SPEEDBOAT_GUN_DAMAGE.get()) - .headShot(2f) - .zoom(false); +// ProjectileEntity projectile = new ProjectileEntity(player.level()) +// .shooter(player) +// .damage(80) +// .headShot(3f) +// .zoom(false); +// +// projectile.heBullet(true, 5); +// projectile.bypassArmorRate(1); +// projectile.setPos(worldPosition.x - 1.1 * this.getDeltaMovement().x, worldPosition.y, worldPosition.z - 1.1 * this.getDeltaMovement().z); +// projectile.shoot(player, getBarrelVector(1).x, getBarrelVector(1).y + 0.002f, getBarrelVector(1).z, 20, +// (float) 0.4); +// this.level().addFreshEntity(projectile); - projectile.bypassArmorRate(0.9f); - projectile.setPos(worldPosition.x - 1.1 * this.getDeltaMovement().x, worldPosition.y, worldPosition.z - 1.1 * this.getDeltaMovement().z); - projectile.shoot(player, getBarrelVector(1).x, getBarrelVector(1).y + 0.002f, getBarrelVector(1).z, 20, - (float) 0.4); - this.level().addFreshEntity(projectile); + SmallCannonShellEntity smallCannonShell = new SmallCannonShellEntity(player, this.level(), + 50, + 40, + 4.5f); + + + smallCannonShell.setPos(worldPosition.x - 1.1 * this.getDeltaMovement().x, worldPosition.y, worldPosition.z - 1.1 * this.getDeltaMovement().z); + smallCannonShell.shoot(getBarrelVector(1).x, getBarrelVector(1).y + 0.005f, getBarrelVector(1).z, 15, + 0.5f); + this.level().addFreshEntity(smallCannonShell); sendParticle((ServerLevel) this.level(), ParticleTypes.LARGE_SMOKE, worldPosition.x - 1.1 * this.getDeltaMovement().x, worldPosition.y, worldPosition.z - 1.1 * this.getDeltaMovement().z, 1, 0.02, 0.02, 0.02, 0, false); @@ -264,9 +277,9 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IC if (!player.level().isClientSide) { if (player instanceof ServerPlayer serverPlayer) { - serverPlayer.playSound(ModSounds.M_2_FIRE_3P.get(), 4, pitch); - serverPlayer.playSound(ModSounds.M_2_FAR.get(), 12, pitch); - serverPlayer.playSound(ModSounds.M_2_VERYFAR.get(), 24, pitch); + serverPlayer.playSound(ModSounds.LAV_CANNON_FIRE_3P.get(), 4, pitch); + serverPlayer.playSound(ModSounds.LAV_CANNON_FAR.get(), 12, pitch); + serverPlayer.playSound(ModSounds.LAV_CANNON_VERYFAR.get(), 24, pitch); } } @@ -275,11 +288,11 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IC for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(4), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) { if (target instanceof ServerPlayer serverPlayer) { - ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShakeClientMessage(6, 5, 5, this.getX(), this.getEyeY(), this.getZ())); + ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> serverPlayer), new ShakeClientMessage(6, 5, 9, this.getX(), this.getEyeY(), this.getZ())); } } - this.entityData.set(HEAT, this.entityData.get(HEAT) + 3); + this.entityData.set(HEAT, this.entityData.get(HEAT) + 6); this.entityData.set(FIRE_ANIM, 3); this.getItemStacks().stream().filter(stack -> stack.is(ModItems.HEAVY_AMMO.get())).findFirst().ifPresent(stack -> stack.shrink(1)); } @@ -502,17 +515,17 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IC this.clampRotation(entity); } -// private PlayState firePredicate(AnimationState event) { -// if (this.entityData.get(FIRE_ANIM) > 1) { -// return event.setAndContinue(RawAnimation.begin().thenPlay("animation.speedboat.fire")); -// } -// -// return event.setAndContinue(RawAnimation.begin().thenLoop("animation.speedboat.idle")); -// } + private PlayState firePredicate(AnimationState event) { + if (this.entityData.get(FIRE_ANIM) > 1) { + return event.setAndContinue(RawAnimation.begin().thenPlay("animation.lav.fire")); + } + + return event.setAndContinue(RawAnimation.begin().thenLoop("animation.lav.idle")); + } @Override public void registerControllers(AnimatableManager.ControllerRegistrar data) { -// data.add(new AnimationController<>(this, "movement", 0, this::firePredicate)); + data.add(new AnimationController<>(this, "movement", 0, this::firePredicate)); } @Override @@ -547,7 +560,7 @@ public class Lav150Entity extends ContainerMobileEntity implements GeoEntity, IC @Override public int mainGunRpm() { - return 240; + return 180; } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java index 12b9d8f61..852b53360 100644 --- a/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java +++ b/src/main/java/com/atsuishio/superbwarfare/event/ClientEventHandler.java @@ -409,24 +409,18 @@ public class ClientEventHandler { } else { if (!clientTimer.started()) { clientTimer.start(); - // 首发瞬间发射 - clientTimer.setProgress((cooldown + 1)); + shootClient(player); } if (clientTimer.getProgress() >= cooldown) { - shootClient(player); - clientTimer.setProgress((clientTimer.getProgress() - cooldown)); + clientTimer.stop(); } } if (notInGame()) { clientTimer.stop(); } - } else { - if (mode != 0) { - clientTimer.stop(); - } fireSpread = 0; } @@ -659,23 +653,17 @@ public class ClientEventHandler { } double rps = (double) rpm / 60; - - // cooldown in ms int cooldown = (int) (1000 / rps); if ((holdFire)) { if (!clientTimerVehicle.started()) { clientTimerVehicle.start(); - // 首发瞬间发射 - clientTimerVehicle.setProgress((cooldown + 1)); - } - if (clientTimerVehicle.getProgress() >= cooldown) { ModUtils.PACKET_HANDLER.sendToServer(new VehicleFireMessage(0)); playVehicleClientSounds(player, iVehicle); - clientTimerVehicle.setProgress((clientTimerVehicle.getProgress() - cooldown)); } - } else { - clientTimerVehicle.stop(); + if (clientTimerVehicle.getProgress() >= cooldown) { + clientTimerVehicle.stop(); + } } } else { clientTimerVehicle.stop(); @@ -694,7 +682,11 @@ public class ClientEventHandler { } else if (ah6Entity.getEntityData().get(WEAPON_TYPE) == 1) { player.playSound(ModSounds.HELICOPTER_ROCKET_FIRE_1P.get(), 1f, 1); } - + } + if (iVehicle instanceof Lav150Entity lav150) { + float pitch = lav150.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * java.lang.Math.abs(60 - lav150.getEntityData().get(HEAT))); + player.playSound(ModSounds.LAV_CANNON_FIRE_1P.get(), 1f, pitch); + player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java b/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java index 9f9defc38..3edffa1b6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java @@ -46,6 +46,8 @@ public class ModEntities { .setUpdateInterval(1).sized(0.5f, 0.5f)); public static final RegistryObject> GUN_GRENADE = register("projectile_gun_grenade", EntityType.Builder.of(GunGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(GunGrenadeEntity::new).sized(0.5f, 0.5f)); + public static final RegistryObject> SMALL_CANNON_SHELL = register("projectile_small_cannon_shell", + EntityType.Builder.of(SmallCannonShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(SmallCannonShellEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> RPG_ROCKET = register("projectile_rpg_rocket", EntityType.Builder.of(RpgRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(RpgRocketEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> MORTAR_SHELL = register("projectile_mortar_shell", diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java b/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java index ffc261f7c..b3ecaf6b8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java @@ -35,5 +35,6 @@ public class ModEntityRenderers { event.registerEntityRenderer(ModEntities.AH_6.get(), Ah6Renderer::new); event.registerEntityRenderer(ModEntities.FLARE_DECOY.get(), FlareDecoyEntityRenderer::new); event.registerEntityRenderer(ModEntities.LAV_150.get(), Lav150Renderer::new); + event.registerEntityRenderer(ModEntities.SMALL_CANNON_SHELL.get(), SmallCannonShellRenderer::new); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java b/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java index f80136999..7f7db48a7 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModSounds.java @@ -396,5 +396,9 @@ public class ModSounds { public static final RegistryObject DECOY_FIRE = REGISTRY.register("decoy_fire", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("decoy_fire"))); public static final RegistryObject DECOY_RELOAD = REGISTRY.register("decoy_reload", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("decoy_reload"))); public static final RegistryObject LUNGE_MINE_GROWL = REGISTRY.register("lunge_mine_growl", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lunge_mine_growl"))); + public static final RegistryObject LAV_CANNON_FIRE_1P = REGISTRY.register("lav_cannon_fire_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lav_fire_1p"))); + public static final RegistryObject LAV_CANNON_FIRE_3P = REGISTRY.register("lav_cannon_fire_3p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lav_fire_3p"))); + public static final RegistryObject LAV_CANNON_FAR = REGISTRY.register("lav_cannon_far", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lav_far"))); + public static final RegistryObject LAV_CANNON_VERYFAR = REGISTRY.register("lav_cannon_veryfar", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lav_veryfar"))); } diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/ParticleTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/ParticleTool.java index c6348a3ca..f522c3d93 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/ParticleTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/ParticleTool.java @@ -26,14 +26,20 @@ public class ParticleTool { level.sendParticles(viewer, particle, force, x, y, z, count, xOffset, yOffset, zOffset, speed); } - public static void spawnSmallExplosionParticles(Level level, Vec3 pos) { + public static void spawnMiniExplosionParticles(Level level, Vec3 pos) { double x = pos.x; double y = pos.y; double z = pos.z; if (!level.isClientSide()) { + if ((level.getBlockState(BlockPos.containing(x, y, z))).getBlock() == Blocks.WATER) { + level.playSound(null, BlockPos.containing(x, y + 1, z), ModSounds.EXPLOSION_WATER.get(), SoundSource.BLOCKS, 2, 1); + } level.playSound(null, BlockPos.containing(x, y + 1, z), SoundEvents.FIREWORK_ROCKET_BLAST, SoundSource.BLOCKS, 4, 1); } else { + if ((level.getBlockState(BlockPos.containing(x, y, z))).getBlock() == Blocks.WATER) { + level.playLocalSound(x, (y + 1), z, ModSounds.EXPLOSION_WATER.get(), SoundSource.BLOCKS, 1, 1, false); + } level.playLocalSound(x, (y + 1), z, SoundEvents.FIREWORK_ROCKET_BLAST, SoundSource.BLOCKS, 2, 1, false); } @@ -44,6 +50,38 @@ public class ParticleTool { } } + public static void spawnSmallExplosionParticles(Level level, Vec3 pos) { + double x = pos.x; + double y = pos.y; + double z = pos.z; + + if (!level.isClientSide()) { + if ((level.getBlockState(BlockPos.containing(x, y, z))).getBlock() == Blocks.WATER) { + level.playSound(null, BlockPos.containing(x, y + 1, z), ModSounds.EXPLOSION_WATER.get(), SoundSource.BLOCKS, 2, 1); + } + level.playSound(null, BlockPos.containing(x, y + 1, z), SoundEvents.FIREWORK_ROCKET_BLAST, SoundSource.BLOCKS, 4, 1); + level.playSound(null, BlockPos.containing(x, y + 1, z), ModSounds.EXPLOSION_CLOSE.get(), SoundSource.BLOCKS, 3, 1); + level.playSound(null, BlockPos.containing(x, y + 1, z), ModSounds.EXPLOSION_FAR.get(), SoundSource.BLOCKS, 6, 1); + level.playSound(null, BlockPos.containing(x, y + 1, z), ModSounds.EXPLOSION_VERY_FAR.get(), SoundSource.BLOCKS, 12, 1); + } else { + if ((level.getBlockState(BlockPos.containing(x, y, z))).getBlock() == Blocks.WATER) { + level.playLocalSound(x, (y + 1), z, ModSounds.EXPLOSION_WATER.get(), SoundSource.BLOCKS, 1, 1, false); + } + level.playLocalSound(x, (y + 1), z, SoundEvents.FIREWORK_ROCKET_BLAST, SoundSource.BLOCKS, 2, 1, false); + level.playLocalSound(x, (y + 1), z, ModSounds.EXPLOSION_CLOSE.get(), SoundSource.BLOCKS, 1, 1, false); + level.playLocalSound(x, (y + 1), z, ModSounds.EXPLOSION_FAR.get(), SoundSource.BLOCKS, 1, 1, false); + level.playLocalSound(x, (y + 1), z, ModSounds.EXPLOSION_VERY_FAR.get(), SoundSource.BLOCKS, 1, 1, false); + } + + if (level instanceof ServerLevel serverLevel) { + sendParticle(serverLevel, ParticleTypes.EXPLOSION, x, y + 1, z, 4, 0.25, 0.25, 0.25, 1, true); + 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, 20, 0, 0, 0, 0.6, true); + sendParticle(serverLevel, ParticleTypes.FLASH, x, y + 0.2, z, 20, 0.1, 0.1, 0.1, 20, true); + } + } + public static void spawnMediumExplosionParticles(Level level, Vec3 pos) { double x = pos.x; double y = pos.y; diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/ProjectileTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/ProjectileTool.java index 92eb1a973..01ddf7d47 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/ProjectileTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/ProjectileTool.java @@ -17,7 +17,14 @@ public class ProjectileTool { explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(projectile.level(), explosion); explosion.finalizeExplosion(false); - ParticleTool.spawnMediumExplosionParticles(projectile.level(), projectile.position()); + if (radius <= 5) { + ParticleTool.spawnSmallExplosionParticles(projectile.level(), projectile.position()); + } else if (radius > 5 && radius < 10) { + ParticleTool.spawnMediumExplosionParticles(projectile.level(), projectile.position()); + } else { + ParticleTool.spawnHugeExplosionParticles(projectile.level(), projectile.position()); + } + projectile.discard(); } diff --git a/src/main/resources/assets/superbwarfare/animations/lav.animation.json b/src/main/resources/assets/superbwarfare/animations/lav.animation.json new file mode 100644 index 000000000..80e7b109f --- /dev/null +++ b/src/main/resources/assets/superbwarfare/animations/lav.animation.json @@ -0,0 +1,44 @@ +{ + "format_version": "1.8.0", + "animations": { + "animation.lav.fire": { + "animation_length": 0.4, + "bones": { + "barrel2": { + "position": { + "0.0": [0, 0, 0], + "0.0417": { + "pre": [0, 0, 6.1], + "post": [0, 0, 6.1], + "lerp_mode": "catmullrom" + }, + "0.1": { + "post": [0, 0, 6.26563], + "lerp_mode": "catmullrom" + }, + "0.1833": [0, 0, 3], + "0.275": [0, 0, 0] + } + }, + "flare": { + "scale": { + "0.0": [0, 0, 0], + "0.0083": [8, 8, 8], + "0.05": [11, 11, 11], + "0.075": [1, 1, 1], + "0.0917": [0, 0, 0], + "0.15": [0, 0, 0] + } + } + } + }, + "animation.lav.idle": { + "animation_length": 0.25, + "bones": { + "flare": { + "scale": 0 + } + } + } + } +} \ No newline at end of file diff --git a/src/main/resources/assets/superbwarfare/geo/lav150.geo.json b/src/main/resources/assets/superbwarfare/geo/lav150.geo.json index 20ea90a39..f34b125ce 100644 --- a/src/main/resources/assets/superbwarfare/geo/lav150.geo.json +++ b/src/main/resources/assets/superbwarfare/geo/lav150.geo.json @@ -3005,6 +3005,51 @@ "parent": "cannon", "pivot": [0.375, 43.8072, -13.2] }, + { + "name": "flare", + "parent": "barrel", + "pivot": [0.375, 45.61482, -63.67799], + "cubes": [ + { + "origin": [-0.35251, 44.88732, -63.73986], + "size": [1.455, 1.455, 0], + "uv": { + "north": {"uv": [512, 0], "uv_size": [-128, 128]}, + "south": {"uv": [384, 0], "uv_size": [128, 128]} + } + }, + { + "origin": [-1.45501, 45.00731, -64.52738], + "size": [3.66, 1.215, 0], + "pivot": [0.37499, 45.61482, -64.52736], + "rotation": [0, -90, -60], + "uv": { + "north": {"uv": [512, 0], "uv_size": [-103, 128]}, + "south": {"uv": [409, 0], "uv_size": [103, 128]} + } + }, + { + "origin": [-1.45501, 45.00731, -64.52738], + "size": [3.66, 1.215, 0], + "pivot": [0.37499, 45.61482, -64.52736], + "rotation": [0, -90, -120], + "uv": { + "north": {"uv": [512, 0], "uv_size": [-103, 128]}, + "south": {"uv": [409, 0], "uv_size": [103, 128]} + } + }, + { + "origin": [-1.45501, 45.00731, -64.52738], + "size": [3.66, 1.215, 0], + "pivot": [0.37499, 45.61482, -64.52736], + "rotation": [0, -90, 0], + "uv": { + "north": {"uv": [512, 0], "uv_size": [-103, 128]}, + "south": {"uv": [409, 0], "uv_size": [103, 128]} + } + } + ] + }, { "name": "barrel2", "parent": "barrel", diff --git a/src/main/resources/assets/superbwarfare/sounds.json b/src/main/resources/assets/superbwarfare/sounds.json index 9e9b62f06..7578df4fc 100644 --- a/src/main/resources/assets/superbwarfare/sounds.json +++ b/src/main/resources/assets/superbwarfare/sounds.json @@ -2704,5 +2704,37 @@ "stream": false } ] + }, + "lav_fire_1p": { + "sounds": [ + { + "name": "superbwarfare:lav/lav_fire_1p", + "stream": false + } + ] + }, + "lav_fire_3p": { + "sounds": [ + { + "name": "superbwarfare:lav/lav_fire_3p", + "stream": false + } + ] + }, + "lav_far": { + "sounds": [ + { + "name": "superbwarfare:lav/lav_far", + "stream": false + } + ] + }, + "lav_veryfar": { + "sounds": [ + { + "name": "superbwarfare:lav/lav_veryfar", + "stream": false + } + ] } } \ No newline at end of file diff --git a/src/main/resources/assets/superbwarfare/sounds/lav/lav_far.ogg b/src/main/resources/assets/superbwarfare/sounds/lav/lav_far.ogg new file mode 100644 index 000000000..c56672e8b Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/lav/lav_far.ogg differ diff --git a/src/main/resources/assets/superbwarfare/sounds/lav/lav_fire_1p.ogg b/src/main/resources/assets/superbwarfare/sounds/lav/lav_fire_1p.ogg new file mode 100644 index 000000000..239b7bab0 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/lav/lav_fire_1p.ogg differ diff --git a/src/main/resources/assets/superbwarfare/sounds/lav/lav_fire_3p.ogg b/src/main/resources/assets/superbwarfare/sounds/lav/lav_fire_3p.ogg new file mode 100644 index 000000000..91f52ce3e Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/lav/lav_fire_3p.ogg differ diff --git a/src/main/resources/assets/superbwarfare/sounds/lav/lav_veryfar.ogg b/src/main/resources/assets/superbwarfare/sounds/lav/lav_veryfar.ogg new file mode 100644 index 000000000..b4c869a51 Binary files /dev/null and b/src/main/resources/assets/superbwarfare/sounds/lav/lav_veryfar.ogg differ