重做阔剑地雷

This commit is contained in:
17146 2024-08-25 01:33:20 +08:00
parent 15f2319ea6
commit 21d28f41c1
4 changed files with 226 additions and 82 deletions

View file

@ -45,4 +45,9 @@ public class ClaymoreRenderer extends GeoEntityRenderer<ClaymoreEntity> {
protected float getDeathMaxRotation(ClaymoreEntity entityLivingBaseIn) { protected float getDeathMaxRotation(ClaymoreEntity entityLivingBaseIn) {
return 0.0F; return 0.0F;
} }
@Override
public boolean shouldShowName(ClaymoreEntity animatable) {
return false;
}
} }

View file

@ -6,111 +6,195 @@ import net.mcreator.superbwarfare.init.ModEntities;
import net.mcreator.superbwarfare.init.ModItems; import net.mcreator.superbwarfare.init.ModItems;
import net.mcreator.superbwarfare.tools.CustomExplosion; import net.mcreator.superbwarfare.tools.CustomExplosion;
import net.mcreator.superbwarfare.tools.ParticleTool; import net.mcreator.superbwarfare.tools.ParticleTool;
import net.minecraft.core.Direction; import net.minecraft.core.NonNullList;
import net.minecraft.network.protocol.Packet; import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.protocol.game.ClientGamePacketListener;
import net.minecraft.network.syncher.EntityDataAccessor; import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers; import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData; import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.server.level.ServerLevel;
import net.minecraft.server.players.OldUsersConverter;
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.*; import net.minecraft.world.entity.*;
import net.minecraft.world.entity.ai.attributes.AttributeSupplier;
import net.minecraft.world.entity.ai.attributes.Attributes;
import net.minecraft.world.entity.player.Player; import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.ThrowableItemProjectile; import net.minecraft.world.entity.projectile.ThrownPotion;
import net.minecraft.world.item.Item; import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Explosion; import net.minecraft.world.level.Explosion;
import net.minecraft.world.level.Level; import net.minecraft.world.level.Level;
import net.minecraft.world.phys.AABB; import net.minecraft.world.phys.AABB;
import net.minecraft.world.phys.BlockHitResult;
import net.minecraft.world.phys.HitResult;
import net.minecraft.world.phys.Vec3; import net.minecraft.world.phys.Vec3;
import net.minecraftforge.network.NetworkHooks; import net.minecraftforge.items.ItemHandlerHelper;
import net.minecraftforge.network.PlayMessages;
import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.animatable.GeoEntity;
import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache;
import software.bernie.geckolib.core.animation.AnimatableManager; 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 software.bernie.geckolib.util.GeckoLibUtil;
import javax.annotation.Nullable;
import java.util.Comparator; import java.util.Comparator;
import java.util.Optional;
import java.util.UUID;
public class ClaymoreEntity extends ThrowableItemProjectile implements GeoEntity, AnimatedEntity { public class ClaymoreEntity extends LivingEntity implements GeoEntity, AnimatedEntity, OwnableEntity {
public static final EntityDataAccessor<String> ANIMATION = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor<String> ANIMATION = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.STRING);
public static final EntityDataAccessor<Float> ROT_Y = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.FLOAT); protected static final EntityDataAccessor<Optional<UUID>> OWNER_UUID = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.OPTIONAL_UUID);
private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this);
public String animationProcedure = "empty"; public String animationProcedure = "empty";
public ClaymoreEntity(EntityType<? extends ClaymoreEntity> type, Level world) { public ClaymoreEntity(EntityType<ClaymoreEntity> type, Level world) {
super(type, world); super(type, world);
} }
public ClaymoreEntity(EntityType<? extends ClaymoreEntity> type, LivingEntity entity, Level world) { public ClaymoreEntity(LivingEntity owner, Level level) {
super(type, entity, world); super(ModEntities.CLAYMORE.get(), level);
} this.setOwnerUUID(owner.getUUID());
public ClaymoreEntity(LivingEntity entity, Level level) {
super(ModEntities.CLAYMORE.get(), entity, level);
}
public ClaymoreEntity(PlayMessages.SpawnEntity spawnEntity, Level level) {
this(ModEntities.CLAYMORE.get(), level);
} }
@Override @Override
protected void defineSynchedData() { protected void defineSynchedData() {
this.entityData.define(ROT_Y, 0f); super.defineSynchedData();
} this.entityData.define(ANIMATION, "undefined");
this.entityData.define(OWNER_UUID, Optional.empty());
public void setRotY(float rotY) {
this.entityData.set(ROT_Y, rotY);
} }
@Override @Override
public Packet<ClientGamePacketListener> getAddEntityPacket() { public boolean isCustomNameVisible() {
return NetworkHooks.getEntitySpawningPacket(this); return false;
} }
@Override @Override
protected Item getDefaultItem() { public MobType getMobType() {
return ModItems.CLAYMORE_MINE.get(); return super.getMobType();
} }
@Override @Override
public boolean shouldRenderAtSqrDistance(double pDistance) { public Iterable<ItemStack> getArmorSlots() {
return true; return NonNullList.withSize(1, ItemStack.EMPTY);
} }
@Override @Override
protected void onHit(HitResult result) { public ItemStack getItemBySlot(EquipmentSlot pSlot) {
switch (result.getType()) { return ItemStack.EMPTY;
case BLOCK: }
BlockHitResult blockResult = (BlockHitResult) result;
this.bounce(blockResult.getDirection()); @Override
break; public void setItemSlot(EquipmentSlot pSlot, ItemStack pStack) {
case ENTITY:
this.bounce(Direction.getNearest(this.getDeltaMovement().x(), this.getDeltaMovement().y(), this.getDeltaMovement().z()).getOpposite()); }
this.setDeltaMovement(this.getDeltaMovement().multiply(0.25, 1.0, 0.25));
break; @Override
default: public boolean hurt(DamageSource source, float amount) {
break; if (source.is(DamageTypes.IN_FIRE))
return 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.EXPLOSION))
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;
return super.hurt(source, amount);
}
@Override
public void die(DamageSource source) {
super.die(source);
if (level() instanceof ServerLevel) {
destroyExplode();
this.discard();
} }
} }
private void bounce(Direction direction) { private void destroyExplode() {
switch (direction.getAxis()) { CustomExplosion explosion = new CustomExplosion(this.level(), this,
case X: ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), 15f,
this.setDeltaMovement(this.getDeltaMovement().multiply(-0.5, 0.75, 0.75)); this.getX(), this.getY(), this.getZ(), 7.5f, Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
break; explosion.explode();
case Y: net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion);
this.setDeltaMovement(this.getDeltaMovement().multiply(0.75, -0.01, 0.75)); explosion.finalizeExplosion(false);
if (this.getDeltaMovement().y() < this.getGravity()) {
this.setDeltaMovement(this.getDeltaMovement().multiply(1, 0, 1)); ParticleTool.spawnMediumExplosionParticles(this.level(), this.position());
} }
break;
case Z: public void setOwnerUUID(@Nullable UUID pUuid) {
this.setDeltaMovement(this.getDeltaMovement().multiply(0.75, 0.75, -0.5)); this.entityData.set(OWNER_UUID, Optional.ofNullable(pUuid));
break; }
@Nullable
public UUID getOwnerUUID() {
return this.entityData.get(OWNER_UUID).orElse(null);
}
public boolean isOwnedBy(LivingEntity pEntity) {
return pEntity == this.getOwner();
}
@Override
public void addAdditionalSaveData(CompoundTag compound) {
super.addAdditionalSaveData(compound);
if (this.getOwnerUUID() != null) {
compound.putUUID("Owner", this.getOwnerUUID());
} }
} }
@Override
public void readAdditionalSaveData(CompoundTag compound) {
super.readAdditionalSaveData(compound);
UUID uuid;
if (compound.hasUUID("Owner")) {
uuid = compound.getUUID("Owner");
} else {
String s = compound.getString("Owner");
assert this.getServer() != null;
uuid = OldUsersConverter.convertMobOwnerIfNecessary(this.getServer(), s);
}
if (uuid != null) {
try {
this.setOwnerUUID(uuid);
} catch (Throwable ignored) {
}
}
}
@Override
public InteractionResult interact(Player player, InteractionHand hand) {
if (this.isOwnedBy(player) && player.isShiftKeyDown()) {
if (!this.level().isClientSide()) {
this.discard();
}
if (!player.getAbilities().instabuild) {
ItemHandlerHelper.giveItemToPlayer(player, new ItemStack(ModItems.CLAYMORE_MINE.get()));
}
}
return InteractionResult.sidedSuccess(this.level().isClientSide());
}
@Override @Override
public void tick() { public void tick() {
super.tick(); super.tick();
@ -123,11 +207,15 @@ public class ClaymoreEntity extends ThrowableItemProjectile implements GeoEntity
if (!this.level().isClientSide()) this.discard(); if (!this.level().isClientSide()) this.discard();
} }
if (this.tickCount >= 20) { this.removeAllEffects();
this.clearFire();
if (this.tickCount >= 40) {
final Vec3 center = new Vec3(x + 1.5 * this.getLookAngle().x, y + 1.5 * this.getLookAngle().y, z + 1.5 * this.getLookAngle().z); final Vec3 center = new Vec3(x + 1.5 * this.getLookAngle().x, y + 1.5 * this.getLookAngle().y, z + 1.5 * this.getLookAngle().z);
for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(2.5 / 2d), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) { for (Entity target : level.getEntitiesOfClass(Entity.class, new AABB(center, center).inflate(2.5 / 2d), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(center))).toList()) {
var condition = this.getOwner() != target var condition = this.getOwner() != target
&& target instanceof LivingEntity && target instanceof LivingEntity
&& !(target instanceof ClaymoreEntity)
&& !(target instanceof TargetEntity) && !(target instanceof TargetEntity)
&& !(target instanceof Player player && (player.isCreative() || player.isSpectator())) && !(target instanceof Player player && (player.isCreative() || player.isSpectator()))
&& (!this.isAlliedTo(target) || target.getTeam() == null || target.getTeam().getName().equals("TDM")) && (!this.isAlliedTo(target) || target.getTeam() == null || target.getTeam().getName().equals("TDM"))
@ -153,27 +241,60 @@ public class ClaymoreEntity extends ThrowableItemProjectile implements GeoEntity
private void triggerExplode(Entity target) { private void triggerExplode(Entity target) {
CustomExplosion explosion = new CustomExplosion(this.level(), this, CustomExplosion explosion = new CustomExplosion(this.level(), this,
ModDamageTypes.causeMineDamage(this.level().registryAccess(), this.getOwner()), 80f, ModDamageTypes.causeMineDamage(this.level().registryAccess(), this.getOwner()), 40f,
target.getX(), target.getY(), target.getZ(), 6f, Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); target.getX(), target.getY(), target.getZ(), 4f, Explosion.BlockInteraction.KEEP).setDamageMultiplier(1);
explosion.explode(); explosion.explode();
net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion);
explosion.finalizeExplosion(false); explosion.finalizeExplosion(false);
} }
@Override
protected void updateRotation() {
this.setXRot(0);
this.setYRot(this.entityData.get(ROT_Y));
}
@Override @Override
public EntityDimensions getDimensions(Pose p_33597_) { public EntityDimensions getDimensions(Pose p_33597_) {
return super.getDimensions(p_33597_).scale((float) 0.5); return super.getDimensions(p_33597_).scale((float) 0.5);
} }
@Override @Override
protected float getGravity() { public boolean isPushable() {
return 0.07F; return false;
}
@Override
public HumanoidArm getMainArm() {
return HumanoidArm.RIGHT;
}
@Override
public void aiStep() {
super.aiStep();
this.updateSwingTime();
}
private PlayState movementPredicate(software.bernie.geckolib.core.animation.AnimationState<ClaymoreEntity> event) {
if (this.animationProcedure.equals("empty")) {
return event.setAndContinue(RawAnimation.begin().thenLoop("animation.claymore.idle"));
}
return PlayState.STOP;
}
private PlayState procedurePredicate(AnimationState<ClaymoreEntity> event) {
if (!animationProcedure.equals("empty") && event.getController().getAnimationState() == AnimationController.State.STOPPED) {
event.getController().setAnimation(RawAnimation.begin().thenPlay(this.animationProcedure));
if (event.getController().getAnimationState() == AnimationController.State.STOPPED) {
this.animationProcedure = "empty";
event.getController().forceAnimationReset();
}
} else if (animationProcedure.equals("empty")) {
return PlayState.STOP;
}
return PlayState.CONTINUE;
}
@Override
protected void tickDeath() {
++this.deathTime;
if (this.deathTime == 1) {
this.remove(ClaymoreEntity.RemovalReason.KILLED);
}
} }
public String getSyncedAnimation() { public String getSyncedAnimation() {
@ -191,10 +312,20 @@ public class ClaymoreEntity extends ThrowableItemProjectile implements GeoEntity
@Override @Override
public void registerControllers(AnimatableManager.ControllerRegistrar data) { public void registerControllers(AnimatableManager.ControllerRegistrar data) {
data.add(new AnimationController<>(this, "movement", 4, this::movementPredicate));
data.add(new AnimationController<>(this, "procedure", 4, this::procedurePredicate));
} }
@Override @Override
public AnimatableInstanceCache getAnimatableInstanceCache() { public AnimatableInstanceCache getAnimatableInstanceCache() {
return this.cache; return this.cache;
} }
}
public static AttributeSupplier.Builder createAttributes() {
return Mob.createMobAttributes().add(Attributes.MOVEMENT_SPEED, 0)
.add(Attributes.MAX_HEALTH, 5)
.add(Attributes.FOLLOW_RANGE, 64)
.add(Attributes.ATTACK_DAMAGE, 0)
.add(Attributes.KNOCKBACK_RESISTANCE, 10);
}
}

View file

@ -25,7 +25,7 @@ public class ModEntities {
EntityType.Builder.<SenpaiEntity>of(SenpaiEntity::new, MobCategory.MONSTER).setShouldReceiveVelocityUpdates(true).setTrackingRange(1024).setUpdateInterval(3).setCustomClientFactory(SenpaiEntity::new) EntityType.Builder.<SenpaiEntity>of(SenpaiEntity::new, MobCategory.MONSTER).setShouldReceiveVelocityUpdates(true).setTrackingRange(1024).setUpdateInterval(3).setCustomClientFactory(SenpaiEntity::new)
.sized(0.6f, 2f)); .sized(0.6f, 2f));
public static final RegistryObject<EntityType<ClaymoreEntity>> CLAYMORE = register("claymore", public static final RegistryObject<EntityType<ClaymoreEntity>> CLAYMORE = register("claymore",
EntityType.Builder.<ClaymoreEntity>of(ClaymoreEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(ClaymoreEntity::new).sized(0.5f, 0.5f)); 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", public static final RegistryObject<EntityType<Mk42Entity>> MK_42 = register("mk_42",
EntityType.Builder.<Mk42Entity>of(Mk42Entity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(5124).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f)); EntityType.Builder.<Mk42Entity>of(Mk42Entity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(5124).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f));
public static final RegistryObject<EntityType<Mle1934Entity>> MLE_1934 = register("mle_1934", public static final RegistryObject<EntityType<Mle1934Entity>> MLE_1934 = register("mle_1934",
@ -55,8 +55,8 @@ public class ModEntities {
EntityType.Builder.<RgoGrenadeEntity>of(RgoGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(RgoGrenadeEntity::new).sized(0.3f, 0.3f)); EntityType.Builder.<RgoGrenadeEntity>of(RgoGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(RgoGrenadeEntity::new).sized(0.3f, 0.3f));
private static <T extends Entity> RegistryObject<EntityType<T>> register(String registryname, EntityType.Builder<T> entityTypeBuilder) { private static <T extends Entity> RegistryObject<EntityType<T>> register(String name, EntityType.Builder<T> entityTypeBuilder) {
return REGISTRY.register(registryname, () -> entityTypeBuilder.build(registryname)); return REGISTRY.register(name, () -> entityTypeBuilder.build(name));
} }
@SubscribeEvent @SubscribeEvent
@ -72,5 +72,6 @@ public class ModEntities {
event.put(MK_42.get(), Mk42Entity.createAttributes().build()); event.put(MK_42.get(), Mk42Entity.createAttributes().build());
event.put(DRONE.get(), DroneEntity.createAttributes().build()); event.put(DRONE.get(), DroneEntity.createAttributes().build());
event.put(MLE_1934.get(), Mle1934Entity.createAttributes().build()); event.put(MLE_1934.get(), Mle1934Entity.createAttributes().build());
event.put(CLAYMORE.get(), ClaymoreEntity.createAttributes().build());
} }
} }

