add tnt arrow & implement ItemModelProvider

This commit is contained in:
Jenny 2025-01-23 22:19:04 +01:00
parent 8b5c7b53a5
commit db9309d9d8
Signed by: Jenny
GPG Key ID: 4A98012FB1C39311
14 changed files with 423 additions and 2 deletions

View File

@ -38,7 +38,7 @@ mod_name=Compressed TNT
# The license of the mod. Review your options at https://choosealicense.com/. All Rights Reserved is the default.
mod_license=All Rights Reserved
# The mod version. See https://semver.org/
mod_version=0.3.0
mod_version=0.4.0
# The group ID for the mod. It is only important when publishing as an artifact to a Maven repository.
# This should match the base package used for the mod sources.
# See https://maven.apache.org/guides/mini/guide-naming-conventions.html

View File

@ -2,6 +2,7 @@ package com.jenny.compressedtnt;
import com.jenny.compressedtnt.blocks.blocks;
import com.jenny.compressedtnt.entities.entities;
import com.jenny.compressedtnt.items.items;
import com.mojang.logging.LogUtils;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
@ -29,6 +30,7 @@ public class Compressedtnt {
modEventBus.addListener(this::commonSetup);
blocks.register(modEventBus);
items.register(modEventBus);
creativeTab.register(modEventBus);
entities.register(modEventBus);

View File

@ -1,6 +1,7 @@
package com.jenny.compressedtnt;
import com.jenny.compressedtnt.blocks.blocks;
import com.jenny.compressedtnt.items.items;
import net.minecraft.core.registries.Registries;
import net.minecraft.network.chat.Component;
@ -26,6 +27,7 @@ public class creativeTab {
output.accept(blocks.TNT_HOMING.get());
output.accept(blocks.TNT_BLACK_HOLE.get());
output.accept(blocks.TNT_CLAYMORE.get());
output.accept(items.TNT_ARROW.get());
}).title(Component.literal("Compressed TNT")).build());
public static void register(IEventBus bus) {

View File

@ -22,5 +22,6 @@ public class DataGenerators {
CompletableFuture<HolderLookup.Provider> lookupProvider = event.getLookupProvider();
generator.addProvider(event.includeClient(), new ModBlockStateProvider(packOutput, existingFileHelper));
generator.addProvider(event.includeClient(), new ModItemModelProvider(packOutput, existingFileHelper));
}
}

View File

@ -0,0 +1,30 @@
package com.jenny.compressedtnt.datagen;
import com.jenny.compressedtnt.items.items;
import net.minecraft.data.PackOutput;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.item.Item;
import net.minecraftforge.client.model.generators.ItemModelBuilder;
import net.minecraftforge.client.model.generators.ItemModelProvider;
import net.minecraftforge.common.data.ExistingFileHelper;
import net.minecraftforge.registries.RegistryObject;
import static com.jenny.compressedtnt.Compressedtnt.MODID;
public class ModItemModelProvider extends ItemModelProvider {
public ModItemModelProvider(PackOutput output, ExistingFileHelper existingFileHelper) {
super(output, MODID, existingFileHelper);
}
@Override
protected void registerModels() {
simpleItem(items.TNT_ARROW);
}
private ItemModelBuilder simpleItem(RegistryObject<Item> item) {
return withExistingParent(item.getId().getPath(),
new ResourceLocation("item/generated")).texture("layer0",
new ResourceLocation(MODID,"item/" + item.getId().getPath()));
}
}

View File

@ -0,0 +1,45 @@
package com.jenny.compressedtnt.entities.client;
import com.jenny.compressedtnt.items.arrows.entity.EntityArrowTNT;
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.world.entity.projectile.Arrow;
import net.minecraft.world.level.block.Blocks;
import org.jetbrains.annotations.NotNull;
public class TNTArrowRenderer extends EntityRenderer<EntityArrowTNT> {
private final BlockRenderDispatcher blockRenderer;
private float i = 0;
public TNTArrowRenderer(EntityRendererProvider.Context pContext) {
super(pContext);
this.shadowRadius = 0.0F;
this.blockRenderer = pContext.getBlockRenderDispatcher();
}
public void render(@NotNull EntityArrowTNT pEntity, float pEntityYaw, float pPartialTicks, PoseStack pPoseStack, @NotNull MultiBufferSource pBuffer, int pPackedLight) {
pPoseStack.pushPose();
pPoseStack.translate(0.0F, 0.5F, 0.0F);
pPoseStack.scale(0.5f, 0.5f, 0.5f);
i += 0.1f;
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.defaultBlockState(), pPoseStack, pBuffer, pPackedLight, Math.round(Math.sin(i)) == 0);
pPoseStack.popPose();
super.render(pEntity, pEntityYaw, pPartialTicks, pPoseStack, pBuffer, pPackedLight);
}
@NotNull
public ResourceLocation getTextureLocation(@NotNull EntityArrowTNT pEntity) {
return TextureAtlas.LOCATION_BLOCKS;
}
}

