添加线控导弹

This commit is contained in:
Atsuihsio 2025-01-28 00:28:31 +08:00
parent c75289daee
commit a881e1f1f2
27 changed files with 637 additions and 13 deletions

View file

@ -1,4 +1,4 @@
// 1.20.1 2025-01-24T23:46:19.2276768 Item Models: superbwarfare
// 1.20.1 2025-01-27T23:57:54.4907094 Item Models: superbwarfare
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/aa_12_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_12_blueprint.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/ak_47_blueprint.json
@ -114,3 +114,4 @@ fe78719387b06e37de4abe02c808a8f2dba179f8 assets/superbwarfare/models/item/us_che
01dabedc256e53d58a14f4ba9ce83b839f3a7bdb assets/superbwarfare/models/item/us_helmet_pastg.json
13ca8d5676888ff51f3308d88e4bf67691fa34f8 assets/superbwarfare/models/item/vector_blueprint.json
7e4ba98653b69bcdc7e9bdbd05d2e8b8b20df293 assets/superbwarfare/models/item/wheel.json
a2b4b6f79b504888b66681107ce9c8307d1a3abc assets/superbwarfare/models/item/wire_guide_missile.json

View file

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

View file

@ -0,0 +1,27 @@
package com.atsuishio.superbwarfare.client.layer;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.entity.projectile.WgMissileEntity;
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 WgMissileLayer extends GeoRenderLayer<WgMissileEntity> {
private static final ResourceLocation LAYER = new ResourceLocation(ModUtils.MODID, "textures/entity/rpg_rocket_e.png");
public WgMissileLayer(GeoRenderer<WgMissileEntity> entityRenderer) {
super(entityRenderer);
}
@Override
public void render(PoseStack poseStack, WgMissileEntity 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);
}
}

View file

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

View file

@ -284,9 +284,11 @@ public class VehicleHudOverlay {
if (multiWeaponVehicle.getWeaponType() == 0) {
double heat = 1 - bmp2.getEntityData().get(HEAT) / 100.0F;
guiGraphics.drawString(mc.font, Component.literal(" 30MM 2A42 " + (player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get())) ? "" : bmp2.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
} else {
} else if (multiWeaponVehicle.getWeaponType() == 1) {
double heat = 1 - bmp2.getEntityData().get(COAX_HEAT) / 100.0F;
guiGraphics.drawString(mc.font, Component.literal(" 7.62MM ПКТ " + (player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get())) ? "" : bmp2.getAmmoCount(player))), w / 2 - 33, h - 65, Mth.hsvToRgb((float) heat / 3.745318352059925F, 1.0F, 1.0F), false);
} else {
guiGraphics.drawString(mc.font, Component.literal(" 9M113 " + bmp2.getAmmoCount(player)), w / 2 - 33, h - 65, 0x66FF00, false);
}
}
@ -329,9 +331,11 @@ public class VehicleHudOverlay {
if (multiWeaponVehicle.getWeaponType() == 0) {
double heat = bmp201.getEntityData().get(HEAT) / 100.0F;
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("30MM 2A42 " + (player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get())) ? "" : bmp201.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat, 1.0F), false);
} else {
} else if (multiWeaponVehicle.getWeaponType() == 1) {
double heat2 = bmp201.getEntityData().get(COAX_HEAT) / 100.0F;
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("7.62MM ПКТ " + (player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get())) ? "" : bmp201.getAmmoCount(player))), 30, -9, Mth.hsvToRgb(0F, (float) heat2, 1.0F), false);
} else {
guiGraphics.drawString(Minecraft.getInstance().font, Component.literal("9M113 " + bmp201.getAmmoCount(player)), 30, -9, -1, false);
}
}

View file