View file

@ -14,17 +14,24 @@ public class ClaymoreMine extends Item {
} }
@Override @Override
public InteractionResultHolder<ItemStack> use(Level world, Player player, InteractionHand hand) { public InteractionResultHolder<ItemStack> use(Level level, Player player, InteractionHand hand) {
ItemStack stack = player.getItemInHand(hand); ItemStack stack = player.getItemInHand(hand);
ClaymoreEntity claymore = new ClaymoreEntity(player, world); if (!level.isClientSide) {
claymore.setPos(player.getX(), player.getEyeY() - 0.3, player.getZ()); ClaymoreEntity entity = new ClaymoreEntity(player, level);
claymore.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, 0.2f,0); entity.moveTo(player.getX(), player.getY() + 1.1, player.getZ(), player.getYRot(), 0);
claymore.setRotY(player.getYRot()); entity.setYBodyRot(player.getYRot());
world.addFreshEntity(claymore); entity.setYHeadRot(player.getYRot());
entity.setDeltaMovement(0.5 * player.getLookAngle().x, 0.5 * player.getLookAngle().y, 0.5 * player.getLookAngle().z);
level.addFreshEntity(entity);
}
player.getCooldowns().addCooldown(this, 20); player.getCooldowns().addCooldown(this, 20);
stack.shrink(1);
if (!player.getAbilities().instabuild) {
stack.shrink(1);
}
return InteractionResultHolder.consume(stack); return InteractionResultHolder.consume(stack);
} }