添加XY100坦克

This commit is contained in:
Atsuihsio 2025-03-03 14:24:13 +08:00
parent 0940186599
commit 84d93078ad
15 changed files with 11891 additions and 4 deletions

View file

@ -0,0 +1,36 @@
package com.atsuishio.superbwarfare.client.model.entity;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.entity.vehicle.Yx100GunEntity;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.util.Mth;
import software.bernie.geckolib.constant.DataTickets;
import software.bernie.geckolib.core.animatable.model.CoreGeoBone;
import software.bernie.geckolib.core.animation.AnimationState;
import software.bernie.geckolib.model.GeoModel;
import software.bernie.geckolib.model.data.EntityModelData;
public class Yx100GunModel extends GeoModel<Yx100GunEntity> {
@Override
public ResourceLocation getAnimationResource(Yx100GunEntity entity) {
return null;
}
@Override
public ResourceLocation getModelResource(Yx100GunEntity entity) {
return ModUtils.loc("geo/yx_100_gun.geo.json");
}
@Override
public ResourceLocation getTextureResource(Yx100GunEntity entity) {
return ModUtils.loc("textures/entity/yx_100.png");
}
@Override
public void setCustomAnimations(Yx100GunEntity animatable, long instanceId, AnimationState<Yx100GunEntity> animationState) {
CoreGeoBone bone = getAnimationProcessor().getBone("barrel");
EntityModelData entityData = animationState.getData(DataTickets.ENTITY_MODEL_DATA);
bone.setRotX((entityData.headPitch()) * Mth.DEG_TO_RAD);
}
}

View file

@ -0,0 +1,125 @@
package com.atsuishio.superbwarfare.client.model.entity;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.entity.vehicle.Yx100Entity;
import net.minecraft.resources.ResourceLocation;
import software.bernie.geckolib.model.GeoModel;
public class Yx100Model extends GeoModel<Yx100Entity> {
@Override
public ResourceLocation getAnimationResource(Yx100Entity entity) {
return null;
}
@Override
public ResourceLocation getModelResource(Yx100Entity entity) {
return ModUtils.loc("geo/yx_100.geo.json");
// Player player = Minecraft.getInstance().player;
//
// int distance = 0;
//
// if (player != null) {
// distance = (int) player.position().distanceTo(entity.position());
// }
//
// if (distance < 32) {
// return ModUtils.loc("geo/Yx100.geo.json");
// } else {
// return ModUtils.loc("geo/speedboat.lod1.geo.json");
// }
}
@Override
public ResourceLocation getTextureResource(Yx100Entity entity) {
return ModUtils.loc("textures/entity/yx_100.png");
}
// @Override
// public void setCustomAnimations(Yx100Entity animatable, long instanceId, AnimationState<Yx100Entity> animationState) {
// for (int i = 0; i < 50; i++) {
// CoreGeoBone trackL = getAnimationProcessor().getBone("trackL" + i);
// CoreGeoBone trackLRot = getAnimationProcessor().getBone("trackLRot" + i);
// CoreGeoBone trackR = getAnimationProcessor().getBone("trackR" + i);
// CoreGeoBone trackRRot = getAnimationProcessor().getBone("trackRRot" + i);
//
// float t = animatable.getEntityData().get(TRACK_L) + 2 * i;
//
// if (t >= 100) {
// t -= 100;
// }
//
// trackAnimation(trackL, trackLRot, t);
//
// float t2 = animatable.getEntityData().get(TRACK_R) + 2 * i;
//
// if (t2 >= 100) {
// t2 -= 100;
// }
//
// trackAnimation(trackR, trackRRot, t2);
// }
// }
//
// public void trackAnimation(CoreGeoBone track, CoreGeoBone trackRot, float t) {
// if (t < 37.5) {
// track.setPosY(0);
// track.setPosZ(3 * t);
// trackRot.setRotX(0);
// }
//
// if (t >= 37.5 && t < 39.5) {
// track.setPosY(-(t - 37.5f) * 3 * 0.7071f);
// track.setPosZ(3 * 37.5f + (t - 37.5f) * 3 * 0.7071f);
// trackRot.setRotX(45 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 39.5 && t < 41.5) {
// track.setPosY(-5.3f - (t - 39.5f) * 3);
// track.setPosZ(116);
// trackRot.setRotX(90 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 41.5 && t < 43) {
// track.setPosY(-11.6f - (t - 41.5f) * 3 * 0.7071f);
// track.setPosZ(115 - (t - 41.5f) * 3 * 0.7071f);
// trackRot.setRotX(135 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 43 && t < 49.5) {
// track.setPosY(-15.6f - (t - 43f) * 3 * 0.45f);
// track.setPosZ(109.5f - (t - 43f) * 3 * 0.75f);
// trackRot.setRotX(150 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 49.5 && t < 76.5) {
// track.setPosY(-23.5f);
// track.setPosZ(95f - (t - 49.5f) * 3);
// trackRot.setRotX(180 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 76.5 && t < 83.5) {
// track.setPosY(-23.5f + (t - 76.5f) * 3 * 0.45f);
// track.setPosZ(13.5f - (t - 76.5f) * 3 * 0.75f);
// trackRot.setRotX(210 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 83.5 && t < 85.5) {
// track.setPosY(-12.7f + (t - 83.5f) * 3 * 0.7071f);
// track.setPosZ(-3.5f - (t - 83.5f) * 3 * 0.7071f);
// trackRot.setRotX(225 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 85.5 && t < 87) {
// track.setPosY(-9.2f + (t - 85.5f) * 3);
// track.setPosZ(-6.9f);
// trackRot.setRotX(270 * Mth.DEG_TO_RAD);
// }
//
// if (t >= 87 && t < 89) {
// track.setPosY(-4.3f + (t - 87f) * 3 * 0.7071f);
// track.setPosZ(-6.9f + (t - 87f) * 3 * 0.7071f);
// trackRot.setRotX(315 * Mth.DEG_TO_RAD);
// }
// }
}

View file

@ -0,0 +1,43 @@
package com.atsuishio.superbwarfare.client.renderer.entity;
import com.atsuishio.superbwarfare.client.model.entity.Yx100GunModel;
import com.atsuishio.superbwarfare.entity.vehicle.Yx100GunEntity;
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 Yx100GunRenderer extends GeoEntityRenderer<Yx100GunEntity> {
public Yx100GunRenderer(EntityRendererProvider.Context renderManager) {
super(renderManager, new Yx100GunModel());
}
@Override
public RenderType getRenderType(Yx100GunEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
@Override
public void preRender(PoseStack poseStack, Yx100GunEntity 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(Yx100GunEntity 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())));
super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
poseStack.popPose();
}
}

View file

