diff --git a/src/main/java/net/mcreator/superbwarfare/client/renderer/entity/ClaymoreRenderer.java b/src/main/java/net/mcreator/superbwarfare/client/renderer/entity/ClaymoreRenderer.java index f61fbabcf..58a4593fb 100644 --- a/src/main/java/net/mcreator/superbwarfare/client/renderer/entity/ClaymoreRenderer.java +++ b/src/main/java/net/mcreator/superbwarfare/client/renderer/entity/ClaymoreRenderer.java @@ -45,4 +45,9 @@ public class ClaymoreRenderer extends GeoEntityRenderer { protected float getDeathMaxRotation(ClaymoreEntity entityLivingBaseIn) { return 0.0F; } + + @Override + public boolean shouldShowName(ClaymoreEntity animatable) { + return false; + } } diff --git a/src/main/java/net/mcreator/superbwarfare/entity/ClaymoreEntity.java b/src/main/java/net/mcreator/superbwarfare/entity/ClaymoreEntity.java index e8a1800ab..8fd92772c 100644 --- a/src/main/java/net/mcreator/superbwarfare/entity/ClaymoreEntity.java +++ b/src/main/java/net/mcreator/superbwarfare/entity/ClaymoreEntity.java @@ -6,111 +6,195 @@ import net.mcreator.superbwarfare.init.ModEntities; import net.mcreator.superbwarfare.init.ModItems; import net.mcreator.superbwarfare.tools.CustomExplosion; import net.mcreator.superbwarfare.tools.ParticleTool; -import net.minecraft.core.Direction; -import net.minecraft.network.protocol.Packet; -import net.minecraft.network.protocol.game.ClientGamePacketListener; +import net.minecraft.core.NonNullList; +import net.minecraft.nbt.CompoundTag; 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.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.ai.attributes.AttributeSupplier; +import net.minecraft.world.entity.ai.attributes.Attributes; import net.minecraft.world.entity.player.Player; -import net.minecraft.world.entity.projectile.ThrowableItemProjectile; -import net.minecraft.world.item.Item; +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.minecraft.world.phys.AABB; -import net.minecraft.world.phys.BlockHitResult; -import net.minecraft.world.phys.HitResult; import net.minecraft.world.phys.Vec3; -import net.minecraftforge.network.NetworkHooks; -import net.minecraftforge.network.PlayMessages; +import net.minecraftforge.items.ItemHandlerHelper; import software.bernie.geckolib.animatable.GeoEntity; import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache; import software.bernie.geckolib.core.animation.AnimatableManager; +import software.bernie.geckolib.core.animation.AnimationController; +import software.bernie.geckolib.core.animation.AnimationState; +import software.bernie.geckolib.core.animation.RawAnimation; +import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; +import javax.annotation.Nullable; 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 ANIMATION = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.STRING); - public static final EntityDataAccessor ROT_Y = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.FLOAT); - + protected static final EntityDataAccessor> OWNER_UUID = SynchedEntityData.defineId(ClaymoreEntity.class, EntityDataSerializers.OPTIONAL_UUID); private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + public String animationProcedure = "empty"; - public ClaymoreEntity(EntityType type, Level world) { + public ClaymoreEntity(EntityType type, Level world) { super(type, world); } - public ClaymoreEntity(EntityType type, LivingEntity entity, Level world) { - super(type, entity, world); - } - - public ClaymoreEntity(LivingEntity entity, Level level) { - super(ModEntities.CLAYMORE.get(), entity, level); - } - - public ClaymoreEntity(PlayMessages.SpawnEntity spawnEntity, Level level) { - this(ModEntities.CLAYMORE.get(), level); + public ClaymoreEntity(LivingEntity owner, Level level) { + super(ModEntities.CLAYMORE.get(), level); + this.setOwnerUUID(owner.getUUID()); } @Override protected void defineSynchedData() { - this.entityData.define(ROT_Y, 0f); - } - - public void setRotY(float rotY) { - this.entityData.set(ROT_Y, rotY); + super.defineSynchedData(); + this.entityData.define(ANIMATION, "undefined"); + this.entityData.define(OWNER_UUID, Optional.empty()); } @Override - public Packet getAddEntityPacket() { - return NetworkHooks.getEntitySpawningPacket(this); + public boolean isCustomNameVisible() { + return false; } @Override - protected Item getDefaultItem() { - return ModItems.CLAYMORE_MINE.get(); + public MobType getMobType() { + return super.getMobType(); } @Override - public boolean shouldRenderAtSqrDistance(double pDistance) { - return true; + public Iterable getArmorSlots() { + return NonNullList.withSize(1, ItemStack.EMPTY); } @Override - protected void onHit(HitResult result) { - switch (result.getType()) { - case BLOCK: - BlockHitResult blockResult = (BlockHitResult) result; - this.bounce(blockResult.getDirection()); - break; - 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; - default: - break; + public ItemStack getItemBySlot(EquipmentSlot pSlot) { + return ItemStack.EMPTY; + } + + @Override + public void setItemSlot(EquipmentSlot pSlot, ItemStack pStack) { + + } + + @Override + public boolean hurt(DamageSource source, float amount) { + 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) { - switch (direction.getAxis()) { - case X: - this.setDeltaMovement(this.getDeltaMovement().multiply(-0.5, 0.75, 0.75)); - break; - case Y: - this.setDeltaMovement(this.getDeltaMovement().multiply(0.75, -0.01, 0.75)); - if (this.getDeltaMovement().y() < this.getGravity()) { - this.setDeltaMovement(this.getDeltaMovement().multiply(1, 0, 1)); - } - break; - case Z: - this.setDeltaMovement(this.getDeltaMovement().multiply(0.75, 0.75, -0.5)); - break; + private void destroyExplode() { + CustomExplosion explosion = new CustomExplosion(this.level(), this, + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, this.getOwner()), 15f, + this.getX(), this.getY(), this.getZ(), 7.5f, Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); + explosion.explode(); + net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); + explosion.finalizeExplosion(false); + + ParticleTool.spawnMediumExplosionParticles(this.level(), this.position()); + } + + public void setOwnerUUID(@Nullable UUID pUuid) { + this.entityData.set(OWNER_UUID, Optional.ofNullable(pUuid)); + } + + @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 public void tick() { super.tick(); @@ -123,11 +207,15 @@ public class ClaymoreEntity extends ThrowableItemProjectile implements GeoEntity 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); 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 && target instanceof LivingEntity + && !(target instanceof ClaymoreEntity) && !(target instanceof TargetEntity) && !(target instanceof Player player && (player.isCreative() || player.isSpectator())) && (!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) { CustomExplosion explosion = new CustomExplosion(this.level(), this, - ModDamageTypes.causeMineDamage(this.level().registryAccess(), this.getOwner()), 80f, - target.getX(), target.getY(), target.getZ(), 6f, Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); + ModDamageTypes.causeMineDamage(this.level().registryAccess(), this.getOwner()), 40f, + target.getX(), target.getY(), target.getZ(), 4f, Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this.level(), explosion); explosion.finalizeExplosion(false); } - @Override - protected void updateRotation() { - this.setXRot(0); - this.setYRot(this.entityData.get(ROT_Y)); - } - @Override public EntityDimensions getDimensions(Pose p_33597_) { return super.getDimensions(p_33597_).scale((float) 0.5); } @Override - protected float getGravity() { - return 0.07F; + public boolean isPushable() { + 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 event) { + if (this.animationProcedure.equals("empty")) { + return event.setAndContinue(RawAnimation.begin().thenLoop("animation.claymore.idle")); + } + return PlayState.STOP; + } + + private PlayState procedurePredicate(AnimationState 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() { @@ -191,10 +312,20 @@ public class ClaymoreEntity extends ThrowableItemProjectile implements GeoEntity @Override 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 public AnimatableInstanceCache getAnimatableInstanceCache() { 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); + } +} \ No newline at end of file diff --git a/src/main/java/net/mcreator/superbwarfare/init/ModEntities.java b/src/main/java/net/mcreator/superbwarfare/init/ModEntities.java index 021b0547a..6a0cc5983 100644 --- a/src/main/java/net/mcreator/superbwarfare/init/ModEntities.java +++ b/src/main/java/net/mcreator/superbwarfare/init/ModEntities.java @@ -25,7 +25,7 @@ public class ModEntities { EntityType.Builder.of(SenpaiEntity::new, MobCategory.MONSTER).setShouldReceiveVelocityUpdates(true).setTrackingRange(1024).setUpdateInterval(3).setCustomClientFactory(SenpaiEntity::new) .sized(0.6f, 2f)); public static final RegistryObject> CLAYMORE = register("claymore", - EntityType.Builder.of(ClaymoreEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(ClaymoreEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(ClaymoreEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).sized(0.5f, 0.5f)); public static final RegistryObject> MK_42 = register("mk_42", EntityType.Builder.of(Mk42Entity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(5124).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f)); public static final RegistryObject> MLE_1934 = register("mle_1934", @@ -55,8 +55,8 @@ public class ModEntities { EntityType.Builder.of(RgoGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(RgoGrenadeEntity::new).sized(0.3f, 0.3f)); - private static RegistryObject> register(String registryname, EntityType.Builder entityTypeBuilder) { - return REGISTRY.register(registryname, () -> entityTypeBuilder.build(registryname)); + private static RegistryObject> register(String name, EntityType.Builder entityTypeBuilder) { + return REGISTRY.register(name, () -> entityTypeBuilder.build(name)); } @SubscribeEvent @@ -72,5 +72,6 @@ public class ModEntities { event.put(MK_42.get(), Mk42Entity.createAttributes().build()); event.put(DRONE.get(), DroneEntity.createAttributes().build()); event.put(MLE_1934.get(), Mle1934Entity.createAttributes().build()); + event.put(CLAYMORE.get(), ClaymoreEntity.createAttributes().build()); } } diff --git a/src/main/java/net/mcreator/superbwarfare/item/ClaymoreMine.java b/src/main/java/net/mcreator/superbwarfare/item/ClaymoreMine.java index 64861f7e6..24e184ee3 100644 --- a/src/main/java/net/mcreator/superbwarfare/item/ClaymoreMine.java +++ b/src/main/java/net/mcreator/superbwarfare/item/ClaymoreMine.java @@ -14,17 +14,24 @@ public class ClaymoreMine extends Item { } @Override - public InteractionResultHolder use(Level world, Player player, InteractionHand hand) { + public InteractionResultHolder use(Level level, Player player, InteractionHand hand) { ItemStack stack = player.getItemInHand(hand); - ClaymoreEntity claymore = new ClaymoreEntity(player, world); - claymore.setPos(player.getX(), player.getEyeY() - 0.3, player.getZ()); - claymore.shoot(player.getLookAngle().x, player.getLookAngle().y, player.getLookAngle().z, 0.2f,0); - claymore.setRotY(player.getYRot()); - world.addFreshEntity(claymore); + if (!level.isClientSide) { + ClaymoreEntity entity = new ClaymoreEntity(player, level); + entity.moveTo(player.getX(), player.getY() + 1.1, player.getZ(), player.getYRot(), 0); + entity.setYBodyRot(player.getYRot()); + 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); - stack.shrink(1); + + if (!player.getAbilities().instabuild) { + stack.shrink(1); + } return InteractionResultHolder.consume(stack); }