diff --git a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java index c2dcfa8d7..cf25d5321 100644 --- a/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java +++ b/src/main/java/com/atsuishio/superbwarfare/client/renderer/entity/C4Renderer.java @@ -31,24 +31,15 @@ public class C4Renderer extends GeoEntityRenderer { float scale = 0.5f; this.scaleHeight = scale; this.scaleWidth = scale; - super.preRender(poseStack, entity, model, bufferSource, buffer, isReRender, partialTick, packedLight, packedOverlay, red, green, blue, alpha); + super.preRender(poseStack, entity, model, bufferSource, buffer, isReRender, partialTick, 15, packedOverlay, red, green, blue, alpha); } @Override public void render(C4Entity 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()))); + poseStack.mulPose(Axis.YP.rotationDegrees(-entityYaw)); + poseStack.mulPose(Axis.XP.rotationDegrees(Mth.lerp(partialTicks, entityIn.xRotO, entityIn.getXRot()) + 90)); super.render(entityIn, entityYaw, partialTicks, poseStack, bufferIn, packedLightIn); poseStack.popPose(); } - - @Override - protected float getDeathMaxRotation(C4Entity entityLivingBaseIn) { - return 0.0F; - } - - @Override - public boolean shouldShowName(C4Entity animatable) { - return false; - } } diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java b/src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java index 73dd314eb..72072e0a6 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/C4Entity.java @@ -2,43 +2,41 @@ package com.atsuishio.superbwarfare.entity; import com.atsuishio.superbwarfare.ModUtils; import com.atsuishio.superbwarfare.config.server.ExplosionConfig; -import com.atsuishio.superbwarfare.entity.vehicle.base.VehicleEntity; import com.atsuishio.superbwarfare.init.ModDamageTypes; import com.atsuishio.superbwarfare.init.ModEntities; -import com.atsuishio.superbwarfare.init.ModItems; import com.atsuishio.superbwarfare.tools.CustomExplosion; -import com.atsuishio.superbwarfare.tools.EntityFindUtil; import com.atsuishio.superbwarfare.tools.ParticleTool; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; 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.sounds.SoundEvent; +import net.minecraft.sounds.SoundSource; +import net.minecraft.util.Mth; import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.entity.*; -import net.minecraft.world.entity.item.ItemEntity; -import net.minecraft.world.item.ItemStack; +import net.minecraft.world.entity.projectile.ThrowableItemProjectile; +import net.minecraft.world.item.Item; +import net.minecraft.world.level.ClipContext; 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.BlockHitResult; +import net.minecraft.world.phys.HitResult; +import net.minecraft.world.phys.Vec3; 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 javax.annotation.Nullable; -import java.util.Comparator; -import java.util.Optional; -import java.util.UUID; - -public class C4Entity extends Entity implements GeoEntity, OwnableEntity { - - protected static final EntityDataAccessor> OWNER_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.OPTIONAL_UUID); +public class C4Entity extends ThrowableItemProjectile implements GeoEntity { protected static final EntityDataAccessor LAST_ATTACKER_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING); - protected static final EntityDataAccessor> TARGET_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.OPTIONAL_UUID); + protected static final EntityDataAccessor TARGET_UUID = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.STRING); public static final EntityDataAccessor HEALTH = SynchedEntityData.defineId(C4Entity.class, EntityDataSerializers.FLOAT); - private final AnimatableInstanceCache cache = GeckoLibUtil.createInstanceCache(this); + protected boolean inGround; public C4Entity(EntityType type, Level world) { super(type, world); @@ -47,15 +45,18 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { public C4Entity(LivingEntity owner, Level level) { super(ModEntities.C_4.get(), level); - this.setOwnerUUID(owner.getUUID()); + } + + @Override + protected Item getDefaultItem() { + return null; } @Override protected void defineSynchedData() { - this.entityData.define(OWNER_UUID, Optional.empty()); this.entityData.define(LAST_ATTACKER_UUID, "undefined"); this.entityData.define(HEALTH, 10f); - this.entityData.define(TARGET_UUID, Optional.empty()); + this.entityData.define(TARGET_UUID, "undefined"); } @Override @@ -68,38 +69,11 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { return false; } - public void setOwnerUUID(@Nullable UUID pUuid) { - this.entityData.set(OWNER_UUID, Optional.ofNullable(pUuid)); - } - - public void setTargetUUID(@Nullable UUID uuid) { - this.entityData.set(TARGET_UUID, Optional.ofNullable(uuid)); - } - - @Nullable - public UUID getOwnerUUID() { - return this.entityData.get(OWNER_UUID).orElse(null); - } - - @Nullable - public UUID getTargetUUID() { - return this.entityData.get(TARGET_UUID).orElse(null); - } - - public boolean isOwnedBy(LivingEntity pEntity) { - return pEntity == this.getOwner(); - } - @Override public void addAdditionalSaveData(CompoundTag compound) { compound.putFloat("Health", this.entityData.get(HEALTH)); + compound.putString("Target", this.entityData.get(TARGET_UUID)); compound.putString("LastAttacker", this.entityData.get(LAST_ATTACKER_UUID)); - if (this.getTargetUUID() != null) { - compound.putUUID("Target", this.getTargetUUID()); - } - if (this.getOwnerUUID() != null) { - compound.putUUID("Owner", this.getOwnerUUID()); - } } @Override @@ -112,43 +86,9 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { this.entityData.set(LAST_ATTACKER_UUID, compound.getString("LastAttacker")); } - 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 (compound.contains("Target")) { + this.entityData.set(TARGET_UUID, compound.getString("Target")); } - - if (uuid != null) { - try { - this.setOwnerUUID(uuid); - } catch (Throwable ignored) { - } - } - - // Target - if (compound.hasUUID("Target")) { - uuid = compound.getUUID("Target"); - } else { - String s = compound.getString("Target"); - - assert this.getServer() != null; - uuid = OldUsersConverter.convertMobOwnerIfNecessary(this.getServer(), s); - } - - if (uuid != null) { - try { - this.setTargetUUID(uuid); - } catch (Throwable ignored) { - } - } - } - - public boolean isPlaced() { - return this.onGround() || this.getTargetUUID() != null; } @Override @@ -160,47 +100,86 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { this.explode(); } - if (!this.isPlaced()) { - this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.03, 0.0)); - this.move(MoverType.SELF, this.getDeltaMovement()); - this.setDeltaMovement(this.getDeltaMovement().multiply(0.98, 0.98, 0.98)); + if (inGround && checkNoClip()) { + inGround = false; + } - for (Entity target : level.getEntitiesOfClass(Entity.class, this.getBoundingBox().inflate(1), e -> true).stream().sorted(Comparator.comparingDouble(e -> e.distanceToSqr(this))).toList()) { - if (this.getUUID() == target.getUUID() || this.getOwnerUUID() == target.getUUID() || !(target instanceof LivingEntity || target instanceof VehicleEntity)) { - continue; - } - this.setTargetUUID(target.getUUID()); - - // var relpos = this.calcRelativePos(target); - // this.setRelativePos(((float) relpos.x), ((float) relpos.y), ((float) relpos.z)); - // if (!this.startRiding(target)) this.destroy(); - // ModUtils.LOGGER.info("Start Riding!"); - this.setInvisible(true); - break; - } - if (this.onGround()) { - this.destroy(); - } - } else { - if (level.isClientSide()) return; - if (this.getTargetUUID() == null) { - this.destroy(); - return; - } - Entity target = EntityFindUtil.findEntity(this.level(), this.getTargetUUID().toString()); - if (target == null) { - this.destroy(); - return; - } - if (!this.isInvisible()) { - this.setInvisible(true); - } - this.setPos(target.position().x, target.position().y + target.getBoundingBox().getYsize(), target.position().z); + if (!inGround) { + this.setDeltaMovement(this.getDeltaMovement().add(0.0, -0.05, 0.0)); } this.refreshDimensions(); } + public boolean checkNoClip() { + return level().clip(new ClipContext(this.getEyePosition(), this.getEyePosition().add(getViewVector(1).scale(-0.25)), + ClipContext.Block.OUTLINE, ClipContext.Fluid.NONE, this)).getType() != HitResult.Type.BLOCK; + } + + public void look(Vec3 pTarget) { + double d0 = pTarget.x; + double d1 = pTarget.y; + double d2 = pTarget.z; + double d3 = Math.sqrt(d0 * d0 + d2 * d2); + setXRot(Mth.wrapDegrees((float) (-(Mth.atan2(d1, d3) * 57.2957763671875)))); + setYRot(Mth.wrapDegrees((float) (Mth.atan2(d2, d0) * 57.2957763671875) - 90.0F)); + setYHeadRot(getYRot()); + xRotO = getXRot(); + yRotO = getYRot(); + } + + @Override + protected void updateRotation() { + if (getDeltaMovement().length() > 0.05 && !inGround) { + super.updateRotation(); + } + } + + @Override + protected void onHit(HitResult result) { + switch (result.getType()) { + case BLOCK: + BlockHitResult blockResult = (BlockHitResult) result; + BlockPos resultPos = blockResult.getBlockPos(); + BlockState state = this.level().getBlockState(resultPos); + SoundEvent event = state.getBlock().getSoundType(state, this.level(), resultPos, this).getBreakSound(); + double speed = this.getDeltaMovement().length(); + if (speed > 0.1) { + this.level().playSound(null, result.getLocation().x, result.getLocation().y, result.getLocation().z, event, SoundSource.AMBIENT, 1.0F, 1.0F); + } + this.bounce(blockResult.getDirection()); + + break; + case ENTITY: +// EntityHitResult entityResult = (EntityHitResult) result; +// Entity entity = entityResult.getEntity(); +// if (entity == this.getOwner() || entity == this.getVehicle()) return; +// double speed_e = this.getDeltaMovement().length(); +// if (speed_e > 0.1) { +// if (this.getOwner() instanceof LivingEntity living) { +// if (!living.level().isClientSide() && living instanceof ServerPlayer player) { +// living.level().playSound(null, living.blockPosition(), ModSounds.INDICATION.get(), SoundSource.VOICE, 1, 1); +// +// ModUtils.PACKET_HANDLER.send(PacketDistributor.PLAYER.with(() -> player), new ClientIndicatorMessage(0, 5)); +// } +// } +// entity.hurt(entity.damageSources().thrown(this, this.getOwner()), 1.0F); +// } +// 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; + } + } + + private void bounce(Direction direction) { + Vec3 vec3 = Vec3.atLowerCornerOf(direction.getNormal()); + look(vec3); + inGround = true; + this.setDeltaMovement(this.getDeltaMovement().multiply(0, 0, 0)); + } + public void explode() { if (!this.level().isClientSide()) { ParticleTool.spawnMediumExplosionParticles(this.level(), this.position()); @@ -215,18 +194,9 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { this.discard(); } - public void destroy() { - if (this.level() instanceof ServerLevel && this.tickCount < ExplosionConfig.C4_EXPLOSION_COUNTDOWN.get()) { - ItemEntity c4 = new ItemEntity(this.level(), this.getX(), this.getY(), this.getZ(), new ItemStack(ModItems.C4_BOMB.get())); - c4.setPickUpDelay(10); - this.level().addFreshEntity(c4); - this.discard(); - } - } - private void triggerExplode(Entity target) { CustomExplosion explosion = new CustomExplosion(level(), this, - ModDamageTypes.causeProjectileBoomDamage(level().registryAccess(), getOwner(), getOwner()), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), + ModDamageTypes.causeProjectileBoomDamage(level().registryAccess(), this, this.getOwner()), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), target.getX(), target.getY(), target.getZ(), ExplosionConfig.C4_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); explosion.explode(); net.minecraftforge.event.ForgeEventFactory.onExplosionStart(level(), explosion); @@ -239,11 +209,6 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { return super.getDimensions(p_33597_).scale((float) 0.5); } - @Override - public boolean isPushable() { - return true; - } - @Override public void registerControllers(AnimatableManager.ControllerRegistrar data) { } @@ -252,4 +217,9 @@ public class C4Entity extends Entity implements GeoEntity, OwnableEntity { public AnimatableInstanceCache getAnimatableInstanceCache() { return this.cache; } + + @Override + protected float getGravity() { + return 0; + } } \ No newline at end of file diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/TaserBulletEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/TaserBulletEntity.java index 2cd503fba..87c39abb1 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/projectile/TaserBulletEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/projectile/TaserBulletEntity.java @@ -71,6 +71,10 @@ public class TaserBulletEntity extends AbstractArrow implements GeoEntity { return NetworkHooks.getEntitySpawningPacket(this); } + @Override + public void playerTouch(Player pEntity) { + } + @Override protected ItemStack getPickupItem() { return PROJECTILE_ITEM; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java index 921d58b92..6467e99ee 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/DroneEntity.java @@ -563,11 +563,11 @@ public class DroneEntity extends MobileVehicleEntity implements GeoEntity { Entity attacker = EntityFindUtil.findEntity(this.level(), this.entityData.get(LAST_ATTACKER_UUID)); CustomExplosion explosion = switch (mode) { case 1 -> new CustomExplosion(this.level(), this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), attacker, attacker), ExplosionConfig.DRONE_KAMIKAZE_EXPLOSION_DAMAGE.get(), + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, attacker), ExplosionConfig.DRONE_KAMIKAZE_EXPLOSION_DAMAGE.get(), this.getX(), this.getY(), this.getZ(), ExplosionConfig.DRONE_KAMIKAZE_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); case 2 -> new CustomExplosion(this.level(), this, - ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), attacker, attacker), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), + ModDamageTypes.causeProjectileBoomDamage(this.level().registryAccess(), this, attacker), ExplosionConfig.C4_EXPLOSION_DAMAGE.get(), this.getX(), this.getY(), this.getZ(), ExplosionConfig.C4_EXPLOSION_RADIUS.get(), ExplosionConfig.EXPLOSION_DESTROY.get() ? Explosion.BlockInteraction.DESTROY : Explosion.BlockInteraction.KEEP).setDamageMultiplier(1); default -> null; diff --git a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java index 33e478d7c..d870a05aa 100644 --- a/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java +++ b/src/main/java/com/atsuishio/superbwarfare/entity/vehicle/base/VehicleEntity.java @@ -36,6 +36,7 @@ import net.minecraft.world.damagesource.DamageSource; import net.minecraft.world.damagesource.DamageTypes; import net.minecraft.world.entity.*; import net.minecraft.world.entity.player.Player; +import net.minecraft.world.entity.projectile.AbstractArrow; import net.minecraft.world.entity.projectile.ThrownPotion; import net.minecraft.world.entity.vehicle.DismountHelper; import net.minecraft.world.item.ItemStack; @@ -596,9 +597,21 @@ public abstract class VehicleEntity extends Entity { this.entityData.set(LAST_DRIVER_UUID, getFirstPassenger().getStringUUID()); } + clearArrow(); this.refreshDimensions(); } + public void clearArrow() { + List list = this.level().getEntities(this, this.getBoundingBox().inflate(0F, 0.5F, 0F)); + if (!list.isEmpty()) { + for (Entity entity : list) { + if (entity instanceof AbstractArrow) { + entity.discard(); + } + } + } + } + public void lowHealthWarning() { if (this.getHealth() <= 0.4 * this.getMaxHealth()) { if (this.level() instanceof ServerLevel serverLevel) { diff --git a/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java b/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java index 20d4ef436..6146aeecf 100644 --- a/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java +++ b/src/main/java/com/atsuishio/superbwarfare/item/C4Bomb.java @@ -32,10 +32,9 @@ public class C4Bomb extends Item { } if (!level.isClientSide) { C4Entity entity = new C4Entity(player, level); - entity.moveTo(player.getX(), player.getY() + 1.1, player.getZ(), player.getYRot(), 0); - entity.setYBodyRot(player.getYRot()); - entity.setYHeadRot(player.getYRot()); + entity.setPos(player.getX() + 0.25 * player.getLookAngle().x, player.getEyeY() - 0.2f + 0.25 * player.getLookAngle().y, player.getZ() + 0.25 * player.getLookAngle().z); entity.setDeltaMovement(0.5 * player.getLookAngle().x, 0.5 * player.getLookAngle().y, 0.5 * player.getLookAngle().z); + entity.setOwner(player); level.addFreshEntity(entity); }