diff --git a/gradle.properties b/gradle.properties index 9ea3e74..56441ae 100644 --- a/gradle.properties +++ b/gradle.properties @@ -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 diff --git a/src/main/java/com/jenny/compressedtnt/Compressedtnt.java b/src/main/java/com/jenny/compressedtnt/Compressedtnt.java index 9ecc41f..327e0c9 100644 --- a/src/main/java/com/jenny/compressedtnt/Compressedtnt.java +++ b/src/main/java/com/jenny/compressedtnt/Compressedtnt.java @@ -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); diff --git a/src/main/java/com/jenny/compressedtnt/creativeTab.java b/src/main/java/com/jenny/compressedtnt/creativeTab.java index 5bb4827..567330f 100644 --- a/src/main/java/com/jenny/compressedtnt/creativeTab.java +++ b/src/main/java/com/jenny/compressedtnt/creativeTab.java @@ -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) { diff --git a/src/main/java/com/jenny/compressedtnt/datagen/DataGenerators.java b/src/main/java/com/jenny/compressedtnt/datagen/DataGenerators.java index 790ee06..1bc0aea 100644 --- a/src/main/java/com/jenny/compressedtnt/datagen/DataGenerators.java +++ b/src/main/java/com/jenny/compressedtnt/datagen/DataGenerators.java @@ -22,5 +22,6 @@ public class DataGenerators { CompletableFuture lookupProvider = event.getLookupProvider(); generator.addProvider(event.includeClient(), new ModBlockStateProvider(packOutput, existingFileHelper)); + generator.addProvider(event.includeClient(), new ModItemModelProvider(packOutput, existingFileHelper)); } } \ No newline at end of file diff --git a/src/main/java/com/jenny/compressedtnt/datagen/ModItemModelProvider.java b/src/main/java/com/jenny/compressedtnt/datagen/ModItemModelProvider.java new file mode 100644 index 0000000..3b25395 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/datagen/ModItemModelProvider.java @@ -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) { + return withExistingParent(item.getId().getPath(), + new ResourceLocation("item/generated")).texture("layer0", + new ResourceLocation(MODID,"item/" + item.getId().getPath())); + } +} diff --git a/src/main/java/com/jenny/compressedtnt/entities/client/TNTArrowRenderer.java b/src/main/java/com/jenny/compressedtnt/entities/client/TNTArrowRenderer.java new file mode 100644 index 0000000..c563b66 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/entities/client/TNTArrowRenderer.java @@ -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 { + 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; + } +} diff --git a/src/main/java/com/jenny/compressedtnt/entities/entities.java b/src/main/java/com/jenny/compressedtnt/entities/entities.java index 77d61ee..9653382 100644 --- a/src/main/java/com/jenny/compressedtnt/entities/entities.java +++ b/src/main/java/com/jenny/compressedtnt/entities/entities.java @@ -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.of(claymorePrimedTNT::new, MobCategory.MISC) .sized(0.98F, 0.7F).fireImmune().clientTrackingRange(8).build("tnt_claymore")); + public static final RegistryObject> ARROW_TNT = + ENTITY_TYPES.register("arrow_tnt", () -> EntityType.Builder.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); } } \ No newline at end of file diff --git a/src/main/java/com/jenny/compressedtnt/items/arrows/entity/EntityArrowBase.java b/src/main/java/com/jenny/compressedtnt/items/arrows/entity/EntityArrowBase.java new file mode 100644 index 0000000..9a4a9fb --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/items/arrows/entity/EntityArrowBase.java @@ -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 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 effects = Sets.newHashSet(); + private boolean fixedColor; + + public EntityArrowBase(EntityType pEntityType, Level pLevel) { + super(pEntityType, pLevel); + } + + public EntityArrowBase(Level pLevel, double pX, double pY, double pZ, EntityType pEntityType) { + super(pEntityType, pX, pY, pZ, pLevel); + } + + public EntityArrowBase(Level pLevel, LivingEntity pShooter, EntityType pEntityType) { + super(pEntityType, pShooter, pLevel); + } + + public void setEffectsFromItem(ItemStack pStack) { + if (pStack.is(Items.TIPPED_ARROW)) { + this.potion = PotionUtils.getPotion(pStack); + Collection 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); + } + + } +} diff --git a/src/main/java/com/jenny/compressedtnt/items/arrows/entity/EntityArrowTNT.java b/src/main/java/com/jenny/compressedtnt/items/arrows/entity/EntityArrowTNT.java new file mode 100644 index 0000000..87f6cbc --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/items/arrows/entity/EntityArrowTNT.java @@ -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 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()); + } +} diff --git a/src/main/java/com/jenny/compressedtnt/items/arrows/item/ArrowTNT.java b/src/main/java/com/jenny/compressedtnt/items/arrows/item/ArrowTNT.java new file mode 100644 index 0000000..bf0c437 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/items/arrows/item/ArrowTNT.java @@ -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); + } +} diff --git a/src/main/java/com/jenny/compressedtnt/items/items.java b/src/main/java/com/jenny/compressedtnt/items/items.java new file mode 100644 index 0000000..3c54900 --- /dev/null +++ b/src/main/java/com/jenny/compressedtnt/items/items.java @@ -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 ITEMS = DeferredRegister.create(ForgeRegistries.ITEMS, MODID); + + public static final RegistryObject TNT_ARROW = ITEMS.register("arrow_tnt", () -> new ArrowTNT(new Item.Properties())); + + public static void register(IEventBus bus) { + ITEMS.register(bus); + } +} diff --git a/src/main/resources/assets/compressedtnt/textures/item/arrow_tnt.png b/src/main/resources/assets/compressedtnt/textures/item/arrow_tnt.png new file mode 100644 index 0000000..12e2d4f Binary files /dev/null and b/src/main/resources/assets/compressedtnt/textures/item/arrow_tnt.png differ diff --git a/src/main/resources/data/compressedtnt/recipes/arrow_tnt.json b/src/main/resources/data/compressedtnt/recipes/arrow_tnt.json new file mode 100644 index 0000000..88e7e17 --- /dev/null +++ b/src/main/resources/data/compressedtnt/recipes/arrow_tnt.json @@ -0,0 +1,15 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "redstone", + "ingredients":[ + { + "item": "minecraft:arrow" + }, + { + "item": "minecraft:tnt" + } + ], + "result": { + "item": "compressedtnt:arrow_tnt" + } +} \ No newline at end of file diff --git a/src/main/resources/data/minecraft/tags/items/arrows.json b/src/main/resources/data/minecraft/tags/items/arrows.json new file mode 100644 index 0000000..87508ec --- /dev/null +++ b/src/main/resources/data/minecraft/tags/items/arrows.json @@ -0,0 +1,5 @@ +{ + "values": [ + "compressedtnt:arrow_tnt" + ] +} \ No newline at end of file