添加快艇实体
This commit is contained in:
parent
205d86c9af
commit
1b8e2c03fd
10 changed files with 3429 additions and 1 deletions
|
@ -0,0 +1,30 @@
|
|||
package com.atsuishio.superbwarfare.client.model.entity;
|
||||
|
||||
import com.atsuishio.superbwarfare.ModUtils;
|
||||
import com.atsuishio.superbwarfare.entity.SpeedboatEntity;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import software.bernie.geckolib.core.animation.AnimationState;
|
||||
import software.bernie.geckolib.model.GeoModel;
|
||||
|
||||
public class SpeedboatModel extends GeoModel<SpeedboatEntity> {
|
||||
|
||||
@Override
|
||||
public ResourceLocation getAnimationResource(SpeedboatEntity entity) {
|
||||
return null;
|
||||
// return ModUtils.loc("animations/mk_42.animation.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getModelResource(SpeedboatEntity entity) {
|
||||
return ModUtils.loc("geo/speedboat.geo.json");
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getTextureResource(SpeedboatEntity entity) {
|
||||
return ModUtils.loc("textures/entity/speedboat.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCustomAnimations(SpeedboatEntity animatable, long instanceId, AnimationState<SpeedboatEntity> animationState) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.atsuishio.superbwarfare.client.renderer.entity;
|
||||
|
||||
import com.atsuishio.superbwarfare.client.model.entity.SpeedboatModel;
|
||||
import com.atsuishio.superbwarfare.entity.SpeedboatEntity;
|
||||
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 SpeedboatRenderer extends GeoEntityRenderer<SpeedboatEntity> {
|
||||
|
||||
public SpeedboatRenderer(EntityRendererProvider.Context renderManager) {
|
||||
super(renderManager, new SpeedboatModel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public RenderType getRenderType(SpeedboatEntity animatable, ResourceLocation texture, MultiBufferSource bufferSource, float partialTick) {
|
||||
return RenderType.entityTranslucent(getTextureLocation(animatable));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preRender(PoseStack poseStack, SpeedboatEntity 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(SpeedboatEntity 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
|
||||
protected float getDeathMaxRotation(SpeedboatEntity entityLivingBaseIn) {
|
||||
return 0.0F;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
package com.atsuishio.superbwarfare.entity;
|
||||
public interface IVehicleEntity {
|
||||
}
|
|
@ -0,0 +1,247 @@
|
|||
package com.atsuishio.superbwarfare.entity;
|
||||
|
||||
import com.atsuishio.superbwarfare.config.server.CannonConfig;
|
||||
import com.atsuishio.superbwarfare.config.server.ExplosionDestroyConfig;
|
||||
import com.atsuishio.superbwarfare.init.*;
|
||||
import com.atsuishio.superbwarfare.item.ContainerBlockItem;
|
||||
import com.atsuishio.superbwarfare.tools.CustomExplosion;
|
||||
import com.atsuishio.superbwarfare.tools.ParticleTool;
|
||||
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.server.level.ServerLevel;
|
||||
import net.minecraft.sounds.SoundSource;
|
||||
import net.minecraft.util.Mth;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.InteractionResult;
|
||||
import net.minecraft.world.damagesource.DamageSource;
|
||||
import net.minecraft.world.damagesource.DamageTypes;
|
||||
import net.minecraft.world.entity.AreaEffectCloud;
|
||||
import net.minecraft.world.entity.Entity;
|
||||
import net.minecraft.world.entity.EntityType;
|
||||
import net.minecraft.world.entity.MoverType;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.entity.projectile.ThrownPotion;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.level.Explosion;
|
||||
import net.minecraft.world.level.Level;
|
||||
import net.minecraftforge.fluids.FluidType;
|
||||
import net.minecraftforge.network.NetworkHooks;
|
||||
import net.minecraftforge.network.PlayMessages;
|
||||
import net.minecraftforge.registries.ForgeRegistries;
|
||||
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 SpeedboatEntity extends Entity implements GeoEntity, IChargeEntity, IVehicleEntity{
|
||||
public static final EntityDataAccessor<Float> HEALTH = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
|
||||
public static final EntityDataAccessor<Float> ENERGY = SynchedEntityData.defineId(SpeedboatEntity.class, EntityDataSerializers.FLOAT);
|
||||
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
|
||||
public static final float MAX_HEALTH = CannonConfig.MK42_HP.get();
|
||||
|
||||
|
||||
public SpeedboatEntity(PlayMessages.SpawnEntity packet, Level world) {
|
||||
this(ModEntities.SPEEDBOAT.get(), world);
|
||||
}
|
||||
|
||||
public SpeedboatEntity(EntityType<SpeedboatEntity> type, Level world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void defineSynchedData() {
|
||||
this.entityData.define(HEALTH, MAX_HEALTH);
|
||||
this.entityData.define(ENERGY, 0f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAdditionalSaveData(CompoundTag compound) {
|
||||
compound.putFloat("Health", this.entityData.get(HEALTH));
|
||||
compound.putFloat("Energy", this.entityData.get(ENERGY));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void readAdditionalSaveData(CompoundTag compound) {
|
||||
this.entityData.set(ENERGY, compound.getFloat("Energy"));
|
||||
if (compound.contains("Health")) {
|
||||
this.entityData.set(HEALTH, compound.getFloat("Health"));
|
||||
} else {
|
||||
this.entityData.set(HEALTH, MAX_HEALTH);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canBeCollidedWith() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean canCollideWith(Entity pEntity) {
|
||||
return (pEntity.canBeCollidedWith() || pEntity.isPushable()) && !this.isPassengerOfSameVehicle(pEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Packet<ClientGamePacketListener> getAddEntityPacket() {
|
||||
return NetworkHooks.getEntitySpawningPacket(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getPassengersRidingOffset() {
|
||||
return super.getPassengersRidingOffset() - 1.3;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hurt(DamageSource source, float amount) {
|
||||
if (this.level() instanceof ServerLevel serverLevel) {
|
||||
ParticleTool.sendParticle(serverLevel, ModParticleTypes.FIRE_STAR.get(), this.getX(), this.getY() + 2.5, this.getZ(), 4, 0.2, 0.2, 0.2, 0.2, false);
|
||||
}
|
||||
|
||||
if (source.getDirectEntity() instanceof ThrownPotion || source.getDirectEntity() instanceof AreaEffectCloud)
|
||||
return false;
|
||||
if (source.is(DamageTypes.FALL))
|
||||
return false;
|
||||
if (source.is(DamageTypes.CACTUS))
|
||||
return false;
|
||||
if (source.is(DamageTypes.DROWN))
|
||||
return false;
|
||||
if (source.is(DamageTypes.LIGHTNING_BOLT))
|
||||
return false;
|
||||
if (source.is(DamageTypes.FALLING_ANVIL))
|
||||
return false;
|
||||
if (source.is(DamageTypes.DRAGON_BREATH))
|
||||
return false;
|
||||
if (source.is(DamageTypes.WITHER))
|
||||
return false;
|
||||
if (source.is(DamageTypes.WITHER_SKULL))
|
||||
return false;
|
||||
if (source.is(ModDamageTypes.PROJECTILE_BOOM)) {
|
||||
amount *= 0.5f;
|
||||
}
|
||||
if (source.is(ModDamageTypes.CANNON_FIRE)) {
|
||||
amount *= 1.4f;
|
||||
}
|
||||
if (source.is(ModDamageTypes.GUN_FIRE_ABSOLUTE)) {
|
||||
amount *= 1.6f;
|
||||
}
|
||||
|
||||
this.level().playSound(null, this.getOnPos(), ModSounds.HIT.get(), SoundSource.PLAYERS, 1, 1);
|
||||
this.entityData.set(HEALTH, this.entityData.get(HEALTH) - 0.75f * amount);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isPickable() {
|
||||
return !this.isRemoved();
|
||||
}
|
||||
|
||||
@Override
|
||||
public InteractionResult interact(Player player, InteractionHand hand) {
|
||||
if (player.isShiftKeyDown()) {
|
||||
if (player.getMainHandItem().is(ModItems.CROWBAR.get()) && this.getFirstPassenger() == null) {
|
||||
ItemStack stack = ContainerBlockItem.createInstance(this);
|
||||
if (!player.addItem(stack)) {
|
||||
player.drop(stack, false);
|
||||
}
|
||||
this.discard();
|
||||
return InteractionResult.sidedSuccess(this.level().isClientSide());
|
||||
}
|
||||
return InteractionResult.PASS;
|
||||
} else {
|
||||
player.startRiding(this);
|
||||
return InteractionResult.sidedSuccess(this.level().isClientSide());
|
||||
}
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public Vec3 getDeltaMovement() {
|
||||
// return new Vec3(0, Math.min(super.getDeltaMovement().y, 0), 0);
|
||||
// }
|
||||
|
||||
public double getSubmergedHeight(Entity entity) {
|
||||
for (FluidType fluidType : ForgeRegistries.FLUID_TYPES.get().getValues()) {
|
||||
if (entity.level().getFluidState(entity.blockPosition()).getFluidType() == fluidType)
|
||||
return entity.getFluidTypeHeight(fluidType);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void baseTick() {
|
||||
super.baseTick();
|
||||
|
||||
|
||||
// if (this.getFirstPassenger() instanceof Player player) {
|
||||
// player.displayClientMessage(Component.literal("SubmergedHeight" + new java.text.DecimalFormat("##.##").format(getSubmergedHeight(this))), true);
|
||||
// }
|
||||
|
||||
this.move(MoverType.SELF, this.getDeltaMovement());
|
||||
double fluidFloat;
|
||||
|
||||
if (this.isInWater()) {
|
||||
fluidFloat = -0.025 + 0.05 * getSubmergedHeight(this);
|
||||
} else {
|
||||
fluidFloat = -0.04;
|
||||
}
|
||||
|
||||
this.setDeltaMovement(this.getDeltaMovement().add(0.0, fluidFloat, 0.0));
|
||||
this.setDeltaMovement(this.getDeltaMovement().multiply(1, 0.85, 1));
|
||||
|
||||
if (this.entityData.get(HEALTH) <= 0) {
|
||||
this.ejectPassengers();
|
||||
destroy();
|
||||
}
|
||||
this.refreshDimensions();
|
||||
}
|
||||
|
||||
private void destroy() {
|
||||
CustomExplosion explosion = new CustomExplosion(this.level(), this,
|
||||
ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this), 20f,
|
||||
this.getX(), this.getY(), this.getZ(), 4.5f, ExplosionDestroyConfig.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.spawnHugeExplosionParticles(this.level(), this.position());
|
||||
|
||||
this.discard();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
entity.setYBodyRot(this.getYRot());
|
||||
float f2 = Mth.wrapDegrees(entity.getYRot() - this.getYRot());
|
||||
float f3 = Mth.clamp(f2, -105.0F, 105.0F);
|
||||
entity.yRotO += f3 - f2;
|
||||
entity.setYRot(entity.getYRot() + f3 - f2);
|
||||
entity.setYHeadRot(entity.getYRot());
|
||||
}
|
||||
|
||||
@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 void charge(int amount) {
|
||||
this.entityData.set(ENERGY, Math.min(this.entityData.get(ENERGY) + amount, CannonConfig.ANNIHILATOR_MAX_ENERGY.get().floatValue()));
|
||||
}
|
||||
}
|
|
@ -31,7 +31,7 @@ public class ModEntities {
|
|||
public static final RegistryObject<EntityType<ClaymoreEntity>> CLAYMORE = register("claymore",
|
||||
EntityType.Builder.<ClaymoreEntity>of(ClaymoreEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).sized(0.5f, 0.5f));
|
||||
public static final RegistryObject<EntityType<Mk42Entity>> MK_42 = register("mk_42",
|
||||
EntityType.Builder.<Mk42Entity>of(Mk42Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(5124).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f));
|
||||
EntityType.Builder.<Mk42Entity>of(Mk42Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f));
|
||||
public static final RegistryObject<EntityType<Mle1934Entity>> MLE_1934 = register("mle_1934",
|
||||
EntityType.Builder.<Mle1934Entity>of(Mle1934Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(Mle1934Entity::new).fireImmune().sized(4.5f, 2.8f));
|
||||
public static final RegistryObject<EntityType<AnnihilatorEntity>> ANNIHILATOR = register("annihilator",
|
||||
|
@ -61,6 +61,8 @@ public class ModEntities {
|
|||
EntityType.Builder.<JavelinMissileEntity>of(JavelinMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(JavelinMissileEntity::new).sized(0.5f, 0.5f));
|
||||
public static final RegistryObject<EntityType<LaserEntity>> LASER = register("laser",
|
||||
EntityType.Builder.<LaserEntity>of(LaserEntity::new, MobCategory.MISC).sized(0.1f, 0.1f).fireImmune().setUpdateInterval(1));
|
||||
public static final RegistryObject<EntityType<SpeedboatEntity>> SPEEDBOAT = register("speedboat",
|
||||
EntityType.Builder.<SpeedboatEntity>of(SpeedboatEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(SpeedboatEntity::new).fireImmune().sized(3.3f, 2.5f));
|
||||
|
||||
private static <T extends Entity> RegistryObject<EntityType<T>> register(String name, EntityType.Builder<T> entityTypeBuilder) {
|
||||
return REGISTRY.register(name, () -> entityTypeBuilder.build(name));
|
||||
|
|
|
@ -29,5 +29,6 @@ public class ModEntityRenderers {
|
|||
event.registerEntityRenderer(ModEntities.JAVELIN_MISSILE.get(), JavelinMissileRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.LASER.get(), LaserEntityRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.ANNIHILATOR.get(), AnnihilatorRenderer::new);
|
||||
event.registerEntityRenderer(ModEntities.SPEEDBOAT.get(), SpeedboatRenderer::new);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -106,6 +106,7 @@ public class ModTabs {
|
|||
output.accept(ContainerBlockItem.createMk42Instance());
|
||||
output.accept(ContainerBlockItem.createMle1934Instance());
|
||||
output.accept(ContainerBlockItem.createAnnihilatorInstance());
|
||||
output.accept(ContainerBlockItem.createSpeedboatInstance());
|
||||
} else {
|
||||
output.accept(registryObject.get());
|
||||
if (registryObject.get() == ModItems.ARMOR_PLATE.get()) {
|
||||
|
|
|
@ -101,4 +101,7 @@ public class ContainerBlockItem extends BlockItem implements GeoItem {
|
|||
public static ItemStack createAnnihilatorInstance() {
|
||||
return createInstance(ModEntities.ANNIHILATOR.get());
|
||||
}
|
||||
public static ItemStack createSpeedboatInstance() {
|
||||
return createInstance(ModEntities.SPEEDBOAT.get());
|
||||
}
|
||||
}
|
||||
|
|
3093
src/main/resources/assets/superbwarfare/geo/speedboat.geo.json
Normal file
3093
src/main/resources/assets/superbwarfare/geo/speedboat.geo.json
Normal file
File diff suppressed because it is too large
Load diff
Binary file not shown.
After Width: | Height: | Size: 5.1 KiB |
Loading…
Add table
Reference in a new issue