View File

@ -1,8 +1,13 @@
package com.jenny.compressedtnt.entities;
import com.jenny.compressedtnt.entities.client.BaseTNTRenderer;
import com.jenny.compressedtnt.entities.client.TNTArrowRenderer;
import com.jenny.compressedtnt.entities.client.clusterTNTRenderer;
import com.jenny.compressedtnt.items.arrows.entity.*;
import net.minecraft.client.renderer.entity.ArrowRenderer;
import net.minecraft.client.renderer.entity.EntityRenderers;
import net.minecraft.client.renderer.entity.TippableArrowRenderer;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.MobCategory;
import net.minecraftforge.eventbus.api.IEventBus;
@ -36,6 +41,10 @@ public class entities {
ENTITY_TYPES.register("tnt_claymore", () -> EntityType.Builder.<claymorePrimedTNT>of(claymorePrimedTNT::new, MobCategory.MISC)
.sized(0.98F, 0.7F).fireImmune().clientTrackingRange(8).build("tnt_claymore"));
public static final RegistryObject<EntityType<EntityArrowTNT>> ARROW_TNT =
ENTITY_TYPES.register("arrow_tnt", () -> EntityType.Builder.<EntityArrowTNT>of(EntityArrowTNT::new, MobCategory.MISC)
.sized(0.48F, 0.48F).clientTrackingRange(64).build("arrow_tnt"));
public static void register(IEventBus eventBus) {
ENTITY_TYPES.register(eventBus);
}
@ -46,6 +55,6 @@ public class entities {
EntityRenderers.register(TNT_BLACK_HOLE.get(), BaseTNTRenderer::new);
EntityRenderers.register(TNT_CLUSTER.get(), clusterTNTRenderer::new);
EntityRenderers.register(ARROW_TNT.get(), TNTArrowRenderer::new);
}
}

View File