@ -0,0 +1,50 @@
package com.atsuishio.superbwarfare.client.renderer.entity;
import com.atsuishio.superbwarfare.client.layer.WgMissileLayer;
import com.atsuishio.superbwarfare.client.model.entity.WgMissileModel;
import com.atsuishio.superbwarfare.entity.projectile.WgMissileEntity;
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 WgMissileRenderer extends GeoEntityRenderer<WgMissileEntity> {
public WgMissileRenderer(EntityRendererProvider.Context renderManager) {
super(renderManager, new WgMissileModel());
this.addRenderLayer(new WgMissileLayer(this));
}
@Override
public RenderType getRenderType(WgMissileEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
@Override
public void preRender(PoseStack poseStack, WgMissileEntity 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(WgMissileEntity 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();
}
@Override
protected float getDeathMaxRotation(WgMissileEntity entityLivingBaseIn) {
return 0.0F;
}
}

View file

@ -70,6 +70,7 @@ public class ModItemModelProvider extends ItemModelProvider {
simpleItem(ModItems.BEAM_TEST);
simpleItem(ModItems.HEAVY_AMMO);
simpleItem(ModItems.ROCKET_70);
simpleItem(ModItems.WIRE_GUIDE_MISSILE);
simpleItem(ModItems.SMALL_SHELL);
simpleItem(ModItems.TUNGSTEN_ROD);

View file

@ -0,0 +1,216 @@
package com.atsuishio.superbwarfare.entity.projectile;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.config.server.ExplosionDestroyConfig;
import com.atsuishio.superbwarfare.entity.AnimatedEntity;
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.CustomExplosion;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.VectorTool;
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.util.Mth;
import net.minecraft.world.damagesource.DamageSource;
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.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.EntityHitResult;
import net.minecraft.world.phys.Vec3;
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.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 javax.annotation.Nullable;
public class WgMissileEntity extends ThrowableItemProjectile implements GeoEntity, AnimatedEntity {
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public String animationProcedure = "empty";
private float damage = 250f;
private float explosion_damage = 200f;
private float explosion_radius = 10f;
public WgMissileEntity(EntityType<? extends WgMissileEntity> type, Level world) {
super(type, world);
this.noCulling = true;
}
public WgMissileEntity(LivingEntity entity, Level level, float damage, float explosion_damage, float explosion_radius) {
super(ModEntities.WG_MISSILE.get(), entity, level);
this.damage = damage;
this.explosion_damage = explosion_damage;
this.explosion_radius = explosion_radius;
}
public WgMissileEntity(PlayMessages.SpawnEntity spawnEntity, Level level) {
this(ModEntities.WG_MISSILE.get(), level);
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
protected Item getDefaultItem() {
return ModItems.ROCKET.get();
}
@Override
public boolean shouldRenderAtSqrDistance(double pDistance) {
return true;
}
@Override
protected void onHitEntity(EntityHitResult result) {
Entity entity = result.getEntity();
if (this.tickCount < 1) return;
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);
ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5));
}
}
entity.hurt(ModDamageTypes.causeCannonFireDamage(this.level().registryAccess(), this, this.getOwner()), this.damage);
if (entity instanceof LivingEntity) {
entity.invulnerableTime = 0;
}
if (this.tickCount > 2) {
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
entity, this.explosion_damage, this.explosion_radius);
}
}
this.discard();
}
@Override
public void onHitBlock(BlockHitResult blockHitResult) {
super.onHitBlock(blockHitResult);
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
this, this.explosion_damage, this.explosion_radius);
}
this.discard();
}
@Override
public void tick() {
super.tick();
if (this.tickCount == 1) {
if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) {
ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, this.xo, this.yo, this.zo, 15, 0.8, 0.8, 0.8, 0.01, true);
ParticleTool.sendParticle(serverLevel, ParticleTypes.CAMPFIRE_COSY_SMOKE, this.xo, this.yo, this.zo, 10, 0.8, 0.8, 0.8, 0.01, true);
}
}
if (this.tickCount > 2) {
this.setDeltaMovement(this.getDeltaMovement().multiply(1.03, 1.03, 1.03));
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, true);
}
}
if (tickCount > 5 && this.getOwner() != null) {
Entity shooter = this.getOwner();
Vec3 lookVec = shooter.getViewVector(1).normalize();
Vec3 toVec = shooter.getEyePosition().vectorTo(this.getEyePosition()).normalize();
Vec3 addVec = lookVec.add(toVec.scale(-0.85)).normalize();
double angle = Mth.abs((float) VectorTool.calculateAngle(lookVec, toVec));
setDeltaMovement(getDeltaMovement().add(addVec.scale(Math.min(0.1 + 0.15 * angle, tickCount < 15 ? 0.04 : 0.2))));
// 控制速度
if (this.getDeltaMovement().length() < 2.4) {
this.setDeltaMovement(this.getDeltaMovement().multiply(1.06, 1.06, 1.06));
}
if (this.getDeltaMovement().length() > 2.8) {
this.setDeltaMovement(this.getDeltaMovement().multiply(0.9, 0.9, 0.9));
}
this.setDeltaMovement(this.getDeltaMovement().multiply(0.96, 0.96, 0.96));
}
if (this.tickCount > 300 || this.isInWater()) {
if (this.level() instanceof ServerLevel) {
causeMissileExplode(this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()),
this, this.explosion_damage, this.explosion_radius);
}
this.discard();
}
}
public static void causeMissileExplode(ThrowableItemProjectile projectile, @Nullable DamageSource source, Entity target, float damage, float radius) {
CustomExplosion explosion = new CustomExplosion(projectile.level(), projectile, source, damage,
target.getX(), target.getEyeY(), target.getZ(), radius, ExplosionDestroyConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1.25f);
explosion.explode();
net.minecraftforge.event.ForgeEventFactory.onExplosionStart(projectile.level(), explosion);
explosion.finalizeExplosion(false);
ParticleTool.spawnMediumExplosionParticles(projectile.level(), projectile.position());
projectile.discard();
}
private PlayState movementPredicate(AnimationState<WgMissileEntity> event) {
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.jvm.idle"));
}
@Override
protected float getGravity() {
return 0;
}
public String getSyncedAnimation() {
return null;
}
public void setAnimation(String animation) {
}
@Override
public void setAnimationProcedure(String procedure) {
this.animationProcedure = procedure;
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) {
data.add(new AnimationController<>(this, "movement", 0, this::movementPredicate));
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
}