@ -0,0 +1,78 @@
package com.atsuishio.superbwarfare.client.renderer.entity;
import com.atsuishio.superbwarfare.client.model.entity.Yx100Model;
import com.atsuishio.superbwarfare.entity.vehicle.Yx100Entity;
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.cache.object.GeoBone;
import software.bernie.geckolib.renderer.GeoEntityRenderer;
public class Yx100Renderer extends GeoEntityRenderer<Yx100Entity> {
public Yx100Renderer(EntityRendererProvider.Context renderManager) {
super(renderManager, new Yx100Model());
// this.addRenderLayer(new Yx100Layer(this));
}
@Override
public RenderType getRenderType(Yx100Entity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
return RenderType.entityTranslucent(getTextureLocation(animatable));
}
@Override
public void preRender(PoseStack poseStack, Yx100Entity 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(Yx100Entity 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())));
super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn);
poseStack.popPose();
}
@Override
public void renderRecursively(PoseStack poseStack, Yx100Entity animatable, GeoBone bone, RenderType renderType, MultiBufferSource bufferSource, VertexConsumer buffer, boolean isReRender, float partialTick, int packedLight, int packedOverlay, float red, float green, float blue, float alpha) {
String name = bone.getName();
for (int i = 0; i < 8; i++) {
if (name.equals("wheelL" + i)) {
bone.setRotX(1.5f * Mth.lerp(partialTick, animatable.leftWheelRotO, animatable.getLeftWheelRot()));
}
if (name.equals("wheelR" + i)) {
bone.setRotX(1.5f * Mth.lerp(partialTick, animatable.rightWheelRotO, animatable.getRightWheelRot()));
}
}
if (name.equals("turret")) {
bone.setRotY(Mth.lerp(partialTick, animatable.turretYRotO, animatable.getTurretYRot()) * Mth.DEG_TO_RAD);
}
if (name.equals("barrel")) {
bone.setRotX(-Mth.lerp(partialTick, animatable.turretXRotO, animatable.getTurretXRot()) * Mth.DEG_TO_RAD);
}
if (name.equals("flare")) {
bone.setRotZ((float) (0.5 * (Math.random() - 0.5)));
}
if (name.equals("flare2")) {
bone.setRotZ((float) (0.5 * (Math.random() - 0.5)));
}
if (name.equals("leida") && animatable.getEnergy() > 0) {
bone.setRotY((System.currentTimeMillis() % 36000000) / 300f);
}
super.renderRecursively(poseStack, animatable, bone, renderType, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha);
}
}

View file

