diff --git a/src/main/java/com/jenny/compressedtnt/Compressedtnt.java b/src/main/java/com/jenny/compressedtnt/Compressedtnt.java index ff58b8d..2ae7aae 100644 --- a/src/main/java/com/jenny/compressedtnt/Compressedtnt.java +++ b/src/main/java/com/jenny/compressedtnt/Compressedtnt.java @@ -1,12 +1,10 @@ package com.jenny.compressedtnt; -import com.jenny.compressedtnt.blocks.*; - +import com.jenny.compressedtnt.blocks.blocks; +import com.jenny.compressedtnt.entities.client.BaseTNTRenderer; +import com.jenny.compressedtnt.entities.entities; import com.mojang.logging.LogUtils; -import net.minecraft.core.registries.Registries; -import net.minecraft.network.chat.Component; -import net.minecraft.world.item.CreativeModeTab; -import net.minecraft.world.item.CreativeModeTabs; +import net.minecraft.client.renderer.entity.EntityRenderers; import net.minecraftforge.api.distmarker.Dist; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.event.BuildCreativeModeTabContentsEvent; @@ -17,8 +15,6 @@ import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.event.lifecycle.FMLClientSetupEvent; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext; -import net.minecraftforge.registries.DeferredRegister; -import net.minecraftforge.registries.RegistryObject; import org.slf4j.Logger; // The value here should match an entry in the META-INF/mods.toml file @@ -35,8 +31,9 @@ public class Compressedtnt { modEventBus.addListener(this::commonSetup); - new blocks().register(modEventBus); - new creativeTab().register(modEventBus); + blocks.register(modEventBus); + creativeTab.register(modEventBus); + entities.register(modEventBus); // Register ourselves for server and other game events we are interested in MinecraftForge.EVENT_BUS.register(this); @@ -66,7 +63,7 @@ public class Compressedtnt { @SubscribeEvent public static void onClientSetup(FMLClientSetupEvent event) { - + EntityRenderers.register(entities.TNT_HOMING.get(), pContext -> new BaseTNTRenderer(pContext, blocks.TNT_HOMING.get())); } } } \ No newline at end of file diff --git a/src/main/java/com/jenny/compressedtnt/blocks/ClusterTNTBlock.java b/src/main/java/com/jenny/compressedtnt/blocks/ClusterTNTBlock.java index 54ee9ff..eeec61a 100644 --- a/src/main/java/com/jenny/compressedtnt/blocks/ClusterTNTBlock.java +++ b/src/main/java/com/jenny/compressedtnt/blocks/ClusterTNTBlock.java @@ -1,5 +1,6 @@ package com.jenny.compressedtnt.blocks; +import com.jenny.compressedtnt.entities.ClusterPrimedTNT; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.sounds.SoundEvents; diff --git a/src/main/java/com/jenny/compressedtnt/blocks/blocks.java b/src/main/java/com/jenny/compressedtnt/blocks/blocks.java index 52742d0..e9f6772 100644 --- a/src/main/java/com/jenny/compressedtnt/blocks/blocks.java +++ b/src/main/java/com/jenny/compressedtnt/blocks/blocks.java @@ -40,7 +40,10 @@ public class blocks { public static final RegistryObject TNT_CLUSTER_8 = BLOCKS.register("tnt_cluster_8", () -> new ClusterTNTBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED), 4.0f, 80, 8, 10)); public static final RegistryObject TNT_CLUSTER_8_ITEM = ITEMS.register("tnt_cluster_8", () -> new BlockItem(TNT_CLUSTER_8.get(), new Item.Properties())); - public void register(IEventBus bus) { + public static final RegistryObject TNT_HOMING= BLOCKS.register("tnt_homing", () -> new homingTNTBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED), 4.0f, 80, 1)); + public static final RegistryObject TNT_HOMING_ITEM = ITEMS.register("tnt_homing", () -> new BlockItem(TNT_HOMING.get(), new Item.Properties())); + + public static void register(IEventBus bus) { BLOCKS.register(bus); ITEMS.register(bus); } diff --git a/src/main/java/com/jenny/compressedtnt/blocks/homingTNTBlock.java b/src/main/java/com/jenny/compressedtnt/blocks/homingTNTBlock.java new file mode 100644 index 0000000..f098a5b --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/blocks/homingTNTBlock.java @@ -0,0 +1,49 @@ +package com.jenny.compressedtnt.blocks; + +import com.jenny.compressedtnt.entities.homingPrimedTNT; +import net.minecraft.core.BlockPos; +import net.minecraft.core.Direction; +import net.minecraft.sounds.SoundEvents; +import net.minecraft.sounds.SoundSource; +import net.minecraft.world.entity.LivingEntity; +import net.minecraft.world.entity.player.Player; +import net.minecraft.world.level.Level; +import net.minecraft.world.level.block.TntBlock; +import net.minecraft.world.level.block.state.BlockBehaviour; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.gameevent.GameEvent; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; + +public class homingTNTBlock extends TntBlock { + public final float pRadius, speed; + public final int fuseTime; + + public homingTNTBlock(BlockBehaviour.Properties p_57422_, float pRadius, int fuseTime, float speed) { + super(p_57422_); + this.pRadius = pRadius; + this.fuseTime = fuseTime; + this.speed = speed; + } + + + public void onCaughtFire(@NotNull BlockState state, @NotNull Level world, @NotNull BlockPos pos, @Nullable Direction face, @Nullable LivingEntity igniter) { + explode(world, pos, igniter, this.pRadius, this.fuseTime, this.speed); + } + + @Deprecated + public static void explode(Level p_57434_, BlockPos p_57435_, float pRadius, int fuseTime, float speed) { + explode(p_57434_, p_57435_, (LivingEntity)null, pRadius, fuseTime, speed); + } + + @Deprecated + private static void explode(Level level, BlockPos blockPos, @Nullable LivingEntity entity, float pRadius, int fuseTime, float speed) { + if (!level.isClientSide) { + homingPrimedTNT primedtnt = new homingPrimedTNT(level, (double)blockPos.getX() + (double)0.5F, (double)blockPos.getY(), (double)blockPos.getZ() + (double)0.5F, entity, pRadius, fuseTime, speed); + level.addFreshEntity(primedtnt); + level.playSound((Player)null, primedtnt.getX(), primedtnt.getY(), primedtnt.getZ(), SoundEvents.TNT_PRIMED, SoundSource.BLOCKS, 1.0F, 1.0F); + level.gameEvent(entity, GameEvent.PRIME_FUSE, blockPos); + } + } +} diff --git a/src/main/java/com/jenny/compressedtnt/blocks/strongerTNTBlock.java b/src/main/java/com/jenny/compressedtnt/blocks/strongerTNTBlock.java index b0296e2..7709e65 100644 --- a/src/main/java/com/jenny/compressedtnt/blocks/strongerTNTBlock.java +++ b/src/main/java/com/jenny/compressedtnt/blocks/strongerTNTBlock.java @@ -1,5 +1,6 @@ package com.jenny.compressedtnt.blocks; +import com.jenny.compressedtnt.entities.StrongerPrimedTNT; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.sounds.SoundEvents; diff --git a/src/main/java/com/jenny/compressedtnt/creativeTab.java b/src/main/java/com/jenny/compressedtnt/creativeTab.java index 6ddaca0..ffdc146 100644 --- a/src/main/java/com/jenny/compressedtnt/creativeTab.java +++ b/src/main/java/com/jenny/compressedtnt/creativeTab.java @@ -23,9 +23,10 @@ public class creativeTab { output.accept(blocks.TNT_CLUSTER_2.get()); output.accept(blocks.TNT_CLUSTER_4.get()); output.accept(blocks.TNT_CLUSTER_8.get()); + output.accept(blocks.TNT_HOMING.get()); }).title(Component.literal("Compressed TNT")).build()); - public void register(IEventBus bus) { + public static void register(IEventBus bus) { CREATIVE_MODE_TABS.register(bus); } } diff --git a/src/main/java/com/jenny/compressedtnt/entities/BasePrimedTNT.java b/src/main/java/com/jenny/compressedtnt/entities/BasePrimedTNT.java new file mode 100644 index 0000000..4503b26 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/entities/BasePrimedTNT.java @@ -0,0 +1,94 @@ +package com.jenny.compressedtnt.entities; + +import net.minecraft.core.particles.ParticleTypes; +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.world.entity.Entity; +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MoverType; +import net.minecraft.world.entity.TraceableEntity; +import net.minecraft.world.level.Level; + +public abstract class BasePrimedTNT extends Entity implements TraceableEntity { + private static final EntityDataAccessor DATA_FUSE_ID = SynchedEntityData.defineId(BasePrimedTNT.class, EntityDataSerializers.INT); + private static final EntityDataAccessor DATA_POWER_ID = SynchedEntityData.defineId(BasePrimedTNT.class, EntityDataSerializers.FLOAT); + + public BasePrimedTNT(EntityType pEntityType, Level pLevel) { + super(pEntityType, pLevel); + double d0 = pLevel.random.nextDouble() * (double)((float)Math.PI * 2F); + this.setDeltaMovement(-Math.sin(d0) * 0.02D, (double)0.2F, -Math.cos(d0) * 0.02D); + this.blocksBuilding = true; + } + + protected void explode() { + this.level().explode(this, this.getX(), this.getY(0.0625D), this.getZ(), this.getPower(), Level.ExplosionInteraction.TNT); + } + + public int getFuse() { + return this.entityData.get(DATA_FUSE_ID); + } + + public void setFuse(int fuse) { + this.entityData.set(DATA_FUSE_ID, fuse); + } + + public float getPower() { + return this.entityData.get(DATA_POWER_ID); + } + + public void setPower(float power) { + this.entityData.set(DATA_POWER_ID, power); + } + + public void tick() { + if (!this.isNoGravity()) { + this.setDeltaMovement(this.getDeltaMovement().add(0.0D, -0.04D, 0.0D)); + } + + this.move(MoverType.SELF, this.getDeltaMovement()); + this.setDeltaMovement(this.getDeltaMovement().scale(0.98D)); + if (this.onGround()) { + this.setDeltaMovement(this.getDeltaMovement().multiply(0.7D, -0.5D, 0.7D)); + } + + int i = this.getFuse() - 1; + this.setFuse(i); + if (i <= 0) { + this.discard(); + if (!this.level().isClientSide) { + this.explode(); + } + } else { + this.updateInWaterStateAndDoFluidPushing(); + if (this.level().isClientSide) { + this.level().addParticle(ParticleTypes.SMOKE, this.getX(), this.getY() + 0.5D, this.getZ(), 0.0D, 0.0D, 0.0D); + } + } + } + + public boolean isPickable() { + return !this.isRemoved(); + } + + protected Entity.MovementEmission getMovementEmission() { + return Entity.MovementEmission.NONE; + } + + + protected void defineSynchedData() { + this.entityData.define(DATA_FUSE_ID, 80); + this.entityData.define(DATA_POWER_ID, 4.0f); + } + + protected void addAdditionalSaveData(CompoundTag pCompound) { + pCompound.putShort("Fuse", (short)this.getFuse()); + pCompound.putFloat("Power", (short)this.getPower()); + } + + protected void readAdditionalSaveData(CompoundTag pCompound) { + this.setFuse(pCompound.getShort("Fuse")); + this.setPower(pCompound.getFloat("Power")); + } +} diff --git a/src/main/java/com/jenny/compressedtnt/blocks/ClusterPrimedTNT.java b/src/main/java/com/jenny/compressedtnt/entities/ClusterPrimedTNT.java similarity index 95% rename from src/main/java/com/jenny/compressedtnt/blocks/ClusterPrimedTNT.java rename to src/main/java/com/jenny/compressedtnt/entities/ClusterPrimedTNT.java index 4ac6e27..c82cebc 100644 --- a/src/main/java/com/jenny/compressedtnt/blocks/ClusterPrimedTNT.java +++ b/src/main/java/com/jenny/compressedtnt/entities/ClusterPrimedTNT.java @@ -1,4 +1,4 @@ -package com.jenny.compressedtnt.blocks; +package com.jenny.compressedtnt.entities; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.PrimedTnt; diff --git a/src/main/java/com/jenny/compressedtnt/blocks/StrongerPrimedTNT.java b/src/main/java/com/jenny/compressedtnt/entities/StrongerPrimedTNT.java similarity index 94% rename from src/main/java/com/jenny/compressedtnt/blocks/StrongerPrimedTNT.java rename to src/main/java/com/jenny/compressedtnt/entities/StrongerPrimedTNT.java index 9b2d048..37cd7ec 100644 --- a/src/main/java/com/jenny/compressedtnt/blocks/StrongerPrimedTNT.java +++ b/src/main/java/com/jenny/compressedtnt/entities/StrongerPrimedTNT.java @@ -1,4 +1,4 @@ -package com.jenny.compressedtnt.blocks; +package com.jenny.compressedtnt.entities; import net.minecraft.world.entity.LivingEntity; import net.minecraft.world.entity.item.PrimedTnt; diff --git a/src/main/java/com/jenny/compressedtnt/entities/client/BaseTNTRenderer.java b/src/main/java/com/jenny/compressedtnt/entities/client/BaseTNTRenderer.java new file mode 100644 index 0000000..d58051b --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/entities/client/BaseTNTRenderer.java @@ -0,0 +1,53 @@ +package com.jenny.compressedtnt.entities.client; + +import com.jenny.compressedtnt.blocks.blocks; +import com.jenny.compressedtnt.entities.BasePrimedTNT; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.math.Axis; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.renderer.entity.EntityRenderer; +import net.minecraft.client.renderer.entity.EntityRendererProvider; +import net.minecraft.client.renderer.entity.TntMinecartRenderer; +import net.minecraft.client.renderer.texture.TextureAtlas; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.Mth; +import net.minecraft.world.level.block.Block; + +public class BaseTNTRenderer extends EntityRenderer { + private final BlockRenderDispatcher blockRenderer; + + public BaseTNTRenderer(EntityRendererProvider.Context pContext, Block block) { + super(pContext); + this.shadowRadius = 0.5F; + this.blockRenderer = pContext.getBlockRenderDispatcher(); + } + + public void render(BasePrimedTNT pEntity, float pEntityYaw, float pPartialTicks, PoseStack pPoseStack, MultiBufferSource pBuffer, int pPackedLight) { + pPoseStack.pushPose(); + pPoseStack.translate(0.0F, 0.5F, 0.0F); + int i = pEntity.getFuse(); + if ((float)i - pPartialTicks + 1.0F < 10.0F) { + float f = 1.0F - ((float)i - pPartialTicks + 1.0F) / 10.0F; + f = Mth.clamp(f, 0.0F, 1.0F); + f *= f; + f *= f; + float f1 = 1.0F + f * 0.3F; + pPoseStack.scale(f1, f1, f1); + } + + pPoseStack.mulPose(Axis.YP.rotationDegrees(-90.0F)); + pPoseStack.translate(-0.5F, -0.5F, 0.5F); + pPoseStack.mulPose(Axis.YP.rotationDegrees(90.0F)); + TntMinecartRenderer.renderWhiteSolidBlock(this.blockRenderer, blocks.TNT_HOMING.get().defaultBlockState(), pPoseStack, pBuffer, pPackedLight, i / 5 % 2 == 0); + pPoseStack.popPose(); + super.render(pEntity, pEntityYaw, pPartialTicks, pPoseStack, pBuffer, pPackedLight); + } + + /** + * Returns the location of an entity's texture. + */ + public ResourceLocation getTextureLocation(BasePrimedTNT pEntity) { + return TextureAtlas.LOCATION_BLOCKS; + } +} diff --git a/src/main/java/com/jenny/compressedtnt/entities/entities.java b/src/main/java/com/jenny/compressedtnt/entities/entities.java new file mode 100644 index 0000000..c8a3637 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/entities/entities.java @@ -0,0 +1,23 @@ +package com.jenny.compressedtnt.entities; + +import net.minecraft.world.entity.EntityType; +import net.minecraft.world.entity.MobCategory; +import net.minecraftforge.eventbus.api.IEventBus; +import net.minecraftforge.registries.DeferredRegister; +import net.minecraftforge.registries.ForgeRegistries; +import net.minecraftforge.registries.RegistryObject; + +import static com.jenny.compressedtnt.Compressedtnt.MODID; + +public class entities { + public static final DeferredRegister> ENTITY_TYPES = + DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MODID); + + public static final RegistryObject> TNT_HOMING = + ENTITY_TYPES.register("tnt_homing", () -> EntityType.Builder.of(homingPrimedTNT::new, MobCategory.MISC) + .sized(2.5f, 2.5f).build("tnt_homing")); + + public static void register(IEventBus eventBus) { + ENTITY_TYPES.register(eventBus); + } +} diff --git a/src/main/java/com/jenny/compressedtnt/entities/homingPrimedTNT.java b/src/main/java/com/jenny/compressedtnt/entities/homingPrimedTNT.java new file mode 100644 index 0000000..7b06527 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/entities/homingPrimedTNT.java @@ -0,0 +1,80 @@ +package com.jenny.compressedtnt.entities; + +import net.minecraft.world.entity.*; +import net.minecraft.world.entity.ai.targeting.TargetingConditions; +import net.minecraft.world.level.Level; +import net.minecraft.world.phys.AABB; +import net.minecraft.world.phys.Vec3; +import org.jetbrains.annotations.NotNull; + +import javax.annotation.Nullable; + +public class homingPrimedTNT extends BasePrimedTNT { + float pRadius = 0; + float speed = 0; + Entity target; + + @Nullable + private LivingEntity owner; + + public homingPrimedTNT (Level pLevel, double pX, double pY, double pZ, @Nullable LivingEntity pOwner, float power, int fuse, float speed) { + this(entities.TNT_HOMING.get(), pLevel); + this.setPos(pX, pY, pZ); + this.owner = pOwner; + this.pRadius = power; + this.speed = speed; + this.target = null; + this.setPower(power); + this.setFuse(fuse); + } + + public homingPrimedTNT(EntityType entityType, Level level) { + super(entityType, level); + } + + private Vec3 targetVector() { + double targetDist = getTargetDist(); + Vec3 targetVec = new Vec3(0, 0, 0); + if (targetDist > 3) { + targetVec = new Vec3(target.getX() - this.getX(), target.getY() - this.getY(), target.getZ() - this.getZ()).normalize().multiply(speed, speed, speed); + if (targetDist < 10) { + targetVec.multiply(targetDist / 10, targetDist / 10, targetDist / 10); + } + } + return targetVec; + } + + public double getTargetDist() { + return new Vec3(target.getX(), target.getY(), target.getZ()).subtract(this.getX(), this.getY(), this.getZ()).length(); + } + + public void findTarget() { + Vec3 corner1 = this.position().subtract(15, 15, 15); + Vec3 corner2 = this.position().add(15, 15, 15); + AABB boundingBox = new AABB(corner1, corner2); + target = this.level().getNearestEntity(LivingEntity.class, TargetingConditions.forNonCombat(), null, this.getX(), this.getY(), this.getZ(), boundingBox); + + } + + @Override + public void tick() { + if (target == null) { + findTarget(); + } + else { + if (getTargetDist() > 15) {target = null;} else {addDeltaMovement(targetVector());} + } + + super.tick(); + } + + + @Nullable + public LivingEntity getOwner() { + return this.owner; + } + + protected float getEyeHeight(@NotNull Pose pPose, @NotNull EntityDimensions pSize) { + return 0.15F; + } +}