@ -0,0 +1,228 @@
package com.jenny.compressedtnt.items.arrows.entity;
import com.google.common.collect.Sets;
import net.minecraft.core.particles.ParticleTypes;
import net.minecraft.core.registries.BuiltInRegistries;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.nbt.ListTag;
import net.minecraft.network.syncher.EntityDataAccessor;
import net.minecraft.network.syncher.EntityDataSerializers;
import net.minecraft.network.syncher.SynchedEntityData;
import net.minecraft.world.effect.MobEffectInstance;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.alchemy.Potion;
import net.minecraft.world.item.alchemy.PotionUtils;
import net.minecraft.world.item.alchemy.Potions;
import net.minecraft.world.level.Level;
import java.util.Collection;
import java.util.Set;
public class EntityArrowBase extends AbstractArrow {
private static final int EXPOSED_POTION_DECAY_TIME = 600;
private static final int NO_EFFECT_COLOR = -1;
private static final EntityDataAccessor<Integer> ID_EFFECT_COLOR = SynchedEntityData.defineId(EntityArrowBase.class, EntityDataSerializers.INT);
private static final byte EVENT_POTION_PUFF = 0;
private Potion potion = Potions.EMPTY;
private final Set<MobEffectInstance> effects = Sets.newHashSet();
private boolean fixedColor;
public EntityArrowBase(EntityType<? extends EntityArrowBase> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}
public EntityArrowBase(Level pLevel, double pX, double pY, double pZ, EntityType<? extends EntityArrowBase> pEntityType) {
super(pEntityType, pX, pY, pZ, pLevel);
}
public EntityArrowBase(Level pLevel, LivingEntity pShooter, EntityType<? extends EntityArrowBase> pEntityType) {
super(pEntityType, pShooter, pLevel);
}
public void setEffectsFromItem(ItemStack pStack) {
if (pStack.is(Items.TIPPED_ARROW)) {
this.potion = PotionUtils.getPotion(pStack);
Collection<MobEffectInstance> collection = PotionUtils.getCustomEffects(pStack);
if (!collection.isEmpty()) {
for(MobEffectInstance mobeffectinstance : collection) {
this.effects.add(new MobEffectInstance(mobeffectinstance));
}
}
int i = getCustomColor(pStack);
if (i == -1) {
this.updateColor();
} else {
this.setFixedColor(i);
}
} else if (pStack.is(Items.ARROW)) {
this.potion = Potions.EMPTY;
this.effects.clear();
this.entityData.set(ID_EFFECT_COLOR, -1);
}
}
public static int getCustomColor(ItemStack pStack) {
CompoundTag compoundtag = pStack.getTag();
return compoundtag != null && compoundtag.contains("CustomPotionColor", 99) ? compoundtag.getInt("CustomPotionColor") : -1;
}
private void updateColor() {
this.fixedColor = false;
if (this.potion == Potions.EMPTY && this.effects.isEmpty()) {
this.entityData.set(ID_EFFECT_COLOR, -1);
} else {
this.entityData.set(ID_EFFECT_COLOR, PotionUtils.getColor(PotionUtils.getAllEffects(this.potion, this.effects)));
}
}
public void addEffect(MobEffectInstance pEffectInstance) {
this.effects.add(pEffectInstance);
this.getEntityData().set(ID_EFFECT_COLOR, PotionUtils.getColor(PotionUtils.getAllEffects(this.potion, this.effects)));
}
protected void defineSynchedData() {
super.defineSynchedData();
this.entityData.define(ID_EFFECT_COLOR, -1);
}
public void tick() {
super.tick();
if (this.level().isClientSide) {
if (this.inGround) {
if (this.inGroundTime % 5 == 0) {
this.makeParticle(1);
}
} else {
this.makeParticle(2);
}
} else if (this.inGround && this.inGroundTime != 0 && !this.effects.isEmpty() && this.inGroundTime >= 600) {
this.level().broadcastEntityEvent(this, (byte)0);
this.potion = Potions.EMPTY;
this.effects.clear();
this.entityData.set(ID_EFFECT_COLOR, -1);
}
}
private void makeParticle(int pParticleAmount) {
int i = this.getColor();
if (i != -1 && pParticleAmount > 0) {
double d0 = (double)(i >> 16 & 255) / 255.0D;
double d1 = (double)(i >> 8 & 255) / 255.0D;
double d2 = (double)(i >> 0 & 255) / 255.0D;
for(int j = 0; j < pParticleAmount; ++j) {
this.level().addParticle(ParticleTypes.ENTITY_EFFECT, this.getRandomX(0.5D), this.getRandomY(), this.getRandomZ(0.5D), d0, d1, d2);
}
}
}
public int getColor() {
return this.entityData.get(ID_EFFECT_COLOR);
}
private void setFixedColor(int pFixedColor) {
this.fixedColor = true;
this.entityData.set(ID_EFFECT_COLOR, pFixedColor);
}
public void addAdditionalSaveData(CompoundTag pCompound) {
super.addAdditionalSaveData(pCompound);
if (this.potion != Potions.EMPTY) {
pCompound.putString("Potion", BuiltInRegistries.POTION.getKey(this.potion).toString());
}
if (this.fixedColor) {
pCompound.putInt("Color", this.getColor());
}
if (!this.effects.isEmpty()) {
ListTag listtag = new ListTag();
for(MobEffectInstance mobeffectinstance : this.effects) {
listtag.add(mobeffectinstance.save(new CompoundTag()));
}
pCompound.put("CustomPotionEffects", listtag);
}
}
public void readAdditionalSaveData(CompoundTag pCompound) {
super.readAdditionalSaveData(pCompound);
if (pCompound.contains("Potion", 8)) {
this.potion = PotionUtils.getPotion(pCompound);
}
for(MobEffectInstance mobeffectinstance : PotionUtils.getCustomEffects(pCompound)) {
this.addEffect(mobeffectinstance);
}
if (pCompound.contains("Color", 99)) {
this.setFixedColor(pCompound.getInt("Color"));
} else {
this.updateColor();
}
}
protected void doPostHurtEffects(LivingEntity pLiving) {
super.doPostHurtEffects(pLiving);
Entity entity = this.getEffectSource();
for(MobEffectInstance mobeffectinstance : this.potion.getEffects()) {
pLiving.addEffect(new MobEffectInstance(mobeffectinstance.getEffect(), Math.max(mobeffectinstance.mapDuration((p_268168_) -> {
return p_268168_ / 8;
}), 1), mobeffectinstance.getAmplifier(), mobeffectinstance.isAmbient(), mobeffectinstance.isVisible()), entity);
}
if (!this.effects.isEmpty()) {
for(MobEffectInstance mobeffectinstance1 : this.effects) {
pLiving.addEffect(mobeffectinstance1, entity);
}
}
}
protected ItemStack getPickupItem() {
if (this.effects.isEmpty() && this.potion == Potions.EMPTY) {
return new ItemStack(Items.ARROW);
} else {
ItemStack itemstack = new ItemStack(Items.TIPPED_ARROW);
PotionUtils.setPotion(itemstack, this.potion);
PotionUtils.setCustomEffects(itemstack, this.effects);
if (this.fixedColor) {
itemstack.getOrCreateTag().putInt("CustomPotionColor", this.getColor());
}
return itemstack;
}
}
public void handleEntityEvent(byte pId) {
if (pId == 0) {
int i = this.getColor();
if (i != -1) {
double d0 = (double)(i >> 16 & 255) / 255.0D;
double d1 = (double)(i >> 8 & 255) / 255.0D;
double d2 = (double)(i >> 0 & 255) / 255.0D;
for(int j = 0; j < 20; ++j) {
this.level().addParticle(ParticleTypes.ENTITY_EFFECT, this.getRandomX(0.5D), this.getRandomY(), this.getRandomZ(0.5D), d0, d1, d2);
}
}
} else {
super.handleEntityEvent(pId);
}
}
}

