diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/FlareDecoyEntityRenderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/FlareDecoyEntityRenderer.java new file mode 100644 index 000000000..d5c668347 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/FlareDecoyEntityRenderer.java @@ -0,0 +1,56 @@ +package com.atsuishio.superbwarfare.client.renderer.entity; + +import com.atsuishio.superbwarfare.ModUtils; +import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; +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.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.texture.OverlayTexture; +import net.minecraft.core.BlockPos; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.entity.Entity; +import org.joml.Matrix3f; +import org.joml.Matrix4f; + +public class FlareDecoyEntityRenderer extends EntityRenderer { + public FlareDecoyEntityRenderer(EntityRendererProvider.Context pContext) { + super(pContext); + } + + protected int getBlockLightLevel(FlareDecoyEntity pEntity, BlockPos pPos) { + return 15; + } + + public void render(FlareDecoyEntity pEntity, float pEntityYaw, float pPartialTicks, PoseStack pMatrixStack, MultiBufferSource pBuffer, int pPackedLight) { + pMatrixStack.pushPose(); + pMatrixStack.scale(1.0F, 1.0F, 1.0F); + pMatrixStack.mulPose(this.entityRenderDispatcher.cameraOrientation()); + pMatrixStack.mulPose(Axis.YP.rotationDegrees(180.0F)); + PoseStack.Pose $$6 = pMatrixStack.last(); + Matrix4f $$7 = $$6.pose(); + Matrix3f $$8 = $$6.normal(); + VertexConsumer $$9 = pBuffer.getBuffer(RenderType.entityCutoutNoCull(texture(pEntity))); + vertex($$9, $$7, $$8, pPackedLight, 0.0F, 0, 0, 1); + vertex($$9, $$7, $$8, pPackedLight, 1.0F, 0, 1, 1); + vertex($$9, $$7, $$8, pPackedLight, 1.0F, 1, 1, 0); + vertex($$9, $$7, $$8, pPackedLight, 0.0F, 1, 0, 0); + pMatrixStack.popPose(); + super.render(pEntity, pEntityYaw, pPartialTicks, pMatrixStack, pBuffer, pPackedLight); + } + + private static void vertex(VertexConsumer pConsumer, Matrix4f pPose, Matrix3f pNormal, int pLightmapUV, float pX, float pY, int pU, int pV) { + pConsumer.vertex(pPose, pX - 0.5F, pY - 0.25F, 0.0F).color(255, 255, 255, 255).uv((float)pU, (float)pV).overlayCoords(OverlayTexture.NO_OVERLAY).uv2(pLightmapUV).normal(pNormal, 0.0F, 1.0F, 0.0F).endVertex(); + } + + private static ResourceLocation texture(Entity entity) { + return ModUtils.loc("textures/particle/fire_star_" + (entity.tickCount %8 + 1) + ".png"); + } + + public ResourceLocation getTextureLocation(FlareDecoyEntity pEntity) { + return texture(pEntity); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/FlareDecoyEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/FlareDecoyEntity.java new file mode 100644 index 000000000..b4c7ed8d7 --- /dev/null +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/FlareDecoyEntity.java @@ -0,0 +1,89 @@ +package com.atsuishio.superbwarfare.entity.projectile; + +import com.atsuishio.superbwarfare.init.ModEntities; +import com.atsuishio.superbwarfare.tools.ParticleTool; +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.server.level.ServerLevel; +import net.minecraft.util.Mth; +import net.minecraft.world.damagesource.DamageSource; +import net.minecraft.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.MoverType; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.Vec3; +import net.minecraftforge.network.NetworkHooks; +import net.minecraftforge.network.PlayMessages; + +public class FlareDecoyEntity extends Entity { + public FlareDecoyEntity(EntityType type, Level world) { + super(type, world); + } + + public FlareDecoyEntity(LivingEntity entity, Level level) { + super(ModEntities.FLARE_DECOY.get(), level); + } + + public FlareDecoyEntity(PlayMessages.SpawnEntity spawnEntity, Level level) { + this(ModEntities.FLARE_DECOY.get(), level); + } + + @Override + public Packet getAddEntityPacket() { + return NetworkHooks.getEntitySpawningPacket(this); + } + + @Override + public boolean hurt(DamageSource source, float amount) { + this.discard(); + return super.hurt(source, amount); + } + + @Override + protected void readAdditionalSaveData(CompoundTag compoundTag) { + + } + + @Override + protected void addAdditionalSaveData(CompoundTag compoundTag) { + + } + + @Override + public boolean isPickable() { + return !this.isRemoved(); + } + + @Override + protected void defineSynchedData() { + } + + @Override + public void tick() { + super.tick(); + this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.02, 0.0)); + this.move(MoverType.SELF, this.getDeltaMovement()); + if (!this.level().isClientSide() && this.level() instanceof ServerLevel serverLevel) { + ParticleTool.sendParticle(serverLevel, ParticleTypes.END_ROD, this.xo, this.yo, this.zo, + 1, 0, 0, 0, 0.02, true); + ParticleTool.sendParticle(serverLevel, ParticleTypes.CLOUD, this.xo, this.yo, this.zo, + 1, 0, 0, 0, 0.02, true); + } + if (this.tickCount > 200 || this.isInWater() || this.onGround()) { + this.discard(); + } + } + + public void decoyShoot(Entity entity, Vec3 shootVec, float pVelocity, float pInaccuracy) { + Vec3 vec3 = shootVec.normalize().add(this.random.triangle(0.0, 0.0172275 * (double)pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double)pInaccuracy), this.random.triangle(0.0, 0.0172275 * (double)pInaccuracy)).scale((double)pVelocity); + this.setDeltaMovement(entity.getDeltaMovement().scale(0.75).add(vec3)); + double d0 = vec3.horizontalDistance(); + this.setYRot((float)(Mth.atan2(vec3.x, vec3.z) * 57.2957763671875)); + this.setXRot((float)(Mth.atan2(vec3.y, d0) * 57.2957763671875)); + this.yRotO = this.getYRot(); + this.xRotO = this.getXRot(); + } +} diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java index 7f070186e..9dbe5303e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/GunGrenadeEntity.java @@ -15,7 +15,6 @@ import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.server.level.ServerLevel; import net.minecraft.server.level.ServerPlayer; import net.minecraft.sounds.SoundSource; -import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.EntityType; import net.minecraft.world.entity.LivingEntity; @@ -27,7 +26,6 @@ import net.minecraft.world.level.block.BellBlock; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.BlockHitResult; import net.minecraft.world.phys.EntityHitResult; -import net.minecraft.world.phys.Vec3; import net.minecraftforge.network.NetworkHooks; import net.minecraftforge.network.PacketDistributor; import net.minecraftforge.network.PlayMessages; @@ -162,14 +160,4 @@ public class GunGrenadeEntity extends ThrowableItemProjectile implements GeoEnti return this.cache; } - public void decoyShoot(Entity entity, Vec3 shootVec, float pVelocity) { - Vec3 vec3 = shootVec.normalize().scale(pVelocity); - this.setDeltaMovement(entity.getDeltaMovement().add(vec3)); - double d0 = vec3.horizontalDistance(); - this.setYRot((float)(Mth.atan2(vec3.x, vec3.z) * 57.2957763671875)); - this.setXRot((float)(Mth.atan2(vec3.y, d0) * 57.2957763671875)); - this.yRotO = this.getYRot(); - this.xRotO = this.getXRot(); - } - } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java index 3df8a19dd..885c17af8 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/JavelinMissileEntity.java @@ -11,6 +11,7 @@ import com.atsuishio.superbwarfare.network.message.ClientIndicatorMessage; import com.atsuishio.superbwarfare.tools.EntityFindUtil; import com.atsuishio.superbwarfare.tools.ParticleTool; import com.atsuishio.superbwarfare.tools.ProjectileTool; +import com.atsuishio.superbwarfare.tools.SeekTool; import net.minecraft.commands.arguments.EntityAnchorArgument; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; @@ -50,6 +51,8 @@ import software.bernie.geckolib.core.animation.RawAnimation; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.List; + public class JavelinMissileEntity extends ThrowableItemProjectile implements GeoEntity, AnimatedEntity { public static final EntityDataAccessor TARGET_UUID = SynchedEntityData.defineId(JavelinMissileEntity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor TOP = SynchedEntityData.defineId(JavelinMissileEntity.class, EntityDataSerializers.BOOLEAN); @@ -61,6 +64,7 @@ public class JavelinMissileEntity extends ThrowableItemProjectile implements Geo private float damage = 500.0f; private float explosion_damage = 140f; private float explosion_radius = 6f; + private boolean distracted = false; public JavelinMissileEntity(EntityType type, Level world) { super(type, world); @@ -183,18 +187,32 @@ public class JavelinMissileEntity extends ThrowableItemProjectile implements Geo @Override public void tick() { super.tick(); - Entity entity = EntityFindUtil.findEntity(this.level(), entityData.get(TARGET_UUID)); + List decoy = SeekTool.seekLivingEntities(this, this.level(), 48 , 160); - if (entity != null && entity.level() instanceof ServerLevel) { - this.entityData.set(TARGET_X, (float) entity.getX()); - this.entityData.set(TARGET_Y, (float) entity.getEyeY()); - this.entityData.set(TARGET_Z, (float) entity.getZ()); - if ((!entity.getPassengers().isEmpty() || entity instanceof VehicleEntity) && entity.tickCount %((int)Math.max(0.04 * this.distanceTo(entity),2)) == 0) { - entity.level().playSound(null, entity.getOnPos(), entity instanceof Pig ? SoundEvents.PIG_HURT : ModSounds.MISSILE_WARNING.get(), SoundSource.PLAYERS, 2, 1f); + for (var e : decoy) { + if (e instanceof FlareDecoyEntity flareDecoy && !distracted) { + this.entityData.set(TARGET_UUID, flareDecoy.getStringUUID()); + distracted = true; } } + if (entity != null) { + if (entity.level() instanceof ServerLevel) { + this.entityData.set(TARGET_X, (float) entity.getX()); + this.entityData.set(TARGET_Y, (float) entity.getEyeY()); + this.entityData.set(TARGET_Z, (float) entity.getZ()); + if ((!entity.getPassengers().isEmpty() || entity instanceof VehicleEntity) && entity.tickCount %((int)Math.max(0.04 * this.distanceTo(entity),2)) == 0) { + entity.level().playSound(null, entity.getOnPos(), entity instanceof Pig ? SoundEvents.PIG_HURT : ModSounds.MISSILE_WARNING.get(), SoundSource.PLAYERS, 2, 1f); + } + } + } else { + this.entityData.set(TARGET_X, (float)(this.getX() + this.getDeltaMovement().scale(10).x)); + this.entityData.set(TARGET_Y, (float)(this.getY() + this.getDeltaMovement().scale(10).y)); + this.entityData.set(TARGET_Z, (float)(this.getZ() + this.getDeltaMovement().scale(10).z)); + } + + double px = this.getX(); double ex = this.entityData.get(TARGET_X); double pz = this.getZ(); diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java index 86e3486d2..53686c84a 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/Ah6Entity.java @@ -3,7 +3,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionDestroyConfig; import com.atsuishio.superbwarfare.config.server.VehicleConfig; -import com.atsuishio.superbwarfare.entity.projectile.GunGrenadeEntity; +import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; import com.atsuishio.superbwarfare.entity.projectile.HeliRocketEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.init.*; @@ -15,6 +15,7 @@ import com.google.common.collect.Lists; import net.minecraft.core.BlockPos; import net.minecraft.core.particles.ParticleTypes; import net.minecraft.nbt.CompoundTag; +import net.minecraft.network.chat.Component; import net.minecraft.network.protocol.Packet; import net.minecraft.network.protocol.game.ClientGamePacketListener; import net.minecraft.network.syncher.EntityDataAccessor; @@ -51,6 +52,7 @@ import software.bernie.geckolib.core.animatable.instance.AnimatableInstanceCache import software.bernie.geckolib.core.animation.AnimatableManager; import software.bernie.geckolib.util.GeckoLibUtil; +import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Comparator; import java.util.List; @@ -67,6 +69,7 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli public static final EntityDataAccessor WEAPON_TYPE = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor AMMO = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.INT); + public static final EntityDataAccessor DECOY_COUNT = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.INT); public static final EntityDataAccessor LOADED_ROCKET = SynchedEntityData.defineId(Ah6Entity.class, EntityDataSerializers.INT); public boolean engineStart; public boolean engineStartOver; @@ -75,6 +78,7 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli public double velocity; public int reloadCoolDown; + public int decoyReloadCoolDown; public int fireIndex; public Ah6Entity(PlayMessages.SpawnEntity packet, Level world) { @@ -94,18 +98,23 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli this.entityData.define(DELTA_ROT, 0f); this.entityData.define(WEAPON_TYPE, 0); this.entityData.define(PROPELLER_ROT, 0f); + this.entityData.define(DECOY_COUNT, 6); } @Override public void addAdditionalSaveData(CompoundTag compound) { super.addAdditionalSaveData(compound); compound.putInt("LoadedRocket", this.entityData.get(LOADED_ROCKET)); + compound.putFloat("propellerRot", this.entityData.get(PROPELLER_ROT)); + compound.putInt("decoyCount", this.entityData.get(DECOY_COUNT)); } @Override public void readAdditionalSaveData(CompoundTag compound) { super.readAdditionalSaveData(compound); this.entityData.set(LOADED_ROCKET, compound.getInt("LoadedRocket")); + this.entityData.set(PROPELLER_ROT, compound.getFloat("propellerRot")); + this.entityData.set(DECOY_COUNT, compound.getInt("decoyCount")); } @Override @@ -145,6 +154,9 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli if (reloadCoolDown > 0) { reloadCoolDown--; } + if (decoyReloadCoolDown > 0) { + decoyReloadCoolDown--; + } Player player = (Player) this.getFirstPassenger(); if (player != null) { if ((this.getItemStacks().stream().filter(stack -> stack.is(ModItems.ROCKET_70.get())).mapToInt(ItemStack::getCount).sum() > 0 || player.getInventory().hasAnyMatching(s -> s.is(ModItems.CREATIVE_AMMO_BOX.get()))) && reloadCoolDown == 0 && this.getEntityData().get(LOADED_ROCKET) < 14) { @@ -179,29 +191,35 @@ public class Ah6Entity extends ContainerMobileEntity implements GeoEntity, IHeli this.hurt(ModDamageTypes.causeVehicleStrikeDamage(this.level().registryAccess(), this, this.getFirstPassenger() == null ? this : this.getFirstPassenger()), 26 + (float) (60 * ((lastTickSpeed - 0.4) * (lastTickSpeed - 0.4)))); } - lowHealthWarning(); releaseDecoy(); + lowHealthWarning(); this.refreshDimensions(); } public void releaseDecoy() { if (decoyInputDown) { - if (!this.level().isClientSide()) { + if (this.entityData.get(DECOY_COUNT) > 0) { Entity passenger = this.getPassengers().isEmpty() ? null : this.getPassengers().get(0); - for (int i = 0; i < 6; i++) { - GunGrenadeEntity gunGrenadeEntity = new GunGrenadeEntity((LivingEntity) passenger, this.level(), - 5, - 5, - 5); - gunGrenadeEntity.setPos(this.getX(), this.getY() + 0.3, this.getZ()); - gunGrenadeEntity.decoyShoot(this, this.getDeltaMovement().normalize().yRot(60 * i * Mth.DEG_TO_RAD), 0.4f); - this.level().addFreshEntity(gunGrenadeEntity); + for (int i = 0; i < 4; i++) { + FlareDecoyEntity flareDecoyEntity = new FlareDecoyEntity((LivingEntity) passenger, this.level()); + flareDecoyEntity.setPos(this.getX() + this.getDeltaMovement().x, this.getY() + 0.5 + this.getDeltaMovement().y, this.getZ()+ this.getDeltaMovement().z); + flareDecoyEntity.decoyShoot(this, this.getViewVector(1).yRot((45 + 90 * i) * Mth.DEG_TO_RAD), 0.8f, 8); + this.level().addFreshEntity(flareDecoyEntity); } - + this.getEntityData().set(DECOY_COUNT, this.getEntityData().get(DECOY_COUNT) - 1); } decoyInputDown = false; } + if (this.entityData.get(DECOY_COUNT) < 6 && decoyReloadCoolDown == 0) { + this.entityData.set(DECOY_COUNT, this.entityData.get(DECOY_COUNT) + 1); + decoyReloadCoolDown = 300; + } + Player player = (Player) this.getFirstPassenger(); + + if (player != null) { + player.displayClientMessage(Component.literal( new DecimalFormat("##").format(this.getEntityData().get(DECOY_COUNT))), true); + } } @Override diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MobileVehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MobileVehicleEntity.java index bd3a2254f..4281c075e 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MobileVehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/MobileVehicleEntity.java @@ -1,6 +1,7 @@ package com.atsuishio.superbwarfare.entity.vehicle; import com.atsuishio.superbwarfare.entity.TargetEntity; +import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; import com.atsuishio.superbwarfare.entity.projectile.LaserEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.init.ModDamageTypes; @@ -135,7 +136,7 @@ public class MobileVehicleEntity extends EnergyVehicleEntity { var entities = level().getEntities(EntityTypeTest.forClass(Entity.class), frontBox, entity -> entity != this && entity != getFirstPassenger() && entity.getVehicle() == null) .stream().filter(entity -> entity.isAlive() - && !(entity instanceof ItemEntity || entity instanceof Projectile || entity instanceof ProjectileEntity || entity instanceof LaserEntity) + && !(entity instanceof ItemEntity || entity instanceof Projectile || entity instanceof ProjectileEntity || entity instanceof LaserEntity || entity instanceof FlareDecoyEntity) && !(entity instanceof Player player && (player.isSpectator() || player.isCreative()))) .toList(); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java b/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java index cd522696d..eb1d9f7e6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModEntities.java @@ -23,7 +23,7 @@ public class ModEntities { public static final DeferredRegister> REGISTRY = DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, ModUtils.MODID); public static final RegistryObject> TARGET = register("target", - EntityType.Builder.of(TargetEntity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(TargetEntity::new).fireImmune().sized(0.875f, 2f)); + EntityType.Builder.of(TargetEntity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(TargetEntity::new).fireImmune().sized(0.875f, 2f)); public static final RegistryObject> MORTAR = register("mortar", EntityType.Builder.of(MortarEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(MortarEntity::new).fireImmune().sized(0.8f, 1.4f)); public static final RegistryObject> SENPAI = register("senpai", @@ -32,44 +32,46 @@ public class ModEntities { public static final RegistryObject> CLAYMORE = register("claymore", EntityType.Builder.of(ClaymoreEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).sized(0.5f, 0.5f)); public static final RegistryObject> MK_42 = register("mk_42", - EntityType.Builder.of(Mk42Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f)); + EntityType.Builder.of(Mk42Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(Mk42Entity::new).fireImmune().sized(3.4f, 3.5f)); public static final RegistryObject> MLE_1934 = register("mle_1934", - EntityType.Builder.of(Mle1934Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(Mle1934Entity::new).fireImmune().sized(4.5f, 2.8f)); + EntityType.Builder.of(Mle1934Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(Mle1934Entity::new).fireImmune().sized(4.5f, 2.8f)); public static final RegistryObject> ANNIHILATOR = register("annihilator", - EntityType.Builder.of(AnnihilatorEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(AnnihilatorEntity::new).fireImmune().sized(13f, 4.2f)); + EntityType.Builder.of(AnnihilatorEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(AnnihilatorEntity::new).fireImmune().sized(13f, 4.2f)); public static final RegistryObject> DRONE = register("drone", - EntityType.Builder.of(DroneEntity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(DroneEntity::new).sized(0.6f, 0.2f)); + EntityType.Builder.of(DroneEntity::new, MobCategory.CREATURE).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(DroneEntity::new).sized(0.6f, 0.2f)); public static final RegistryObject> TASER_BULLET_PROJECTILE = register("projectile_taser_bullet_projectile", EntityType.Builder.of(TaserBulletProjectileEntity::new, MobCategory.MISC).setCustomClientFactory(TaserBulletProjectileEntity::new).setShouldReceiveVelocityUpdates(true).setTrackingRange(64) .setUpdateInterval(1).sized(0.5f, 0.5f)); public static final RegistryObject> GUN_GRENADE = register("projectile_gun_grenade", - EntityType.Builder.of(GunGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(GunGrenadeEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(GunGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(GunGrenadeEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> RPG_ROCKET = register("projectile_rpg_rocket", - EntityType.Builder.of(RpgRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(RpgRocketEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(RpgRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(RpgRocketEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> MORTAR_SHELL = register("projectile_mortar_shell", - EntityType.Builder.of(MortarShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(MortarShellEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(MortarShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(MortarShellEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> PROJECTILE = register("projectile", - EntityType.Builder.of(ProjectileEntity::new, MobCategory.MISC).setCustomClientFactory(ProjectileEntity::new).setTrackingRange(512).sized(0.5f, 0.5f)); + EntityType.Builder.of(ProjectileEntity::new, MobCategory.MISC).setCustomClientFactory(ProjectileEntity::new).setTrackingRange(64).sized(0.5f, 0.5f)); public static final RegistryObject> CANNON_SHELL = register("projectile_cannon_shell", - EntityType.Builder.of(CannonShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(CannonShellEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(CannonShellEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(CannonShellEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> HAND_GRENADE_ENTITY = register("projectile_hand_grenade_entity", - EntityType.Builder.of(HandGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(HandGrenadeEntity::new).sized(0.3f, 0.3f)); + EntityType.Builder.of(HandGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(HandGrenadeEntity::new).sized(0.3f, 0.3f)); public static final RegistryObject> RGO_GRENADE = register("projectile_rgo_grenade", - EntityType.Builder.of(RgoGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(RgoGrenadeEntity::new).sized(0.3f, 0.3f)); + EntityType.Builder.of(RgoGrenadeEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(RgoGrenadeEntity::new).sized(0.3f, 0.3f)); public static final RegistryObject> JAVELIN_MISSILE = register("projectile_javelin_missile", - EntityType.Builder.of(JavelinMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(JavelinMissileEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(JavelinMissileEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(JavelinMissileEntity::new).sized(0.5f, 0.5f)); public static final RegistryObject> LASER = register("laser", EntityType.Builder.of(LaserEntity::new, MobCategory.MISC).sized(0.1f, 0.1f).fireImmune().setUpdateInterval(1)); public static final RegistryObject> SPEEDBOAT = register("speedboat", - EntityType.Builder.of(SpeedboatEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(SpeedboatEntity::new).fireImmune().sized(3.0f, 2.0f)); + EntityType.Builder.of(SpeedboatEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(SpeedboatEntity::new).fireImmune().sized(3.0f, 2.0f)); public static final RegistryObject> WHEEL_CHAIR = register("wheel_chair", - EntityType.Builder.of(WheelChairEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(WheelChairEntity::new).fireImmune().sized(1.0f, 1.0f)); + EntityType.Builder.of(WheelChairEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(WheelChairEntity::new).fireImmune().sized(1.0f, 1.0f)); public static final RegistryObject> AH_6 = register("ah_6", - EntityType.Builder.of(Ah6Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(3).setCustomClientFactory(Ah6Entity::new).fireImmune().sized(2.8f, 2.9f)); + EntityType.Builder.of(Ah6Entity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(3).setCustomClientFactory(Ah6Entity::new).fireImmune().sized(2.8f, 2.9f)); public static final RegistryObject> HELI_ROCKET = register("projectile_heli_rocket", - EntityType.Builder.of(HeliRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(512).setUpdateInterval(1).setCustomClientFactory(HeliRocketEntity::new).sized(0.5f, 0.5f)); + EntityType.Builder.of(HeliRocketEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(HeliRocketEntity::new).sized(0.5f, 0.5f)); + public static final RegistryObject> FLARE_DECOY = register("flare_decoy_entity", + EntityType.Builder.of(FlareDecoyEntity::new, MobCategory.MISC).setShouldReceiveVelocityUpdates(true).setTrackingRange(64).setUpdateInterval(1).setCustomClientFactory(FlareDecoyEntity::new).sized(0.5f, 0.5f)); private static RegistryObject> register(String name, EntityType.Builder entityTypeBuilder) { return REGISTRY.register(name, () -> entityTypeBuilder.build(name)); diff --git a/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java b/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java index 9bae710fa..69954e250 100644 --- a/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java +++ b/src/main/java/com/atsuishio/superbwarfare/init/ModEntityRenderers.java @@ -33,5 +33,6 @@ public class ModEntityRenderers { event.registerEntityRenderer(ModEntities.SPEEDBOAT.get(), SpeedboatRenderer::new); event.registerEntityRenderer(ModEntities.WHEEL_CHAIR.get(), WheelChairRenderer::new); event.registerEntityRenderer(ModEntities.AH_6.get(), Ah6Renderer::new); + event.registerEntityRenderer(ModEntities.FLARE_DECOY.get(), FlareDecoyEntityRenderer::new); } } diff --git a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java index ff2ca6b8c..614fd9ad0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/gun/launcher/JavelinItem.java @@ -4,6 +4,7 @@ import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.client.PoseTool; import com.atsuishio.superbwarfare.client.renderer.item.JavelinItemRenderer; import com.atsuishio.superbwarfare.client.tooltip.component.LauncherImageComponent; +import com.atsuishio.superbwarfare.entity.projectile.FlareDecoyEntity; import com.atsuishio.superbwarfare.entity.vehicle.VehicleEntity; import com.atsuishio.superbwarfare.event.ClientEventHandler; import com.atsuishio.superbwarfare.init.ModItems; @@ -44,6 +45,7 @@ import software.bernie.geckolib.core.animation.RawAnimation; import software.bernie.geckolib.core.object.PlayState; import software.bernie.geckolib.util.GeckoLibUtil; +import java.util.List; import java.util.Optional; import java.util.Set; import java.util.function.Consumer; @@ -145,8 +147,15 @@ public class JavelinItem extends GunItem implements GeoItem, AnimatedItem { GunsTool.setGunIntTag(stack, "MaxAmmo", getAmmoCount(player)); if (tag.getBoolean("Seeking")) { + List decoy = SeekTool.seekLivingEntities(player, player.level(), 512, 8); Entity targetEntity = EntityFindUtil.findEntity(player.level(), tag.getString("TargetEntity")); Entity seekingEntity = SeekTool.seekEntity(player, player.level(), 512, 8); + for (var e : decoy) { + if (e instanceof FlareDecoyEntity flareDecoy) { + tag.putString("TargetEntity", flareDecoy.getStringUUID()); + } + } + if (seekingEntity != null && seekingEntity == targetEntity) { tag.putInt("SeekTime", tag.getInt("SeekTime") + 1); if (tag.getInt("SeekTime") > 0 && (!seekingEntity.getPassengers().isEmpty() || seekingEntity instanceof VehicleEntity) && seekingEntity.tickCount %3 == 0) { diff --git a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java index b6646edcc..24dc385f0 100644 --- a/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java +++ b/src/main/java/com/atsuishio/superbwarfare/tools/SeekTool.java @@ -3,12 +3,10 @@ package com.atsuishio.superbwarfare.tools; import com.atsuishio.superbwarfare.entity.ClaymoreEntity; import com.atsuishio.superbwarfare.entity.projectile.ProjectileEntity; import com.atsuishio.superbwarfare.entity.vehicle.MobileVehicleEntity; -import com.atsuishio.superbwarfare.entity.vehicle.VehicleEntity; import net.minecraft.core.BlockPos; import net.minecraft.util.Mth; import net.minecraft.world.entity.Entity; import net.minecraft.world.entity.ExperienceOrb; -import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.decoration.ArmorStand; import net.minecraft.world.entity.decoration.HangingEntity; import net.minecraft.world.entity.item.ItemEntity; @@ -56,7 +54,7 @@ public class SeekTool { && e != entity && e.isAlive() && !(e instanceof ItemEntity || e instanceof ExperienceOrb || e instanceof HangingEntity || e instanceof ProjectileEntity || e instanceof Projectile || e instanceof ArmorStand) - && (e instanceof LivingEntity || e instanceof VehicleEntity) + && e.getVehicle() == null && !(e instanceof Player player && (player.isSpectator())) && (!e.isAlliedTo(entity) || e.getTeam() == null || e.getTeam().getName().equals("TDM"))) { return level.clip(new ClipContext(entity.getEyePosition(), e.getEyePosition(), @@ -73,7 +71,7 @@ public class SeekTool { && e != entity && e.isAlive() && !(e instanceof ItemEntity || e instanceof ExperienceOrb || e instanceof HangingEntity || e instanceof ProjectileEntity || e instanceof Projectile || e instanceof ArmorStand) - && (e instanceof LivingEntity || e instanceof VehicleEntity) + && e.getVehicle() == null && !(e instanceof Player player && (player.isSpectator())) && (!e.isAlliedTo(entity) || e.getTeam() == null || e.getTeam().getName().equals("TDM"))) { return level.clip(new ClipContext(entity.getEyePosition(), e.getEyePosition(), diff --git a/src/main/resources/assets/superbwarfare/textures/particle/fire_star.png b/src/main/resources/assets/superbwarfare/textures/particle/fire_star.png deleted file mode 100644 index c9dd3c7a6..000000000 Binary files a/src/main/resources/assets/superbwarfare/textures/particle/fire_star.png and /dev/null differ