@ -139,13 +139,13 @@ public class VehicleEntity extends Entity {
return InteractionResult.SUCCESS;
} else if (!player.isShiftKeyDown()) {
if (this.getFirstPassenger() == null) {
player.setXRot(this.getXRot());
player.setYRot(this.getYRot());
// player.setXRot(this.getXRot());
// player.setYRot(this.getYRot());
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
} else if (!(this.getFirstPassenger() instanceof Player)) {
this.getFirstPassenger().stopRiding();
player.setXRot(this.getXRot());
player.setYRot(this.getYRot());
// player.setXRot(this.getXRot());
// player.setYRot(this.getYRot());
return player.startRiding(this) ? InteractionResult.CONSUME : InteractionResult.PASS;
}
if (this.canAddPassenger(player)) {

View file

@ -0,0 +1,749 @@
package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.config.server.ExplosionConfig;
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.vehicle.damage.DamageModifier;
import com.atsuishio.superbwarfare.init.*;
import com.atsuishio.superbwarfare.network.message.ShakeClientMessage;
import com.atsuishio.superbwarfare.tools.CustomExplosion;
import com.atsuishio.superbwarfare.tools.EntityFindUtil;
import com.atsuishio.superbwarfare.tools.ParticleTool;
import com.atsuishio.superbwarfare.tools.SoundTool;
import com.mojang.math.Axis;
import net.minecraft.core.BlockPos;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.level.ServerPlayer;
import net.minecraft.sounds.SoundEvent;
import net.minecraft.util.Mth;
import net.minecraft.world.damagesource.DamageTypes;
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.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks;
import net.minecraftforge.network.PacketDistributor;
import net.minecraftforge.network.PlayMessages;
import org.jetbrains.annotations.NotNull;
import org.joml.Matrix4f;
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.util.GeckoLibUtil;
import java.util.Comparator;
import java.util.List;
import static com.atsuishio.superbwarfare.tools.ParticleTool.sendParticle;
public class Yx100Entity extends ContainerMobileVehicleEntity implements GeoEntity, ILandArmorEntity, MultiWeaponVehicleEntity {
public static final EntityDataAccessor<Integer> FIRE_ANIM = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Float> DELTA_ROT = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Integer> HEAT = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> COAX_HEAT = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> AMMO = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Integer> WEAPON_TYPE = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.INT);
public static final EntityDataAccessor<Float> TRACK_L = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.FLOAT);
public static final EntityDataAccessor<Float> TRACK_R = SynchedEntityData.defineId(Yx100Entity.class, EntityDataSerializers.FLOAT);
public static final float MAX_HEALTH = VehicleConfig.BMP_2_HP.get();
public static final int MAX_ENERGY = VehicleConfig.BMP_2_MAX_ENERGY.get();
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public float turretYRot;
public float turretXRot;
public float turretYRotO;
public float turretXRotO;
public float leftWheelRot;
public float rightWheelRot;
public float leftWheelRotO;
public float rightWheelRotO;
public boolean cannotFire;
public boolean cannotFireCoax;
public int reloadCoolDown;
public Yx100Entity(PlayMessages.SpawnEntity packet, Level world) {
this(ModEntities.YX_100.get(), world);
}
public Yx100Entity(EntityType<Yx100Entity> type, Level world) {
super(type, world);
this.setMaxUpStep(1.5f);
}
@Override
protected void defineSynchedData() {
super.defineSynchedData();
this.entityData.define(AMMO, 0);
this.entityData.define(FIRE_ANIM, 0);
this.entityData.define(DELTA_ROT, 0f);
this.entityData.define(HEAT, 0);
this.entityData.define(COAX_HEAT, 0);
this.entityData.define(WEAPON_TYPE, 0);
this.entityData.define(TRACK_L, 0f);
this.entityData.define(TRACK_R, 0f);
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
}
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public DamageModifier getDamageModifier() {
return super.getDamageModifier()
.multiply(0.3f, DamageTypes.ARROW)
.multiply(0.3f, DamageTypes.TRIDENT)
.multiply(0.5f, DamageTypes.MOB_ATTACK)
.multiply(0.4f, DamageTypes.MOB_ATTACK_NO_AGGRO)
.multiply(0.3f, DamageTypes.MOB_PROJECTILE)
.multiply(0.2f, DamageTypes.PLAYER_ATTACK)
.multiply(2.5f, DamageTypes.LAVA)
.multiply(1.2f, DamageTypes.EXPLOSION)
.multiply(1.2f, DamageTypes.PLAYER_EXPLOSION)
.multiply(0.4f, ModDamageTypes.CUSTOM_EXPLOSION)
.multiply(0.4f, ModDamageTypes.PROJECTILE_BOOM)
.multiply(0.14f, ModDamageTypes.MINE)
.multiply(0.18f, ModDamageTypes.LUNGE_MINE)
.multiply(0.3f, ModDamageTypes.CANNON_FIRE)
.multiply(0.02f, ModTags.DamageTypes.PROJECTILE)
.multiply(0.14f, ModTags.DamageTypes.PROJECTILE_ABSOLUTE)
.multiply(1.7f, ModDamageTypes.VEHICLE_STRIKE)
.reduce(8);
}
@Override
protected void playStepSound(BlockPos pPos, BlockState pState) {
this.playSound(ModSounds.BMP_STEP.get(), Mth.abs(this.entityData.get(POWER)) * 8, random.nextFloat() * 0.15f + 1f);
}
@Override
public double getSubmergedHeight(Entity entity) {
return super.getSubmergedHeight(entity);
}
@Override
public void baseTick() {
turretYRotO = this.getTurretYRot();
turretXRotO = this.getTurretXRot();
leftWheelRotO = this.getLeftWheelRot();
rightWheelRotO = this.getRightWheelRot();
super.baseTick();
if (this.entityData.get(TRACK_R) < 0) {
this.entityData.set(TRACK_R, 100f);
}
if (this.entityData.get(TRACK_R) > 100) {
this.entityData.set(TRACK_R, 0f);
}
if (this.entityData.get(TRACK_L) < 0) {
this.entityData.set(TRACK_L, 100f);
}
if (this.entityData.get(TRACK_L) > 100) {
this.entityData.set(TRACK_L, 0f);
}
if (this.entityData.get(HEAT) > 0) {
this.entityData.set(HEAT, this.entityData.get(HEAT) - 1);
}
if (this.entityData.get(FIRE_ANIM) > 0) {
this.entityData.set(FIRE_ANIM, this.entityData.get(FIRE_ANIM) - 1);
}
if (this.entityData.get(HEAT) < 40) {
cannotFire = false;
}
if (this.entityData.get(COAX_HEAT) > 0) {
this.entityData.set(COAX_HEAT, this.entityData.get(COAX_HEAT) - 1);
}
if (this.entityData.get(COAX_HEAT) < 40) {
cannotFireCoax = false;
}
if (this.level() instanceof ServerLevel) {
if (reloadCoolDown > 0) {
reloadCoolDown--;
}
this.handleAmmo();
}
Entity driver = this.getFirstPassenger();
if (driver instanceof Player player) {
if (this.entityData.get(HEAT) > 100) {
cannotFire = true;
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 1f, 1f);
}
}
if (this.entityData.get(COAX_HEAT) > 100) {
cannotFireCoax = true;
if (!player.level().isClientSide() && player instanceof ServerPlayer serverPlayer) {
SoundTool.playLocalSound(serverPlayer, ModSounds.MINIGUN_OVERHEAT.get(), 1f, 1f);
}
}
}
if (this.onGround()) {
float f0 = 0.54f + 0.25f * Mth.abs(90 - (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) / 90;
this.setDeltaMovement(this.getDeltaMovement().add(this.getViewVector(1).normalize().scale(0.05 * this.getDeltaMovement().horizontalDistance())));
this.setDeltaMovement(this.getDeltaMovement().multiply(f0, 0.85, f0));
} else if (this.isInWater()) {
float f1 = 0.61f + 0.08f * Mth.abs(90 - (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1))) / 90;
this.setDeltaMovement(this.getDeltaMovement().add(this.getViewVector(1).normalize().scale(0.04 * this.getDeltaMovement().horizontalDistance())));
this.setDeltaMovement(this.getDeltaMovement().multiply(f1, 0.85, f1));
} else {
this.setDeltaMovement(this.getDeltaMovement().multiply(0.99, 0.95, 0.99));
}
if (this.level() instanceof ServerLevel serverLevel && this.isInWater() && this.getDeltaMovement().length() > 0.1) {
sendParticle(serverLevel, ParticleTypes.CLOUD, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int) (2 + 4 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true);
sendParticle(serverLevel, ParticleTypes.BUBBLE_COLUMN_UP, this.getX() + 0.5 * this.getDeltaMovement().x, this.getY() + getSubmergedHeight(this) - 0.2, this.getZ() + 0.5 * this.getDeltaMovement().z, (int) (2 + 10 * this.getDeltaMovement().length()), 0.65, 0, 0.65, 0, true);
}
float deltaT = Math.abs(getTurretYRot() - turretYRotO);
while (getTurretYRot() > 180F) {
setTurretYRot(getTurretYRot() - 360F);
turretYRotO = getTurretYRot() - deltaT;
}
while (getTurretYRot() <= -180F) {
setTurretYRot(getTurretYRot() + 360F);
turretYRotO = deltaT + getTurretYRot();
}
collideBlock();
if (this.getDeltaMovement().length() > 0.15) {
collideHardBlock();
}
gunnerAngle();
lowHealthWarning();
// List<Entity> entities = this.getPassengers();
//
// for (var e : entities) {
// if (!(e instanceof Yx100GunEntity)) {
// Yx100GunEntity yx100Gun = new Yx100GunEntity(ModEntities.YX_100_GUN.get(), this.level());
// this.level().addFreshEntity(yx100Gun);
// yx100Gun.startRiding(this, true);
// }
// }
//
//// if (!(this.hasPassenger(yx100Gun))) {
////
//// }
this.refreshDimensions();
}
private void handleAmmo() {
if (!(this.getFirstPassenger() instanceof Player player)) return;
int ammoCount = this.getItemStacks().stream().filter(stack -> {
if (stack.is(ModItems.AMMO_BOX.get())) {
return stack.getOrCreateTag().getInt("RifleAmmo") > 0;
}
return false;
}).mapToInt(stack -> stack.getOrCreateTag().getInt("RifleAmmo")).sum()
+ this.getItemStacks().stream().filter(stack -> stack.is(ModItems.RIFLE_AMMO.get())).mapToInt(ItemStack::getCount).sum();
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 if (this.getEntityData().get(WEAPON_TYPE) == 1) {
this.entityData.set(AMMO, ammoCount);
}
}
@Override
public void move(@NotNull MoverType movementType, @NotNull Vec3 movement) {
super.move(movementType, movement);
if (this.isInWater() && horizontalCollision) {
setDeltaMovement(this.getDeltaMovement().add(0, 0.07, 0));
}
}
@Override
public void vehicleShoot(Player player) {
Matrix4f transform = getBarrelTransform();
if (entityData.get(WEAPON_TYPE) == 0) {
if (this.cannotFire) return;
float x = -0.1125f;
float y = 0.174025f;
float z = 4.2f;
Vector4f worldPosition = transformPosition(transform, x, y, z);
SmallCannonShellEntity smallCannonShell = new SmallCannonShellEntity(player, this.level(),
VehicleConfig.BMP_2_CANNON_DAMAGE.get(),
VehicleConfig.BMP_2_CANNON_EXPLOSION_DAMAGE.get(),
VehicleConfig.BMP_2_CANNON_EXPLOSION_RADIUS.get().floatValue());
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, 20,
0.25f);
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);
float pitch = this.entityData.get(HEAT) <= 60 ? 1 : (float) (1 - 0.011 * Math.abs(60 - this.entityData.get(HEAT)));
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
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);
}
}
Level level = player.level();
final Vec3 center = new Vec3(this.getX(), this.getEyeY(), this.getZ());
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, 9, this.getX(), this.getEyeY(), this.getZ()));
}
}
this.entityData.set(HEAT, this.entityData.get(HEAT) + 7);
this.entityData.set(FIRE_ANIM, 3);
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.SMALL_SHELL.get())).findFirst().ifPresent(stack -> stack.shrink(1));
} else if (entityData.get(WEAPON_TYPE) == 1) {
if (this.cannotFireCoax) return;
float x = 0.1125f;
float y = 0.174025f;
float z = 2f;
Vector4f worldPosition = transformPosition(transform, x, y, z);
boolean hasCreativeAmmo = player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()));
if (this.entityData.get(AMMO) > 0 || hasCreativeAmmo) {
ProjectileEntity projectileRight = new ProjectileEntity(player.level())
.shooter(player)
.damage(9.5f)
.headShot(2f)
.zoom(false);
projectileRight.bypassArmorRate(0.2f);
projectileRight.setPos(worldPosition.x - 1.1 * this.getDeltaMovement().x, worldPosition.y, worldPosition.z - 1.1 * this.getDeltaMovement().z);
projectileRight.shoot(player, getBarrelVector(1).x, getBarrelVector(1).y + 0.002f, getBarrelVector(1).z, 36,
0.25f);
this.level().addFreshEntity(projectileRight);
if (!hasCreativeAmmo) {
ItemStack ammoBox = this.getItemStacks().stream().filter(stack -> {
if (stack.is(ModItems.AMMO_BOX.get())) {
return stack.getOrCreateTag().getInt("RifleAmmo") > 0;
}
return false;
}).findFirst().orElse(ItemStack.EMPTY);
if (!ammoBox.isEmpty()) {
ammoBox.getOrCreateTag().putInt("RifleAmmo", Math.max(0, ammoBox.getOrCreateTag().getInt("RifleAmmo") - 1));
} else {
this.getItemStacks().stream().filter(stack -> stack.is(ModItems.RIFLE_AMMO.get())).findFirst().ifPresent(stack -> stack.shrink(1));
}
}
}
this.entityData.set(COAX_HEAT, this.entityData.get(COAX_HEAT) + 3);
this.entityData.set(FIRE_ANIM, 2);
if (!player.level().isClientSide) {
if (player instanceof ServerPlayer serverPlayer) {
serverPlayer.playSound(ModSounds.M_60_FIRE_3P.get(), 3, 1);
serverPlayer.playSound(ModSounds.M_60_FAR.get(), 6, 1);
serverPlayer.playSound(ModSounds.M_60_VERYFAR.get(), 12, 1);
}
}
}
}
public final Vec3 getBarrelVector(float pPartialTicks) {
return this.calculateViewVector(this.getBarrelXRot(pPartialTicks), this.getBarrelYRot(pPartialTicks));
}
public float getBarrelXRot(float pPartialTicks) {
return Mth.lerp(pPartialTicks, turretXRotO - this.xRotO, getTurretXRot() - this.getXRot());
}
public float getBarrelYRot(float pPartialTick) {
return -Mth.lerp(pPartialTick, turretYRotO - this.yRotO, getTurretYRot() - this.getYRot());
}
@Override
public void travel() {
Entity passenger0 = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
if (this.getEnergy() <= 0) return;
if (!(passenger0 instanceof Player)) {
this.leftInputDown = false;
this.rightInputDown = false;
this.forwardInputDown = false;
this.backInputDown = false;
this.entityData.set(POWER, 0f);
}
if (forwardInputDown) {
this.entityData.set(POWER, Math.min(this.entityData.get(POWER) + (this.entityData.get(POWER) < 0 ? 0.016f : 0.0024f), 0.21f));
}
if (backInputDown) {
this.entityData.set(POWER, Math.max(this.entityData.get(POWER) - (this.entityData.get(POWER) > 0 ? 0.016f : 0.0024f), -0.16f));
if (rightInputDown) {
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) + 0.1f);
} else if (this.leftInputDown) {
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) - 0.1f);
}
} else {
if (rightInputDown) {
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) - 0.1f);
} else if (this.leftInputDown) {
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) + 0.1f);
}
}
if (this.forwardInputDown || this.backInputDown) {
this.consumeEnergy(VehicleConfig.BMP_2_ENERGY_COST.get());
}
this.entityData.set(POWER, this.entityData.get(POWER) * (upInputDown ? 0.5f : (rightInputDown || leftInputDown) ? 0.947f : 0.96f));
this.entityData.set(DELTA_ROT, this.entityData.get(DELTA_ROT) * (float) Math.max(0.76f - 0.1f * this.getDeltaMovement().horizontalDistance(), 0.3));
float angle = (float) calculateAngle(this.getDeltaMovement(), this.getViewVector(1));
double s0;
if (Mth.abs(angle) < 90) {
s0 = this.getDeltaMovement().horizontalDistance();
} else {
s0 = -this.getDeltaMovement().horizontalDistance();
}
this.setLeftWheelRot((float) ((this.getLeftWheelRot() - 1.25 * s0) + Mth.clamp(0.75f * this.entityData.get(DELTA_ROT), -5f, 5f)));
this.setRightWheelRot((float) ((this.getRightWheelRot() - 1.25 * s0) - Mth.clamp(0.75f * this.entityData.get(DELTA_ROT), -5f, 5f)));
this.entityData.set(TRACK_L, (float) ((entityData.get(TRACK_L) - 1.9 * Math.PI * s0) + Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f)));
this.entityData.set(TRACK_R, (float) ((entityData.get(TRACK_R) - 1.9 * Math.PI * s0) - Mth.clamp(0.4f * Math.PI * this.entityData.get(DELTA_ROT), -5f, 5f)));
if (this.isInWater() || onGround()) {
this.setYRot((float) (this.getYRot() - (isInWater() && !onGround() ? 2.5 : 6) * entityData.get(DELTA_ROT)));
this.setDeltaMovement(this.getDeltaMovement().add(Mth.sin(-this.getYRot() * 0.017453292F) * (!isInWater() && !onGround() ? 0.13f : (isInWater() && !onGround() ? 2f : 2.4)) * this.entityData.get(POWER), 0.0, Mth.cos(this.getYRot() * 0.017453292F) * (!isInWater() && !onGround() ? 0.13f : (isInWater() && !onGround() ? 2f : 2.4)) * this.entityData.get(POWER)));
}
}
private void gunnerAngle() {
Entity driver = this.getFirstPassenger();
if (!(driver instanceof Player)) return;
float gunAngle = -Mth.wrapDegrees(driver.getYHeadRot() - this.getYRot());
float diffY;
float diffX;
diffY = Mth.wrapDegrees(gunAngle - getTurretYRot() + 0.05f);
diffX = Mth.wrapDegrees(driver.getXRot() - this.getTurretXRot());
this.setTurretXRot(Mth.clamp(this.getTurretXRot() + Mth.clamp(0.95f * diffX, -5, 5), -30f, 4f));
this.setTurretYRot(this.getTurretYRot() + Mth.clamp(0.95f * diffY, -8, 8));
}
@Override
public float turretYRotO() {
return turretYRotO;
}
@Override
public float turretYRot() {
return turretYRot;
}
@Override
public float turretXRotO() {
return turretXRotO;
}
@Override
public float turretXRot() {
return turretXRot;
}
@Override
public Vec3 getBarrelVec(float ticks) {
return getBarrelVector(ticks);
}
public float getTurretYRot() {
return this.turretYRot;
}
public void setTurretYRot(float pTurretYRot) {
this.turretYRot = pTurretYRot;
}
public float getTurretXRot() {
return this.turretXRot;
}
public void setTurretXRot(float pTurretXRot) {
this.turretXRot = pTurretXRot;
}
public float getLeftWheelRot() {
return this.leftWheelRot;
}
public void setLeftWheelRot(float pLeftWheelRot) {
this.leftWheelRot = pLeftWheelRot;
}
public float getRightWheelRot() {
return this.rightWheelRot;
}
public void setRightWheelRot(float pRightWheelRot) {
this.rightWheelRot = pRightWheelRot;
}
@Override
public SoundEvent getEngineSound() {
return ModSounds.BMP_ENGINE.get();
}
@Override
public void positionRider(@NotNull Entity passenger, @NotNull MoveFunction callback) {
// From Immersive_Aircraft
if (!this.hasPassenger(passenger)) {
return;
}
Matrix4f transform = getTurretTransform();
float x = 0.8669625f;
float y = 0.2f;
float z = 0.6076875f;
y += (float) passenger.getMyRidingOffset();
int i = this.getPassengers().indexOf(passenger);
Vector4f worldPosition = transformPosition(transform, x, y, z);
if (passenger instanceof Yx100GunEntity) {
worldPosition = transformPosition(transform, -x, y + 2, z);
}
passenger.setPos(worldPosition.x, worldPosition.y, worldPosition.z);
callback.accept(passenger, worldPosition.x, worldPosition.y, worldPosition.z);
}
public int getMaxPassengers() {
return 2;
}
public Matrix4f getBarrelTransform() {
Matrix4f transformT = getTurretTransform();
float x = 0f;
float y = 0.653275f;
float z = 0.750975f;
Vector4f worldPosition = transformPosition(transformT, x, y, z);
Matrix4f transform = new Matrix4f();
transform.translate(worldPosition.x, worldPosition.y, worldPosition.z);
transform.rotate(Axis.YP.rotationDegrees(getTurretYRot() - getYRot()));
transform.rotate(Axis.XP.rotationDegrees(getTurretXRot()));
transform.rotate(Axis.ZP.rotationDegrees(getRoll()));
return transform;
}
public Matrix4f getTurretTransform() {
Matrix4f transformT = getVehicleTransform();
float x = 0f;
float y = 2.1484375f;
float z = 0;
Vector4f worldPosition = transformPosition(transformT, x, y, z);
Matrix4f transform = new Matrix4f();
transform.translate(worldPosition.x, worldPosition.y, worldPosition.z);
transform.rotate(Axis.YP.rotationDegrees(getTurretYRot() - getYRot()));
transform.rotate(Axis.XP.rotationDegrees(getXRot()));
transform.rotate(Axis.ZP.rotationDegrees(getRoll()));
return transform;
}
@Override
public void destroy() {
Entity attacker = EntityFindUtil.findEntity(this.level(), this.entityData.get(LAST_ATTACKER_UUID));
if (level() instanceof ServerLevel) {
CustomExplosion explosion = new CustomExplosion(this.level(), this,
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), attacker, attacker), 80f,
this.getX(), this.getY(), this.getZ(), 5f, ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
explosion.explode();
net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion);
explosion.finalizeExplosion(false);
ParticleTool.spawnMediumExplosionParticles(this.level(), this.position());
}
List<Entity> passengers = this.getPassengers();
for (var entity : passengers) {
if (entity instanceof LivingEntity living) {
var tempAttacker = living == attacker ? null : attacker;
living.hurt(ModDamageTypes.causeVehicleExplosionDamage(this.level().registryAccess(), null, tempAttacker), Integer.MAX_VALUE);
living.invulnerableTime = 0;
living.hurt(ModDamageTypes.causeVehicleExplosionDamage(this.level().registryAccess(), null, tempAttacker), Integer.MAX_VALUE);
living.invulnerableTime = 0;
living.hurt(ModDamageTypes.causeVehicleExplosionDamage(this.level().registryAccess(), null, tempAttacker), Integer.MAX_VALUE);
living.invulnerableTime = 0;
living.hurt(ModDamageTypes.causeVehicleExplosionDamage(this.level().registryAccess(), null, tempAttacker), Integer.MAX_VALUE);
living.invulnerableTime = 0;
living.hurt(ModDamageTypes.causeVehicleExplosionDamage(this.level().registryAccess(), null, tempAttacker), Integer.MAX_VALUE);
}
}
this.discard();
}
protected void clampRotation(Entity entity) {
float f = Mth.wrapDegrees(entity.getXRot());
float f1 = Mth.clamp(f, -30F, 4F);
entity.xRotO += f1 - f;
entity.setXRot(entity.getXRot() + f1 - f);
}
@Override
public void onPassengerTurned(Entity entity) {
this.clampRotation(entity);
}
// private PlayState firePredicate(AnimationState<Yx100Entity> event) {
// if (this.entityData.get(FIRE_ANIM) > 1 && entityData.get(WEAPON_TYPE) == 0) {
// return event.setAndContinue(RawAnimation.begin().thenPlay("animation.lav.fire"));
// }
//
// if (this.entityData.get(FIRE_ANIM) > 0 && entityData.get(WEAPON_TYPE) == 1) {
// return event.setAndContinue(RawAnimation.begin().thenPlay("animation.lav.fire2"));
// }
//
// 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));
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
@Override
public int getMaxEnergy() {
return MAX_ENERGY;
}
@Override
public float getMaxHealth() {
return MAX_HEALTH;
}
@Override
public boolean isDriver(Player player) {
return player == this.getFirstPassenger();
}
@Override
public int mainGunRpm() {
return 15;
}
@Override
public boolean canShoot(Player player) {
if (entityData.get(WEAPON_TYPE) == 0) {
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(AMMO) > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) && !cannotFireCoax;
}
return false;
}
@Override
public int getAmmoCount(Player player) {
return this.entityData.get(AMMO);
}
@Override
public boolean banHand(Player player) {
return true;
}
@Override
public boolean hidePassenger() {
return true;
}
@Override
public int zoomFov() {
return 3;
}
@Override
public void changeWeapon(int scroll) {
var type = (entityData.get(WEAPON_TYPE) + scroll + 3) % 3;
entityData.set(WEAPON_TYPE, type);
var sound = switch (type) {
case 0, 2 -> ModSounds.INTO_MISSILE.get();
case 1 -> ModSounds.INTO_CANNON.get();
default -> throw new IllegalStateException("Unexpected type: " + type);
};
this.level().playSound(null, this, sound, this.getSoundSource(), 1, 1);
}
@Override
public int getWeaponType() {
return entityData.get(WEAPON_TYPE);
}
@Override
public ResourceLocation getVehicleIcon() {
return ModUtils.loc("textures/vehicle_icon/bmp2_icon.png");
}
}