View file

@ -5,6 +5,7 @@ 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.entity.projectile.WgMissileEntity;
import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.network.ModVariables;
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
@ -71,6 +72,7 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
public static final EntityDataAccessor<Integer> COAX_HEAT = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> AMMO = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> LOADED_COAX_AMMO = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> LOADED_MISSILE = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> WEAPON_TYPE = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Float> TRACK_L = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> TRACK_R = SynchedEntityData.defineId(Bmp2Entity.class, EntityDataSerializers.FLOAT);
@ -89,6 +91,7 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
public float rightWheelRotO;
public boolean cannotFire;
public boolean cannotFireCoax;
public int reloadCoolDown;
public Bmp2Entity(PlayMessages.SpawnEntity packet, Level world) {
this(ModEntities.BMP_2.get(), world);
@ -109,6 +112,7 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
this.entityData.define(COAX_HEAT, 0);
this.entityData.define(WEAPON_TYPE, 0);
this.entityData.define(LOADED_COAX_AMMO, 0);
this.entityData.define(LOADED_MISSILE, 0);
this.entityData.define(TRACK_L, 0f);
this.entityData.define(TRACK_R, 0f);
}
@ -117,12 +121,14 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
compound.putInt("LoadedCoaxAmmo", this.entityData.get(LOADED_COAX_AMMO));
compound.putInt("LoadedMissile", this.entityData.get(LOADED_MISSILE));
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
this.entityData.set(LOADED_COAX_AMMO, compound.getInt("LoadedCoaxAmmo"));
this.entityData.set(LOADED_MISSILE, compound.getInt("LoadedMissile"));
}
@Override
@ -250,6 +256,9 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
}
if (this.level() instanceof ServerLevel) {
if (reloadCoolDown > 0) {
reloadCoolDown--;
}
if (this.getFirstPassenger() instanceof Player player) {
if ((this.getItemStacks().stream().filter(stack -> stack.is(ModItems.RIFLE_AMMO_BOX.get())).mapToInt(ItemStack::getCount).sum() > 0 && this.getEntityData().get(LOADED_COAX_AMMO) < 500)) {
this.entityData.set(LOADED_COAX_AMMO, this.getEntityData().get(LOADED_COAX_AMMO) + 30);
@ -261,10 +270,23 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
}
}
if (this.getFirstPassenger() instanceof Player player) {
if ((this.getItemStacks().stream().filter(stack -> stack.is(ModItems.WIRE_GUIDE_MISSILE.get())).mapToInt(ItemStack::getCount).sum() > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) && reloadCoolDown == 0 && this.getEntityData().get(LOADED_MISSILE) < 1) {
this.entityData.set(LOADED_MISSILE, this.getEntityData().get(LOADED_MISSILE) + 1);
reloadCoolDown = 160;
if (!player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.WIRE_GUIDE_MISSILE.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
this.level().playSound(null, this, ModSounds.BMP_MISSILE_RELOAD.get(), this.getSoundSource(), 1, 1);
}
}
if (this.getEntityData().get(WEAPON_TYPE) == 0) {
this.entityData.set(AMMO, this.getItemStacks().stream().filter(stack -> stack.is(ModItems.SMALL_SHELL.get())).mapToInt(ItemStack::getCount).sum());
} else {
} else if (this.getEntityData().get(WEAPON_TYPE) == 1) {
this.entityData.set(AMMO, this.getEntityData().get(LOADED_COAX_AMMO));
} else {
this.entityData.set(AMMO, this.getEntityData().get(LOADED_MISSILE));
}
}
@ -369,7 +391,7 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.playSound(ModSounds.LAV_CANNON_FIRE_3P.get(), 4, pitch);
serverPlayer.playSound(ModSounds.BMP_CANNON_FIRE_3P.get(), 4, pitch);
serverPlayer.playSound(ModSounds.LAV_CANNON_FAR.get(), 12, pitch);
serverPlayer.playSound(ModSounds.LAV_CANNON_VERYFAR.get(), 24, pitch);
}
@ -424,6 +446,27 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
serverPlayer.playSound(ModSounds.M_60_VERYFAR.get(), 12, 1);
}
}
} else if (entityData.get(WEAPON_TYPE) == 2 && this.getEntityData().get(LOADED_MISSILE) > 0) {
Matrix4f transformT = getBarrelTransform();
Vector4f worldPosition = transformPosition(transformT, 0, 1, 0);
WgMissileEntity wgMissileEntity = new WgMissileEntity(player, player.level(),
400,
60,
6);
wgMissileEntity.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
wgMissileEntity.shoot(getBarrelVector(1).x, 0, getBarrelVector(1).z, 2f, 0f);
player.level().addFreshEntity(wgMissileEntity);
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.playSound(ModSounds.BMP_MISSILE_FIRE_3P.get(), 6, 1);
}
}
this.entityData.set(LOADED_MISSILE, this.getEntityData().get(LOADED_MISSILE) - 1);
reloadCoolDown = 160;
}
}
@ -581,7 +624,7 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
@Override
public SoundEvent getEngineSound() {
return ModSounds.LAV_ENGINE.get();
return ModSounds.BMP_ENGINE.get();
}
@Override
@ -737,6 +780,8 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
return (this.entityData.get(AMMO) > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) && !cannotFire;
} else if (entityData.get(WEAPON_TYPE) == 1) {
return (this.entityData.get(LOADED_COAX_AMMO) > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) && !cannotFireCoax;
} else if (entityData.get(WEAPON_TYPE) == 2) {
return (this.entityData.get(LOADED_MISSILE) > 0);
}
return false;
}
@ -767,8 +812,11 @@ public class Bmp2Entity extends ContainerMobileEntity implements GeoEntity, ICha
this.level().playSound(null, this, ModSounds.INTO_MISSILE.get(), this.getSoundSource(), 1, 1);
entityData.set(WEAPON_TYPE, 1);
} else if (entityData.get(WEAPON_TYPE) == 1) {
entityData.set(WEAPON_TYPE, 0);
entityData.set(WEAPON_TYPE, 2);
this.level().playSound(null, this, ModSounds.INTO_CANNON.get(), this.getSoundSource(), 1, 1);
} else if (entityData.get(WEAPON_TYPE) == 2) {
entityData.set(WEAPON_TYPE, 0);
this.level().playSound(null, this, ModSounds.INTO_MISSILE.get(), this.getSoundSource(), 1, 1);
}
}

