add homing tnt & implement custom abstract tnt class + custom renderer

This commit is contained in:
Jenny 2025-01-21 14:26:27 +01:00
parent 41a939cc48
commit 095e3d4e8b
Signed by: Jenny
GPG Key ID: 4A98012FB1C39311
12 changed files with 317 additions and 15 deletions

View File

@ -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()));
}
}
}

View File

@ -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;

View File

@ -40,7 +40,10 @@ public class blocks {
public static final RegistryObject<Block> 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<Item> 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<Block> TNT_HOMING= BLOCKS.register("tnt_homing", () -> new homingTNTBlock(BlockBehaviour.Properties.of().mapColor(MapColor.COLOR_RED), 4.0f, 80, 1));
public static final RegistryObject<Item> 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);
}

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);
}
}

View File

@ -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<Integer> DATA_FUSE_ID = SynchedEntityData.defineId(BasePrimedTNT.class, EntityDataSerializers.INT);
private static final EntityDataAccessor<Float> DATA_POWER_ID = SynchedEntityData.defineId(BasePrimedTNT.class, EntityDataSerializers.FLOAT);
public BasePrimedTNT(EntityType<? extends BasePrimedTNT> 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"));
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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<BasePrimedTNT> {
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;
}
}

View File

@ -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<EntityType<?>> ENTITY_TYPES =
DeferredRegister.create(ForgeRegistries.ENTITY_TYPES, MODID);
public static final RegistryObject<EntityType<homingPrimedTNT>> TNT_HOMING =
ENTITY_TYPES.register("tnt_homing", () -> EntityType.Builder.<homingPrimedTNT>of(homingPrimedTNT::new, MobCategory.MISC)
.sized(2.5f, 2.5f).build("tnt_homing"));
public static void register(IEventBus eventBus) {
ENTITY_TYPES.register(eventBus);
}
}

View File

@ -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<homingPrimedTNT> 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;
}
}