View File

@ -0,0 +1,39 @@
package com.jenny.compressedtnt.items.arrows.entity;
import com.jenny.compressedtnt.items.items;
import com.jenny.compressedtnt.entities.entities;
import net.minecraft.world.entity.EntityType;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
public class EntityArrowTNT extends EntityArrowBase {
public EntityArrowTNT(EntityType<EntityArrowTNT> pEntityType, Level pLevel) {
super(pEntityType, pLevel);
}
public EntityArrowTNT(Level pLevel, LivingEntity pShooter) {
super(pLevel, pShooter, entities.ARROW_TNT.get());
}
@Override
public void tick() {
super.tick();
if (this.inGround) {
this.level().explode(this, this.getX(), this.getY(), this.getZ(), 2, Level.ExplosionInteraction.TNT);
this.discard();
}
}
@Override
protected void doPostHurtEffects(LivingEntity pTarget) {
this.level().explode(this, this.getX(), this.getY(), this.getZ(), 2, Level.ExplosionInteraction.TNT);
}
@NotNull
protected ItemStack getPickupItem() {
return new ItemStack(items.TNT_ARROW.get());
}
}

View File

@ -0,0 +1,23 @@
package com.jenny.compressedtnt.items.arrows.item;
import com.jenny.compressedtnt.items.arrows.entity.EntityArrowTNT;
import net.minecraft.world.entity.LivingEntity;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.entity.projectile.Arrow;
import net.minecraft.world.item.ArrowItem;
import net.minecraft.world.item.Item;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.level.Level;
import org.jetbrains.annotations.NotNull;
public class ArrowTNT extends ArrowItem {
public ArrowTNT(Item.Properties properties){
super(properties);
}
@Override
@NotNull
public AbstractArrow createArrow(Level pLevel, ItemStack pStack, LivingEntity pShooter) {
return new EntityArrowTNT(pLevel, pShooter);
}
}

View File

@ -0,0 +1,22 @@
package com.jenny.compressedtnt.items;
import com.jenny.compressedtnt.items.arrows.item.*;
import net.minecraft.world.item.ArrowItem;
import net.minecraft.world.item.Item;
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 items {
public static final DeferredRegister<Item> ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID);
public static final RegistryObject<Item> TNT_ARROW = ITEMS.register("arrow_tnt", () -> new ArrowTNT(new Item.Properties()));
public static void register(IEventBus bus) {
ITEMS.register(bus);
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 196 B

View File

@ -0,0 +1,15 @@
{
"type": "minecraft:crafting_shapeless",
"category": "redstone",
"ingredients":[
{
"item": "minecraft:arrow"
},
{
"item": "minecraft:tnt"
}
],
"result": {
"item": "compressedtnt:arrow_tnt"
}
}

View File

@ -0,0 +1,5 @@
{
"values": [
"compressedtnt:arrow_tnt"
]
}