View file

@ -748,11 +748,13 @@ public class ClientEventHandler {
if (iVehicle instanceof Bmp2Entity bmp2) {
if (multiWeaponVehicle.getWeaponType() == 0) {
float pitch = bmp2.getEntityData().get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * java.lang.Math.abs(60 - bmp2.getEntityData().get(HEAT)));
player.playSound(ModSounds.LAV_CANNON_FIRE_1P.get(), 1f, pitch);
player.playSound(ModSounds.BMP_CANNON_FIRE_1P.get(), 1f, pitch);
player.playSound(ModSounds.SHELL_CASING_50CAL.get(), 0.3f, 1);
} else if (multiWeaponVehicle.getWeaponType() == 1) {
float pitch = bmp2.getEntityData().get(COAX_HEAT) <= 60 ? 1 : (float) (1 - 0.011 * java.lang.Math.abs(60 - bmp2.getEntityData().get(COAX_HEAT)));
player.playSound(ModSounds.COAX_FIRE_1P.get(), 1f, pitch);
} else if (multiWeaponVehicle.getWeaponType() == 2) {
player.playSound(ModSounds.BMP_MISSILE_FIRE_1P.get(), 1f, 1);
}
}

View file

@ -68,7 +68,7 @@ public class ClientSoundHandler {
if (e instanceof Bmp2Entity bmp2) {
distanceReduce = (float) Math.max((1 - distance / 64), 0);
if (player.getVehicle() == bmp2) {
player.playSound(ModSounds.LAV_ENGINE_1P.get(), 2 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f), (float) ((2 * Math.random() - 1) * 0.1f + 0.95f));
player.playSound(ModSounds.BMP_ENGINE_1P.get(), 2 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f), (float) ((2 * Math.random() - 1) * 0.1f + 0.95f));
} else {
player.level().playLocalSound(BlockPos.containing(engineSoundPos), engineSound, mobileVehicle.getSoundSource(), 5 * (Mth.abs(mobileVehicle.getEntityData().get(POWER)) + Mth.abs(0.08f * mobileVehicle.getEntityData().get(DELTA_ROT)) - 0.004f) * distanceReduce * distanceReduce, (float) ((2 * Math.random() - 1) * 0.1f + 1), false);
}