View file

@ -0,0 +1,199 @@
package com.atsuishio.superbwarfare.entity.vehicle;
import com.atsuishio.superbwarfare.ModUtils;
import com.atsuishio.superbwarfare.init.ModEntities;
import com.atsuishio.superbwarfare.init.ModItems;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.Packet;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.util.Mth;
import net.minecraft.world.InteractionHand;
import net.minecraft.world.InteractionResult;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import net.minecraftforge.network.NetworkHooks;
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 Yx100GunEntity extends VehicleEntity implements GeoEntity, ICannonEntity {
public static final EntityDataAccessor<Integer> AMMO = SynchedEntityData.defineId(Yx100GunEntity.class, EntityDataSerializers.INT);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public Yx100GunEntity(PlayMessages.SpawnEntity packet, Level world) {
this(ModEntities.YX_100_GUN.get(), world);
}
public Yx100GunEntity(EntityType<Yx100GunEntity> type, Level world) {
super(type, world);
this.noPhysics = true;
}
@Override
protected void defineSynchedData() {
super.defineSynchedData();
this.entityData.define(AMMO, 0);
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
}
@Override
protected void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
}
@Override
public InteractionResult interact(Player player, InteractionHand hand) {
return super.interact(player, hand);
}
@Override
public Packet<ClientGamePacketListener> getAddEntityPacket() {
return NetworkHooks.getEntitySpawningPacket(this);
}
@Override
public double getPassengersRidingOffset() {
return super.getPassengersRidingOffset() - 1;
}
@Override
public boolean isPushable() {
return false;
}
@Override
public boolean isPickable() {
return true;
}
@Override
public void baseTick() {
// if (!(this.getVehicle() instanceof Yx100Entity yx100)) {
// this.discard();
// }
if (this.level() instanceof ServerLevel) {
this.handleAmmo();
}
super.baseTick();
}
private void handleAmmo() {
if (!(this.getFirstPassenger() instanceof Player player)) return;
if (this.getVehicle() instanceof Yx100Entity yx100) {
int ammoCount = yx100.getItemStacks().stream().filter(stack -> {
if (stack.is(ModItems.AMMO_BOX.get())) {
return stack.getOrCreateTag().getInt("HeavyAmmo") > 0;
}
return false;
}).mapToInt(stack -> stack.getOrCreateTag().getInt("HeavyAmmo")).sum()
+ yx100.getItemStacks().stream().filter(stack -> stack.is(ModItems.HEAVY_AMMO.get())).mapToInt(ItemStack::getCount).sum();
this.entityData.set(AMMO, ammoCount);
}
}
@Override
public void vehicleShoot(Player player) {
}
@Override
public void travel() {
Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0);
float diffY = 0;
float diffX = 0;
if (passenger != null) {
diffY = Mth.wrapDegrees(passenger.getYHeadRot() - this.getYRot());
diffX = Mth.wrapDegrees(passenger.getXRot() - this.getXRot());
}
this.setYRot(this.getYRot() + Mth.clamp(0.5f * diffY, -25f, 25f));
this.setXRot(Mth.clamp(this.getXRot() + Mth.clamp(0.5f * diffX, -25f, 25f), -65, 7f));
}
protected void clampRotation(Entity entity) {
float f = Mth.wrapDegrees(entity.getXRot());
float f1 = Mth.clamp(f, -85.0F, 16.3F);
entity.xRotO += f1 - f;
entity.setXRot(entity.getXRot() + f1 - f);
}
@Override
public void onPassengerTurned(Entity entity) {
this.clampRotation(entity);
}
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) {
}
@Override
public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache;
}
@Override
public float getMaxHealth() {
if (this.getVehicle() instanceof VehicleEntity vehicle) {
return vehicle.getMaxHealth();
}
return 0;
}
@Override
public boolean isDriver(Player player) {
return player == this.getFirstPassenger();
}
@Override
public int mainGunRpm() {
return 600;
}
@Override
public boolean canShoot(Player player) {
return true;
}
@Override
public int getAmmoCount(Player player) {
return this.entityData.get(AMMO);
}
@Override
public boolean banHand(Player player) {
return true;
}
@Override
public boolean hidePassenger() {
return true;
}
@Override
public int zoomFov() {
return 3;
}
@Override
public ResourceLocation getVehicleIcon() {
return ModUtils.loc("textures/vehicle_icon/sherman_icon.png");
}
}