View file

@ -84,6 +84,8 @@ public class ModEntities {
EntityType.Builder.<MelonBombEntity>of(MelonBombEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(MelonBombEntity::new).sized(1f, 1f));
public static final RegistryObject<EntityType<Bmp2Entity>> BMP_2 = register("bmp_2",
EntityType.Builder.<Bmp2Entity>of(Bmp2Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(Bmp2Entity::new).fireImmune().sized(4f, 3f));
public static final RegistryObject<EntityType<WgMissileEntity>> WG_MISSILE = register("wg_missile",
EntityType.Builder.<WgMissileEntity>of(WgMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(WgMissileEntity::new).fireImmune().sized(0.5f, 0.5f));
private static <T extends Entity> RegistryObject<EntityType<T>> register(String name, EntityType.Builder<T> entityTypeBuilder) {
return REGISTRY.register(name, () -> entityTypeBuilder.build(name));

View file

@ -40,5 +40,6 @@ public class ModEntityRenderers {
event.registerEntityRenderer(ModEntities.TOM_6.get(), Tom6Renderer::new);
event.registerEntityRenderer(ModEntities.MELON_BOMB.get(), MelonBombEntityRenderer::new);
event.registerEntityRenderer(ModEntities.BMP_2.get(), Bmp2Renderer::new);
event.registerEntityRenderer(ModEntities.WG_MISSILE.get(), WgMissileRenderer::new);
}
}

View file

@ -108,8 +108,9 @@ public class ModItems {
public static final RegistryObject<Item> CLAYMORE_MINE = AMMO.register("claymore_mine", ClaymoreMine::new);
public static final RegistryObject<Item> C4_BOMB = AMMO.register("c4_bomb", C4Bomb::new);
public static final RegistryObject<Item> HEAVY_AMMO = AMMO.register("heavy_ammo", () -> new Item(new Item.Properties()));
public static final RegistryObject<Item> ROCKET_70 = AMMO.register("rocket_70", () -> new Item(new Item.Properties()));
public static final RegistryObject<Item> SMALL_SHELL = AMMO.register("small_shell", () -> new Item(new Item.Properties()));
public static final RegistryObject<Item> ROCKET_70 = AMMO.register("rocket_70", () -> new Item(new Item.Properties()));
public static final RegistryObject<Item> WIRE_GUIDE_MISSILE = AMMO.register("wire_guide_missile", () -> new Item(new Item.Properties()));
public static final RegistryObject<Item> BEAM_TEST = AMMO.register("beam_test", BeamTest::new);
/**

View file

@ -403,5 +403,13 @@ public class ModSounds {
public static final RegistryObject<SoundEvent> LAV_ENGINE = REGISTRY.register("lav_engine", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lav_engine")));
public static final RegistryObject<SoundEvent> LAV_ENGINE_1P = REGISTRY.register("lav_engine_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("lav_engine_1p")));
public static final RegistryObject<SoundEvent> COAX_FIRE_1P = REGISTRY.register("coax_fire_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("coax_fire_1p")));
public static final RegistryObject<SoundEvent> BMP_CANNON_FIRE_1P = REGISTRY.register("bmp_cannon_fire_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_fire_1p")));
public static final RegistryObject<SoundEvent> BMP_CANNON_FIRE_3P = REGISTRY.register("bmp_cannon_fire_3p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_fire_3p")));
public static final RegistryObject<SoundEvent> BMP_ENGINE = REGISTRY.register("bmp_engine", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_engine")));
public static final RegistryObject<SoundEvent> BMP_ENGINE_1P = REGISTRY.register("bmp_engine_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_engine_1p")));
public static final RegistryObject<SoundEvent> BMP_MISSILE_FIRE_1P = REGISTRY.register("bmp_missile_fire_1p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_missile_fire_1p")));
public static final RegistryObject<SoundEvent> BMP_MISSILE_FIRE_3P = REGISTRY.register("bmp_missile_fire_3p", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_missile_fire_3p")));
public static final RegistryObject<SoundEvent> BMP_MISSILE_RELOAD = REGISTRY.register("bmp_missile_reload", () -> SoundEvent.createVariableRangeEvent(ModUtils.loc("bmp_missile_reload")));
}

View file

@ -0,0 +1,173 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.rpg",
"texture_width": 64,
"texture_height": 64,
"visible_bounds_width": 91,
"visible_bounds_height": 10,
"visible_bounds_offset": [0, 1, 0]
},
"bones": [
{
"name": "bone",
"pivot": [0, 0, -0.11791]
},
{
"name": "flare",
"parent": "bone",
"pivot": [0, -0.67, 0],
"cubes": [
{
"origin": [-23.45, -0.63, -1.05],
"size": [22.4, 0, 2.1],
"uv": {
"up": {"uv": [40, 64], "uv_size": [-36, -4]},
"down": {"uv": [40, 64], "uv_size": [-36, -4]}
}
},
{
"origin": [-34.65, -0.63, -1.05],
"size": [33.6, 0, 2.1],
"pivot": [0, 0, 0],
"rotation": [0, 90, 0],
"uv": {
"up": {"uv": [40, 64], "uv_size": [-36, -4]},
"down": {"uv": [40, 64], "uv_size": [-36, -4]}
}
},
{
"origin": [-23.45, -0.63, -1.05],
"size": [22.4, 0, 2.1],
"pivot": [0, 0, 0],
"rotation": [0, 180, 0],
"uv": {
"up": {"uv": [40, 64], "uv_size": [-36, -4]},
"down": {"uv": [40, 64], "uv_size": [-36, -4]}
}
},
{
"origin": [-22.4, 20.3, -1.4],
"size": [44.8, 0, 2.8],
"pivot": [0, 20.3, 0],
"rotation": [135, 0, 90],
"uv": {
"up": {"uv": [40, 64], "uv_size": [-36, -4]},
"down": {"uv": [40, 64], "uv_size": [-36, -4]}
}
},
{
"origin": [-22.4, 20.3, -1.4],
"size": [44.8, 0, 2.8],
"pivot": [0, 20.3, 0],
"rotation": [-135, 0, 90],
"uv": {
"up": {"uv": [40, 64], "uv_size": [-36, -4]},
"down": {"uv": [40, 64], "uv_size": [-36, -4]}
}
},
{
"origin": [-34.65, -0.63, -1.05],
"size": [33.6, 0, 2.1],
"pivot": [0, 0, 0],
"rotation": [0, -90, 0],
"uv": {
"up": {"uv": [40, 64], "uv_size": [-36, -4]},
"down": {"uv": [40, 64], "uv_size": [-36, -4]}
}
},
{
"origin": [-3.85, -0.63, -3.85],
"size": [7.7, 0, 7.7],
"pivot": [0, -0.63, 0],
"rotation": [0, -45, 0],
"uv": {
"north": {"uv": [4, 60], "uv_size": [4, 4]},
"east": {"uv": [4, 60], "uv_size": [4, 4]},
"south": {"uv": [4, 60], "uv_size": [4, 4]},
"west": {"uv": [4, 60], "uv_size": [4, 4]},
"up": {"uv": [8, 64], "uv_size": [-4, -4]},
"down": {"uv": [8, 64], "uv_size": [-4, -4]}
}
},
{
"origin": [-3.5, 1.82, -3.5],
"size": [7, 0, 7],
"pivot": [0, 1.82, 0],
"rotation": [90, -45, 0],
"uv": {
"north": {"uv": [4, 60], "uv_size": [4, 4]},
"east": {"uv": [4, 60], "uv_size": [4, 4]},
"south": {"uv": [4, 60], "uv_size": [4, 4]},
"west": {"uv": [4, 60], "uv_size": [4, 4]},
"up": {"uv": [8, 64], "uv_size": [-4, -4]},
"down": {"uv": [8, 64], "uv_size": [-4, -4]}
}
},
{
"origin": [-3.5, 1.82, -3.5],
"size": [7, 0, 7],
"pivot": [0, 1.82, 0],
"rotation": [90, 45, 0],
"uv": {
"north": {"uv": [4, 60], "uv_size": [4, 4]},
"east": {"uv": [4, 60], "uv_size": [4, 4]},
"south": {"uv": [4, 60], "uv_size": [4, 4]},
"west": {"uv": [4, 60], "uv_size": [4, 4]},
"up": {"uv": [8, 64], "uv_size": [-4, -4]},
"down": {"uv": [8, 64], "uv_size": [-4, -4]}
}
}
]
},
{
"name": "body",
"parent": "bone",
"pivot": [0, -51.91, 0],
"cubes": [
{
"origin": [-3, -30.1186, -3],
"size": [6, 29.2372, 6],
"uv": {
"north": {"uv": [2, 4], "uv_size": [-2, -4]},
"east": {"uv": [2, 4], "uv_size": [-2, -4]},
"south": {"uv": [2, 4], "uv_size": [-2, -4]},
"west": {"uv": [2, 4], "uv_size": [-2, -4]},
"up": {"uv": [17, 0], "uv_size": [2, 3]},
"down": {"uv": [11, 9], "uv_size": [2, 2]}
}
},
{
"origin": [-0.75, -11.1186, -5.5],
"size": [1.5, 10.2372, 11],
"uv": {
"north": {"uv": [2, 4], "uv_size": [-2, -4]},
"east": {"uv": [2, 4], "uv_size": [-2, -4]},
"south": {"uv": [2, 4], "uv_size": [-2, -4]},
"west": {"uv": [2, 4], "uv_size": [-2, -4]},
"up": {"uv": [17, 0], "uv_size": [2, 3]},
"down": {"uv": [11, 9], "uv_size": [2, 2]}
}
},
{
"origin": [-0.75, -11.1186, -5.5],
"size": [1.5, 10.2372, 11],
"pivot": [0, -6, 0],
"rotation": [0, -90, 0],
"uv": {
"north": {"uv": [2, 4], "uv_size": [-2, -4]},
"east": {"uv": [2, 4], "uv_size": [-2, -4]},
"south": {"uv": [2, 4], "uv_size": [-2, -4]},
"west": {"uv": [2, 4], "uv_size": [-2, -4]},
"up": {"uv": [17, 0], "uv_size": [2, 3]},
"down": {"uv": [11, 9], "uv_size": [2, 2]}
}
}
]
}
]
}
]
}

View file

@ -156,6 +156,7 @@
"item.superbwarfare.lunge_mine": "Lunge Mine",
"item.superbwarfare.rocket_70": "70mm Rocket",
"item.superbwarfare.small_shell": "Small Caliber Shells",
"item.superbwarfare.wire_guide_missile": "Wire Guide Missile",
"block.superbwarfare.container": "Container",
"des.superbwarfare.container.empty": "空的",
@ -401,6 +402,8 @@
"entity.minecraft.villager.superbwarfare.armory": "Armory",
"entity.superbwarfare.tom_6": "Tom F6F",
"entity.superbwarfare.melon_bomb": "Melon Bomb",
"entity.superbwarfare.bmp_2": "BMP-2",
"entity.superbwarfare.wg_missile": "Wire Guide Missile",
"key.categories.superbwarfare": "Superb Warfare",
"key.superbwarfare.hold_zoom": "Zoom(Hold)",

View file

@ -156,6 +156,7 @@
"item.superbwarfare.lunge_mine": "突刺爆雷",
"item.superbwarfare.rocket_70": "70mm火箭弹",
"item.superbwarfare.small_shell": "小口径炮弹",
"item.superbwarfare.wire_guide_missile": "线控导弹",
"block.superbwarfare.container": "集装箱",
"des.superbwarfare.container.empty": "空的",
@ -395,10 +396,12 @@
"entity.superbwarfare.speedboat": "快艇",
"entity.superbwarfare.wheel_chair": "轮椅",
"entity.superbwarfare.ah_6": "AH-6 小鸟直升机",
"entity.superbwarfare.lav_150": "LAV-150 Commando",
"entity.superbwarfare.lav_150": "LAV-150 轮式步兵战车",
"entity.minecraft.villager.superbwarfare.armory": "军械师",
"entity.superbwarfare.tom_6": "汤姆 F6F",
"entity.superbwarfare.melon_bomb": "西瓜航弹",
"entity.superbwarfare.bmp_2": "BMP-2 履带式步兵战车",
"entity.superbwarfare.wg_missile": "线控导弹",
"key.categories.superbwarfare": "卓越前线",
"key.superbwarfare.hold_zoom": "瞄准(按住)",

View file

@ -2757,5 +2757,59 @@
"name": "superbwarfare:lav/coax_fire_1p"
}
]
},
"bmp_fire_1p": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_fire_1p",
"stream": false
}
]
},
"bmp_fire_3p": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_fire_3p",
"stream": false
}
]
},
"bmp_engine": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_engine"
}
]
},
"bmp_engine_1p": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_engine_1p"
}
]
},
"bmp_missile_fire_1p": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_missile_fire_1p",
"stream": false
}
]
},
"bmp_missile_fire_3p": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_missile_fire_3p",
"stream": false
}
]
},
"bmp_missile_reload": {
"sounds": [
{
"name": "superbwarfare:bmp/bmp_missile_reload",
"stream": false
}
]
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 252 B