View file

@ -88,6 +88,10 @@ public class ModEntities {
EntityType.Builder.<WgMissileEntity>of(WgMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(WgMissileEntity::new).fireImmune().sized(0.5f, 0.5f));
public static final RegistryObject<EntityType<LaserTowerEntity>> LASER_TOWER = register("laser_tower",
EntityType.Builder.<LaserTowerEntity>of(LaserTowerEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(LaserTowerEntity::new).fireImmune().sized(0.9f, 1.65f));
public static final RegistryObject<EntityType<Yx100Entity>> YX_100 = register("yx_100",
EntityType.Builder.<Yx100Entity>of(Yx100Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(Yx100Entity::new).fireImmune().sized(6f, 3.5f));
public static final RegistryObject<EntityType<Yx100GunEntity>> YX_100_GUN = register("yx_100_gun",
EntityType.Builder.<Yx100GunEntity>of(Yx100GunEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(Yx100GunEntity::new).fireImmune().sized(0.9f, 0.65f));
private static <T extends Entity> RegistryObject<EntityType<T>> register(String name, EntityType.Builder<T> entityTypeBuilder) {
return REGISTRY.register(name, () -> entityTypeBuilder.build(name));

View file

@ -42,5 +42,7 @@ public class ModEntityRenderers {
event.registerEntityRenderer(ModEntities.BMP_2.get(), Bmp2Renderer::new);
event.registerEntityRenderer(ModEntities.WG_MISSILE.get(), WgMissileRenderer::new);
event.registerEntityRenderer(ModEntities.LASER_TOWER.get(), LaserTowerRenderer::new);
event.registerEntityRenderer(ModEntities.YX_100.get(), Yx100Renderer::new);
event.registerEntityRenderer(ModEntities.YX_100_GUN.get(), Yx100GunRenderer::new);
}
}

View file

@ -48,6 +48,7 @@ public class ContainerBlockItem extends BlockItem implements GeoItem {
() -> ContainerBlockItem.createInstance(ModEntities.AH_6.get()),
() -> ContainerBlockItem.createInstance(ModEntities.LAV_150.get(), true),
() -> ContainerBlockItem.createInstance(ModEntities.BMP_2.get(), true),
() -> ContainerBlockItem.createInstance(ModEntities.YX_100.get()),
() -> ContainerBlockItem.createInstance(ModEntities.WHEEL_CHAIR.get()),
() -> ContainerBlockItem.createInstance(ModEntities.TOM_6.get())
);

View file

@ -89,6 +89,19 @@ public abstract class CameraMixin {
return;
}
if (player.getVehicle() instanceof Yx100Entity yx100 && (Minecraft.getInstance().options.getCameraType() == CameraType.FIRST_PERSON || ClientEventHandler.zoomVehicle)) {
if (yx100.getFirstPassenger() == player) {
setRotation(-Mth.lerp(partialTicks, yx100.turretYRotO - yx100.yRotO, yx100.getTurretYRot() - yx100.getYRot()), Mth.lerp(partialTicks, yx100.turretXRotO - yx100.xRotO, yx100.getTurretXRot() - yx100.getXRot()));
setPosition(Mth.lerp(partialTicks, player.xo, player.getX()), Mth.lerp(partialTicks, player.yo + player.getEyeHeight(), player.getEyeY()), Mth.lerp(partialTicks, player.zo, player.getZ()));
info.cancel();
} else {
setRotation(Mth.lerp(partialTicks, player.yHeadRotO, player.getYHeadRot()), Mth.lerp(partialTicks, player.xRotO, player.getXRot()));
setPosition(Mth.lerp(partialTicks, player.xo, player.getX()) - 6 * player.getViewVector(partialTicks).x, Mth.lerp(partialTicks, player.yo + player.getEyeHeight() + 1, player.getEyeY() + 1) - 6 * player.getViewVector(partialTicks).y, Mth.lerp(partialTicks, player.zo, player.getZ()) - 6 * player.getViewVector(partialTicks).z);
info.cancel();
}
return;
}
if (stack.is(ModItems.MONITOR.get()) && stack.getOrCreateTag().getBoolean("Using") && stack.getOrCreateTag().getBoolean("Linked")) {
DroneEntity drone = EntityFindUtil.findDrone(player.level(), stack.getOrCreateTag().getString("LinkedDrone"));
if (drone != null) {
@ -164,6 +177,10 @@ public abstract class CameraMixin {
if (thirdPerson && entity.getVehicle() instanceof Bmp2Entity && !ClientEventHandler.zoomVehicle) {
move(-getMaxZoom(3), 1, 0.0);
}
if (thirdPerson && entity.getVehicle() instanceof Yx100Entity && !ClientEventHandler.zoomVehicle) {
move(-getMaxZoom(4), 1, 0.0);
}
}
@Shadow

View file

@ -59,6 +59,10 @@ public class MouseHandlerMixin {
return ClientEventHandler.zoomVehicle ? 0.22 : 0.27;
}
if (player.getVehicle() instanceof Yx100Entity) {
return ClientEventHandler.zoomVehicle ? 0.18 : 0.23;
}
if (player.getVehicle() instanceof Ah6Entity ah6Entity && !ah6Entity.onGround() && ah6Entity.getFirstPassenger() == player) {
return 0.33;
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,422 @@
{
"format_version": "1.12.0",
"minecraft:geometry": [
{
"description": {
"identifier": "geometry.unknown",
"texture_width": 1024,
"texture_height": 1024,
"visible_bounds_width": 20,
"visible_bounds_height": 15,
"visible_bounds_offset": [0, 0.5, 0]
},
"bones": [
{
"name": "root",
"pivot": [0, -0.5025, 0],
"cubes": [
{
"origin": [-5.15625, 1.02875, -7.03125],
"size": [10.3125, 2.8125, 10.3125],
"uv": {
"north": {"uv": [90, 279], "uv_size": [11, 3]},
"east": {"uv": [15, 567], "uv_size": [11, 3]},
"west": {"uv": [174, 572], "uv_size": [11, 3]},
"up": {"uv": [475, 347], "uv_size": [11, 11]},
"down": {"uv": [486, 375], "uv_size": [11, -11]}
}
},
{
"origin": [1.60041, 1.33665, -7.03125],
"size": [5.625, 2.8125, 15],
"pivot": [5.81916, 1.8054, -1.875],
"rotation": [0, 0, 45],
"uv": {
"north": {"uv": [184, 634], "uv_size": [6, 3]},
"east": {"uv": [608, 466], "uv_size": [16, 3]},
"south": {"uv": [190, 634], "uv_size": [6, 3]},
"west": {"uv": [608, 511], "uv_size": [16, 3]},
"up": {"uv": [336, 558], "uv_size": [6, 16]},
"down": {"uv": [342, 574], "uv_size": [6, -16]}
}
},
{
"origin": [8.18193, 3.89359, -7.5],
"size": [3.75, 0, 2.8125],
"pivot": [7.24443, 3.89359, -5.625],
"rotation": [0, -90, 45],
"uv": {
"up": {"uv": [37, 759.5], "uv_size": [266, 192.5]}
}
},
{
"origin": [5.83818, 3.89359, -0.9375],
"size": [7.03125, 0, 1.40625],
"pivot": [7.24443, 3.89359, 0.46875],
"rotation": [0, -90, 45],
"uv": {
"up": {"uv": [14.5, 956.5], "uv_size": [303, 52.5]}
}
},
{
"origin": [-9.45087, 3.56213, -4.21875],
"size": [3.75, 0, 2.8125],
"pivot": [-7.57587, 3.56213, -2.8125],
"rotation": [0, -90, 135],
"uv": {
"up": {"uv": [303, 759.5], "uv_size": [-266, 192.5]}
}
},
{
"origin": [-11.25724, 3.3964, 1.875],
"size": [7.03125, 0, 1.40625],
"pivot": [-7.74161, 3.3964, 2.57812],
"rotation": [0, -90, 135],
"uv": {
"up": {"uv": [317.5, 956.5], "uv_size": [-303, 52.5]}
}
},
{
"origin": [3.65275, 5.8766, -8.65441],
"size": [3.75, 1.875, 10.3125],
"pivot": [5.52775, 4.9391, -3.49816],
"rotation": [23.85865, 18.74724, -36.00521],
"uv": {
"west": {"uv": [630, 84], "uv_size": [11, 2]}
}
},
{
"origin": [-7.40276, 5.8766, -8.65441],
"size": [3.75, 1.875, 10.3125],
"pivot": [-5.52776, 4.9391, -3.49816],
"rotation": [23.85865, -18.74724, 36.00521],
"uv": {
"east": {"uv": [630, 86], "uv_size": [11, 2]}
}
},
{
"origin": [-7.22541, 1.33665, -7.03125],
"size": [5.625, 2.8125, 15],
"pivot": [-5.81916, 1.8054, -1.875],
"rotation": [0, 0, -45],
"uv": {
"north": {"uv": [634, 526], "uv_size": [6, 3]},
"east": {"uv": [608, 514], "uv_size": [16, 3]},
"south": {"uv": [539, 634], "uv_size": [6, 3]},
"west": {"uv": [608, 564], "uv_size": [16, 3]},
"up": {"uv": [436, 558], "uv_size": [6, 16]},
"down": {"uv": [442, 574], "uv_size": [6, -16]}
}
},
{
"origin": [-6.3419, 0.90104, -11.14254],
"size": [1.93265, 2.30324, 4.0579],
"pivot": [-5.4044, 2.40436, -8.17609],
"rotation": [-32.73241, -24.4045, -32.73241],
"uv": {
"north": {"uv": [325, 649], "uv_size": [2, 2]},
"east": {"uv": [539, 641], "uv_size": [4, 2]},
"south": {"uv": [649, 328], "uv_size": [2, 2]},
"west": {"uv": [566, 641], "uv_size": [4, 2]},
"up": {"uv": [593, 641], "uv_size": [2, 4]},
"down": {"uv": [595, 645], "uv_size": [2, -4]}
}
},
{
"origin": [-5.15625, 0.38779, -8.63619],
"size": [2.8125, 3.00666, 4.0579],
"pivot": [-1.28906, 5.71625, -6.5625],
"rotation": [-40, 0, 0],
"uv": {
"north": {"uv": [468, 539], "uv_size": [3, 3]},
"east": {"uv": [638, 73], "uv_size": [4, 3]},
"south": {"uv": [290, 544], "uv_size": [3, 3]},
"west": {"uv": [638, 104], "uv_size": [4, 3]},
"up": {"uv": [12, 639], "uv_size": [3, 4]},
"down": {"uv": [15, 643], "uv_size": [3, -4]}
}
},
{
"origin": [-5.15625, 0.81049, -6.06571],
"size": [2.8125, 8.63166, 2.1829],
"pivot": [-1.28906, 6.13895, -3.99204],
"rotation": [-60, 0, 0],
"uv": {
"north": {"uv": [204, 572], "uv_size": [3, 9]},
"east": {"uv": [407, 631], "uv_size": [2, 9]},
"south": {"uv": [513, 573], "uv_size": [3, 9]},
"west": {"uv": [428, 631], "uv_size": [2, 9]},
"down": {"uv": [380, 598], "uv_size": [3, -2]}
}
},
{
"origin": [2.34375, 0.38779, -8.63619],
"size": [2.8125, 3.00666, 4.0579],
"pivot": [1.28906, 5.71625, -6.5625],
"rotation": [-40, 0, 0],
"uv": {
"north": {"uv": [575, 78], "uv_size": [3, 3]},
"east": {"uv": [638, 151], "uv_size": [4, 3]},
"south": {"uv": [178, 595], "uv_size": [3, 3]},
"west": {"uv": [638, 240], "uv_size": [4, 3]},
"up": {"uv": [18, 639], "uv_size": [3, 4]},
"down": {"uv": [21, 643], "uv_size": [3, -4]}
}
},
{
"origin": [4.40926, 0.90104, -11.14254],
"size": [1.93265, 2.30324, 4.0579],
"pivot": [5.40441, 2.40436, -8.17609],
"rotation": [-32.73241, 24.4045, 32.73241],
"uv": {
"north": {"uv": [329, 649], "uv_size": [2, 2]},
"east": {"uv": [641, 582], "uv_size": [4, 2]},
"south": {"uv": [331, 649], "uv_size": [2, 2]},
"west": {"uv": [641, 595], "uv_size": [4, 2]},
"up": {"uv": [597, 641], "uv_size": [2, 4]},
"down": {"uv": [599, 645], "uv_size": [2, -4]}
}
},
{
"origin": [2.34375, 0.81049, -6.06571],
"size": [2.8125, 8.63166, 2.1829],
"pivot": [1.28906, 6.13895, -3.99204],
"rotation": [-60, 0, 0],
"uv": {
"north": {"uv": [444, 574], "uv_size": [3, 9]},
"east": {"uv": [557, 631], "uv_size": [2, 9]},
"south": {"uv": [499, 626], "uv_size": [3, 9]},
"west": {"uv": [116, 632], "uv_size": [2, 9]},
"down": {"uv": [630, 463], "uv_size": [3, -2]}
}
},
{
"origin": [-5.15594, 0.01756, -2.16791],
"size": [10.31188, 9.56854, 10.61978],
"inflate": 0.005,
"uv": {
"north": {"uv": [556, 44], "uv_size": [11, 10]},
"east": {"uv": [412, 556], "uv_size": [11, 10]},
"south": {"uv": [15, 557], "uv_size": [11, 10]},
"west": {"uv": [557, 17], "uv_size": [11, 10]},
"up": {"uv": [196, 553], "uv_size": [11, 11]},
"down": {"uv": [299, 564], "uv_size": [11, -11]}
}
},
{
"origin": [-5.15625, 3.11814, 5.52594],
"size": [10.3125, 6.76641, 6.76641],
"pivot": [0, 5.09998, 10.73215],
"rotation": [45, 0, 0],
"uv": {
"east": {"uv": [495, 604], "uv_size": [7, 7]},
"south": {"uv": [196, 582], "uv_size": [11, 7]},
"west": {"uv": [583, 606], "uv_size": [7, 7]},
"down": {"uv": [505, 590], "uv_size": [11, -7]}
}
},
{
"origin": [-4.21875, 5.71625, 4.21875],
"size": [7.5, 3.28125, 4.6875],
"uv": {
"east": {"uv": [566, 631], "uv_size": [5, 4]},
"west": {"uv": [571, 631], "uv_size": [5, 4]}
}
},
{
"origin": [2.34375, -0.93642, -7.52356],
"size": [2.34375, 4.6875, 8.4375],
"pivot": [1.28906, 5.71625, -6.5625],
"rotation": [45, 0, 0],
"uv": {
"north": {"uv": [41, 636], "uv_size": [3, 5]},
"east": {"uv": [33, 608], "uv_size": [9, 5]},
"south": {"uv": [636, 44], "uv_size": [3, 5]},
"west": {"uv": [550, 608], "uv_size": [9, 5]},
"up": {"uv": [30, 627], "uv_size": [3, 9]},
"down": {"uv": [63, 636], "uv_size": [3, -9]}
}
},
{
"origin": [-4.6875, -0.93642, -7.52356],
"size": [2.34375, 4.6875, 8.4375],
"pivot": [1.28906, 5.71625, -6.5625],
"rotation": [45, 0, 0],
"uv": {
"north": {"uv": [52, 636], "uv_size": [3, 5]},
"east": {"uv": [608, 568], "uv_size": [9, 5]},
"south": {"uv": [636, 58], "uv_size": [3, 5]},
"west": {"uv": [608, 573], "uv_size": [9, 5]},
"up": {"uv": [213, 627], "uv_size": [3, 9]},
"down": {"uv": [270, 636], "uv_size": [3, -9]}
}
}
]
},
{
"name": "barrel",
"parent": "root",
"pivot": [0.02781, 6.42016, -3.36644],
"cubes": [
{
"origin": [-2.29765, 3.72995, -12.65625],
"size": [4.6875, 4.6875, 17.8125],
"uv": {
"north": {"uv": [484, 628], "uv_size": [5, 5]},
"east": {"uv": [395, 211], "uv_size": [19, 5]},
"west": {"uv": [0, 404], "uv_size": [19, 5]},
"up": {"uv": [233, 478], "uv_size": [5, 19]},
"down": {"uv": [554, 577], "uv_size": [5, -19]}
}
},
{
"origin": [-0.9375, 7.1225, -10.78125],
"size": [1.875, 1.875, 9.375],
"pivot": [0, 8.06, -6.09375],
"rotation": [-5, 0, 0],
"uv": {
"north": {"uv": [343, 649], "uv_size": [2, 2]},
"east": {"uv": [567, 318], "uv_size": [10, 2]},
"south": {"uv": [345, 649], "uv_size": [2, 2]},
"west": {"uv": [583, 108], "uv_size": [10, 2]},
"up": {"uv": [40, 570], "uv_size": [2, 10]},
"down": {"uv": [191, 585], "uv_size": [2, -10]}
}
},
{
"origin": [-1.71171, 7.47789, -25.69907],
"size": [3.51563, 0.46875, 13.125],
"pivot": [0.0461, 6.29919, -23.4037],
"rotation": [2.5, 0, 0],
"uv": {
"north": {"uv": [649, 332], "uv_size": [4, 1]},
"east": {"uv": [636, 213], "uv_size": [14, 1]},
"south": {"uv": [333, 649], "uv_size": [4, 1]},
"west": {"uv": [636, 229], "uv_size": [14, 1]},
"up": {"uv": [481, 440], "uv_size": [4, 14]},
"down": {"uv": [150, 616], "uv_size": [4, -14]}
}
},
{
"origin": [-9.23467, 4.1987, -11.15577],
"size": [3.31456, 3.75, 3.31456],
"pivot": [0.0461, 6.0737, -1.875],
"rotation": [0, -45, 0],
"uv": {
"north": {"uv": [613, 635], "uv_size": [4, 4]},
"east": {"uv": [617, 635], "uv_size": [4, 4]},
"up": {"uv": [635, 623], "uv_size": [4, 4]},
"down": {"uv": [625, 639], "uv_size": [4, -4]}
}
},
{
"origin": [-1.59452, 9.4632, -19.7191],
"size": [3.28125, 0.46875, 4.99219],
"pivot": [0.0461, 9.69757, -12.45347],
"rotation": [45, 0, 0],
"uv": {
"east": {"uv": [576, 648], "uv_size": [5, 1]},
"west": {"uv": [648, 576], "uv_size": [5, 1]}
}
},
{
"origin": [-1.59452, 5.97226, -18.60456],
"size": [3.28125, 0.46875, 5.32031],
"pivot": [0.0461, 6.20664, -15.71002],
"rotation": [135, 0, 0],
"uv": {
"east": {"uv": [643, 167], "uv_size": [6, 1]},
"west": {"uv": [643, 168], "uv_size": [6, 1]}
}
},
{
"origin": [-1.59452, 9.4632, -23.93784],
"size": [3.28125, 0.46875, 4.26562],
"pivot": [0.0461, 9.69757, -17.14097],
"rotation": [45, 0, 0],
"uv": {
"east": {"uv": [648, 569], "uv_size": [5, 1]},
"west": {"uv": [648, 570], "uv_size": [5, 1]}
}
},
{
"origin": [-1.59452, 5.97226, -22.58894],
"size": [3.28125, 0.46875, 4.38281],
"pivot": [0.0461, 6.20664, -20.39752],
"rotation": [135, 0, 0],
"uv": {
"east": {"uv": [648, 571], "uv_size": [5, 1]},
"west": {"uv": [648, 572], "uv_size": [5, 1]}
}
},
{
"origin": [-1.36015, 5.13414, -25.69907],
"size": [2.8125, 2.8125, 13.125],
"pivot": [0.0461, 6.29919, -23.4037],
"rotation": [2.5, 0, 0],
"uv": {
"north": {"uv": [503, 618], "uv_size": [3, 3]},
"east": {"uv": [257, 352], "uv_size": [14, 3]},
"south": {"uv": [571, 639], "uv_size": [3, 3]},
"west": {"uv": [400, 99], "uv_size": [14, 3]},
"down": {"uv": [290, 544], "uv_size": [3, -14]}
}
},
{
"origin": [-1.36015, 4.82044, -25.89447],
"size": [2.8125, 2.8125, 13.125],
"pivot": [0.0461, 6.29919, -23.4037],
"rotation": [-5, 0, 0],
"uv": {
"north": {"uv": [588, 639], "uv_size": [3, 3]},
"east": {"uv": [581, 488], "uv_size": [14, 3]},
"south": {"uv": [618, 639], "uv_size": [3, 3]},
"west": {"uv": [609, 244], "uv_size": [14, 3]},
"up": {"uv": [506, 607], "uv_size": [3, 14]}
}
},
{
"origin": [-1.8289, 4.82044, -25.89447],
"size": [3.75, 0.46875, 13.125],
"pivot": [0.0461, 6.29919, -23.4037],
"rotation": [-5, 0, 0],
"uv": {
"north": {"uv": [649, 333], "uv_size": [4, 1]},
"east": {"uv": [636, 230], "uv_size": [14, 1]},
"south": {"uv": [649, 334], "uv_size": [4, 1]},
"west": {"uv": [636, 231], "uv_size": [14, 1]},
"up": {"uv": [344, 602], "uv_size": [4, 14]},
"down": {"uv": [348, 616], "uv_size": [4, -14]}
}
},
{
"origin": [-1.8289, 5.12786, -30.9375],
"size": [1.875, 1.875, 5.625],
"pivot": [-0.36406, 6.11808, -31.40625],
"rotation": [0, 0, 135],
"uv": {
"east": {"uv": [639, 44], "uv_size": [6, 2]},
"south": {"uv": [538, 652], "uv_size": [1, 2]},
"west": {"uv": [639, 46], "uv_size": [6, 2]},
"up": {"uv": [103, 643], "uv_size": [1, 6]},
"down": {"uv": [104, 649], "uv_size": [1, -6]}
}
},
{
"origin": [-1.47734, 5.14798, -37.5],
"size": [2.8125, 2.8125, 6.5625],
"uv": {
"north": {"uv": [133, 650], "uv_size": [1, 3]},
"east": {"uv": [192, 631], "uv_size": [7, 3]},
"south": {"uv": [170, 650], "uv_size": [1, 3]},
"west": {"uv": [631, 194], "uv_size": [7, 3]},
"up": {"uv": [69, 642], "uv_size": [1, 7]},
"down": {"uv": [70, 649], "uv_size": [1, -7]}
}
}
]
}
]
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB