From aedd6b180679fb19d3c570fd72aa0dd16668b31e Mon Sep 17 00:00:00 2001 From: Provismet <17149901+Provismet@users.noreply.github.com> Date: Fri, 26 Jan 2024 02:46:22 +0000 Subject: [PATCH] Add boomerang weapon. --- .../assets/additional-armoury/lang/en_us.json | 8 + .../models/item/boomerang.json | 6 + .../asm/BoomerangEnchantmentTarget.java | 23 +++ .../AdditionalArmoury/asm/EarlyRiser.java | 1 + .../boomerang/BoomerangEnchantment.java | 12 ++ .../boomerang/MultiThrowEnchantment.java | 24 +++ .../boomerang/RicochetEnchantment.java | 12 ++ .../entity/BoomerangProjectileEntity.java | 176 ++++++++++++++++++ .../items/BoomerangItem.java | 82 ++++++++ .../registries/AAEnchantmentTargets.java | 1 + .../registries/AAEnchantments.java | 9 + .../registries/AAEntityRenderers.java | 3 + .../registries/AAEntityTypes.java | 13 ++ .../registries/AAItemGroups.java | 1 + .../AdditionalArmoury/registries/AAItems.java | 3 + .../renderers/WorldItemRenderer.java | 48 +++++ .../utility/AADamageSources.java | 5 + .../AdditionalArmoury/LanguageGenerator.java | 5 + .../AdditionalArmoury/ModelGenerator.java | 3 +- .../textures/item/boomerang.png | Bin 0 -> 231 bytes .../damage_type/boomerang.json | 5 + .../tags/damage_type/is_projectile.json | 3 +- 22 files changed, 441 insertions(+), 2 deletions(-) create mode 100644 src/main/generated/assets/additional-armoury/models/item/boomerang.json create mode 100644 src/main/java/com/provismet/AdditionalArmoury/asm/BoomerangEnchantmentTarget.java create mode 100644 src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/BoomerangEnchantment.java create mode 100644 src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/MultiThrowEnchantment.java create mode 100644 src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/RicochetEnchantment.java create mode 100644 src/main/java/com/provismet/AdditionalArmoury/entity/BoomerangProjectileEntity.java create mode 100644 src/main/java/com/provismet/AdditionalArmoury/items/BoomerangItem.java create mode 100644 src/main/java/com/provismet/AdditionalArmoury/renderers/WorldItemRenderer.java create mode 100644 src/main/resources/assets/additional-armoury/textures/item/boomerang.png create mode 100644 src/main/resources/data/additional-armoury/damage_type/boomerang.json diff --git a/src/main/generated/assets/additional-armoury/lang/en_us.json b/src/main/generated/assets/additional-armoury/lang/en_us.json index 4b391f0..27ff8d1 100644 --- a/src/main/generated/assets/additional-armoury/lang/en_us.json +++ b/src/main/generated/assets/additional-armoury/lang/en_us.json @@ -1,4 +1,6 @@ { + "death.attack.boomerang": "%1$s was struck by a boomerang from %2$s", + "death.attack.boomerang.item": "%1$s was struck by a boomerang from %2$s using %3$s", "death.attack.eruption_spell": "%1$s was launched by %2$s", "death.attack.eruption_spell.item": "%1$s was launched by %2$s using %3$s", "death.attack.fireball_spell": "%1$s was blasted by %2$s", @@ -18,8 +20,14 @@ "enchantment.additional-armoury.frostball.desc": "Shoot a frostball that freezes on hit.", "enchantment.additional-armoury.jump": "Soaring", "enchantment.additional-armoury.jump.desc": "Launch into the air and gain slow-fall.", + "enchantment.additional-armoury.multithrow": "MultiThrow", + "enchantment.additional-armoury.multithrow.desc": "Throws 3 boomerangs at once.", + "enchantment.additional-armoury.ricochet": "Ricochet", + "enchantment.additional-armoury.ricochet.desc": "Increases the number of boomerang bounces.", + "entity.additional-armoury.boomerang_projectile": "Boomerang", "entity.additional-armoury.fireball_spell": "Fireball Spell", "entity.additional-armoury.frostball_spell": "Frostball Spell", + "item.additional-armoury.boomerang": "Boomerang", "item.additional-armoury.diamond_dagger": "Diamond Dagger", "item.additional-armoury.diamond_dagger.effect.awkward": "Diamond Dagger", "item.additional-armoury.diamond_dagger.effect.fire_resistance": "Fire Resistance-Tipped Diamond Dagger", diff --git a/src/main/generated/assets/additional-armoury/models/item/boomerang.json b/src/main/generated/assets/additional-armoury/models/item/boomerang.json new file mode 100644 index 0000000..8dd631f --- /dev/null +++ b/src/main/generated/assets/additional-armoury/models/item/boomerang.json @@ -0,0 +1,6 @@ +{ + "parent": "minecraft:item/handheld", + "textures": { + "layer0": "additional-armoury:item/boomerang" + } +} \ No newline at end of file diff --git a/src/main/java/com/provismet/AdditionalArmoury/asm/BoomerangEnchantmentTarget.java b/src/main/java/com/provismet/AdditionalArmoury/asm/BoomerangEnchantmentTarget.java new file mode 100644 index 0000000..d3b5ce9 --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/asm/BoomerangEnchantmentTarget.java @@ -0,0 +1,23 @@ +package com.provismet.AdditionalArmoury.asm; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +import com.provismet.AdditionalArmoury.items.BoomerangItem; + +import net.minecraft.enchantment.EnchantmentTarget; +import net.minecraft.item.Item; + +public class BoomerangEnchantmentTarget extends BoomerangEnchantmentTargetMixin { + @Override + public boolean isAcceptableItem (Item item) { + return item instanceof BoomerangItem; + } +} + + +@Mixin(EnchantmentTarget.class) +abstract class BoomerangEnchantmentTargetMixin { + @Shadow + abstract boolean isAcceptableItem (Item item); +} \ No newline at end of file diff --git a/src/main/java/com/provismet/AdditionalArmoury/asm/EarlyRiser.java b/src/main/java/com/provismet/AdditionalArmoury/asm/EarlyRiser.java index e57992b..c0e9033 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/asm/EarlyRiser.java +++ b/src/main/java/com/provismet/AdditionalArmoury/asm/EarlyRiser.java @@ -13,6 +13,7 @@ public void run () { ClassTinkerers.enumBuilder(enchantmentTarget) .addEnumSubclass("ADDITIONALARMOURY$STAFF", "com.provismet.AdditionalArmoury.asm.StaffEnchantmentTarget") .addEnumSubclass("ADDITIONALARMOURY$DAGGER", "com.provismet.AdditionalArmoury.asm.DaggerEnchantmentTarget") + .addEnumSubclass("ADDITIONALARMOURY$BOOMERANG", "com.provismet.AdditionalArmoury.asm.BoomerangEnchantmentTarget") .build(); } diff --git a/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/BoomerangEnchantment.java b/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/BoomerangEnchantment.java new file mode 100644 index 0000000..7c4dda0 --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/BoomerangEnchantment.java @@ -0,0 +1,12 @@ +package com.provismet.AdditionalArmoury.enchantments.boomerang; + +import com.provismet.AdditionalArmoury.registries.AAEnchantmentTargets; + +import net.minecraft.enchantment.Enchantment; +import net.minecraft.entity.EquipmentSlot; + +public abstract class BoomerangEnchantment extends Enchantment { + protected BoomerangEnchantment (Rarity weight) { + super(weight, AAEnchantmentTargets.BOOMERANG, new EquipmentSlot[] {EquipmentSlot.MAINHAND}); + } +} diff --git a/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/MultiThrowEnchantment.java b/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/MultiThrowEnchantment.java new file mode 100644 index 0000000..b3b6f9a --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/MultiThrowEnchantment.java @@ -0,0 +1,24 @@ +package com.provismet.AdditionalArmoury.enchantments.boomerang; + +import net.minecraft.enchantment.Enchantment; + +public class MultiThrowEnchantment extends BoomerangEnchantment { + public MultiThrowEnchantment () { + super(Rarity.UNCOMMON); + } + + @Override + public int getMinPower (int level) { + return 20; + } + + @Override + public int getMaxPower (int level) { + return 50; + } + + @Override + public boolean canAccept (Enchantment other) { + return super.canAccept(other) && !(other instanceof RicochetEnchantment); + } +} diff --git a/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/RicochetEnchantment.java b/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/RicochetEnchantment.java new file mode 100644 index 0000000..8709b53 --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/enchantments/boomerang/RicochetEnchantment.java @@ -0,0 +1,12 @@ +package com.provismet.AdditionalArmoury.enchantments.boomerang; + +public class RicochetEnchantment extends BoomerangEnchantment { + public RicochetEnchantment () { + super(Rarity.COMMON); + } + + @Override + public int getMaxLevel () { + return 4; + } +} diff --git a/src/main/java/com/provismet/AdditionalArmoury/entity/BoomerangProjectileEntity.java b/src/main/java/com/provismet/AdditionalArmoury/entity/BoomerangProjectileEntity.java new file mode 100644 index 0000000..08e60d3 --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/entity/BoomerangProjectileEntity.java @@ -0,0 +1,176 @@ +package com.provismet.AdditionalArmoury.entity; + +import org.jetbrains.annotations.NotNull; + +import com.provismet.AdditionalArmoury.AdditionalArmouryMain; +import com.provismet.AdditionalArmoury.registries.AAEntityTypes; +import com.provismet.AdditionalArmoury.registries.AAItems; +import com.provismet.AdditionalArmoury.utility.AADamageSources; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityType; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.projectile.ProjectileEntity; +import net.minecraft.entity.projectile.thrown.ThrownItemEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NbtCompound; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.EntityHitResult; +import net.minecraft.util.math.Direction; +import net.minecraft.world.World; + +public class BoomerangProjectileEntity extends ThrownItemEntity { + private static final String RICOCHET_KEY = "ricochet_count"; + private static final String FLIGHT_TIME_KEY = "flight_time"; + private static final String RESETS_COOLDOWN_KEY = "resets_cooldown"; + + protected final int maxTime; + protected int flightTime; + protected int ricochetCount; + + private int ricochetCounterCooldown = 0; + private boolean resetsCooldown = true; + + public BoomerangProjectileEntity (EntityType entityType, World world) { + super(entityType, world); + this.maxTime = 40; + this.flightTime = 0; + this.ricochetCount = 1; + } + + public BoomerangProjectileEntity (World world, @NotNull LivingEntity owner) { + super(AAEntityTypes.BOOMERANG, owner, world); + this.maxTime = 40; + this.flightTime = 0; + this.ricochetCount = 1; + } + + @Override + public void writeCustomDataToNbt (NbtCompound nbt) { + super.writeCustomDataToNbt(nbt); + nbt.putInt(RICOCHET_KEY, this.ricochetCount); + nbt.putInt(FLIGHT_TIME_KEY, this.flightTime); + nbt.putBoolean(RESETS_COOLDOWN_KEY, this.resetsCooldown); + } + + @Override + public void readCustomDataFromNbt (NbtCompound nbt) { + super.readCustomDataFromNbt(nbt); + if (nbt.contains(RICOCHET_KEY)) this.ricochetCount = nbt.getInt(RICOCHET_KEY); + if (nbt.contains(FLIGHT_TIME_KEY)) this.flightTime = nbt.getInt(FLIGHT_TIME_KEY); + if (nbt.contains(RESETS_COOLDOWN_KEY)) this.resetsCooldown = nbt.getBoolean(RESETS_COOLDOWN_KEY); + } + + @Override + public void tick () { + if (!this.getWorld().isClient()) { + if (this.ricochetCount > 0 && ++this.flightTime >= this.maxTime) { + this.ricochet(false, true); + } + if (this.ricochetCounterCooldown > 0) --this.ricochetCounterCooldown; + } + super.tick(); + } + + @Override + protected void onBlockHit (BlockHitResult blockHitResult) { + super.onBlockHit(blockHitResult); + if (!this.getWorld().isClient()) { + if (this.ricochetCount <= 0) this.discard(); + else this.ricochetBlock(blockHitResult.getSide()); + } + } + + @Override + protected void onEntityHit (EntityHitResult entityHitResult) { + super.onEntityHit(entityHitResult); + if (!this.getWorld().isClient()) { + if (this.getOwner() instanceof PlayerEntity player && entityHitResult.getEntity() == player) { + if (this.resetsCooldown) player.getItemCooldownManager().remove(AAItems.BOOMERANG); + this.discard(); + } + else if (!(entityHitResult.getEntity() instanceof ProjectileEntity)) { + if (this.ricochetCount > 0) this.ricochet(); + if (entityHitResult.getEntity() instanceof LivingEntity target) { + target.damage(AADamageSources.boomerang(this, this.getOwner()), 4f); + } + } + } + } + + protected boolean ricochet (boolean doFallback, boolean returnToUser) { + if (this.ricochetCounterCooldown <= 0) { + this.ricochetCounterCooldown = 2; + --this.ricochetCount; + } + this.flightTime = 0; + + if ((this.ricochetCount <= 0 || returnToUser) && this.getOwner() != null) { + this.ricochetCount = 0; + Entity owner = this.getOwner(); + this.setVelocity(owner.getX() - this.getX(), owner.getEyeY() - this.getY(), owner.getZ() - this.getZ(), 1f, 0.5f); + AdditionalArmouryMain.LOGGER.info("Ricochet Count: " + this.ricochetCount + " (player ricochet)"); + return true; + } + else if (doFallback) { + this.setVelocity(-this.getVelocity().getX(), -this.getVelocity().getY(), -this.getVelocity().getZ(), 1f, 1f); + AdditionalArmouryMain.LOGGER.info("Ricochet Count: " + this.ricochetCount + " (used fallback)"); + return true; + } + + AdditionalArmouryMain.LOGGER.info("Ricochet Count: " + this.ricochetCount); + return false; + } + + protected boolean ricochet () { + return this.ricochet(true, false); + } + + protected void ricochetBlock (Direction direction) { + if (!this.ricochet(false, false)) { + switch (direction) { + case UP: + case DOWN: + this.setVelocity(this.getVelocity().getX(), this.getVelocity().getY() * -1, this.getVelocity().getZ(), 1f, 0f); + break; + + case NORTH: + case SOUTH: + this.setVelocity(this.getVelocity().getX(), this.getVelocity().getY(), this.getVelocity().getZ() * -1, 1f, 0f); + break; + + case EAST: + case WEST: + this.setVelocity(this.getVelocity().getX() * -1, this.getVelocity().getY(), this.getVelocity().getZ(), 1f, 0f); + + default: + break; + } + } + } + + @Override + public ItemStack getStack () { + return AAItems.BOOMERANG.getDefaultStack(); + } + + @Override + protected Item getDefaultItem () { + return AAItems.BOOMERANG; + } + + @Override + protected float getGravity () { + return 0.005f; + } + + public void setRicochetCount (int value) { + this.ricochetCount = value; + } + + public void setCanResetCooldown (boolean value) { + this.resetsCooldown = value; + } +} diff --git a/src/main/java/com/provismet/AdditionalArmoury/items/BoomerangItem.java b/src/main/java/com/provismet/AdditionalArmoury/items/BoomerangItem.java new file mode 100644 index 0000000..4ee0ea5 --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/items/BoomerangItem.java @@ -0,0 +1,82 @@ +package com.provismet.AdditionalArmoury.items; + +import com.provismet.AdditionalArmoury.entity.BoomerangProjectileEntity; +import com.provismet.AdditionalArmoury.registries.AAEnchantments; +import com.provismet.AdditionalArmoury.registries.AAItems; + +import net.minecraft.enchantment.EnchantmentHelper; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.item.Vanishable; +import net.minecraft.sound.SoundCategory; +import net.minecraft.sound.SoundEvents; +import net.minecraft.stat.Stats; +import net.minecraft.util.Hand; +import net.minecraft.util.TypedActionResult; +import net.minecraft.util.UseAction; +import net.minecraft.world.World; + +public class BoomerangItem extends Item implements Vanishable { + public BoomerangItem (Settings settings) { + super(settings); + } + + @Override + public UseAction getUseAction (ItemStack stack) { + return UseAction.SPEAR; + } + + @Override + public int getMaxUseTime (ItemStack stack) { + return 72000; + } + + @Override + public TypedActionResult use (World world, PlayerEntity user, Hand hand) { + ItemStack itemStack = user.getStackInHand(hand); + if (itemStack.getDamage() >= itemStack.getMaxDamage() - 1) { + return TypedActionResult.fail(itemStack); + } + user.setCurrentHand(hand); + return TypedActionResult.consume(itemStack); + } + + @Override + public void onStoppedUsing (ItemStack itemStack, World world, LivingEntity user, int remainingUseTicks) { + if (!(user instanceof PlayerEntity)) return; + if (this.getMaxUseTime(itemStack) - remainingUseTicks < 10) return; + + PlayerEntity player = (PlayerEntity)user; + + if (!world.isClient()) { + BoomerangProjectileEntity boomerang = new BoomerangProjectileEntity(world, player); + boomerang.setVelocity(player, player.getPitch(), player.getYaw(), 0f, 1f, 1f); + + int ricochetLevel = 1 + EnchantmentHelper.getLevel(AAEnchantments.RICOCHET, itemStack); + boomerang.setRicochetCount(ricochetLevel); + world.spawnEntity(boomerang); + + int damage = 1 + (EnchantmentHelper.getLevel(AAEnchantments.MULTITHROW, itemStack) > 0 ? 2 : 0); + if (damage > 1) { + for (int i = 0; i < 2; ++i) { + BoomerangProjectileEntity newBoomerang = new BoomerangProjectileEntity(world, player); + newBoomerang.setVelocity(player, player.getPitch(), player.getYaw() + (i == 0 ? 10f : -10f), 0f, 1f, 1f); + newBoomerang.setCanResetCooldown(false); + world.spawnEntity(newBoomerang); + } + } + + itemStack.damage(damage, player, p -> p.sendToolBreakStatus(player.getActiveHand())); + player.getItemCooldownManager().set(AAItems.BOOMERANG, 100); + } + world.playSound(null, player.getX(), player.getY(), player.getZ(), SoundEvents.ENTITY_ARROW_SHOOT, SoundCategory.PLAYERS, 1.0f, 1.0f / (world.getRandom().nextFloat() * 0.4f + 1.2f) + 0.5f); + player.incrementStat(Stats.USED.getOrCreateStat(this)); + } + + @Override + public int getEnchantability () { + return 1; + } +} diff --git a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantmentTargets.java b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantmentTargets.java index 5ce09ff..c66e1fa 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantmentTargets.java +++ b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantmentTargets.java @@ -7,4 +7,5 @@ public class AAEnchantmentTargets { public static final EnchantmentTarget STAFF = ClassTinkerers.getEnum(EnchantmentTarget.class, "ADDITIONALARMOURY$STAFF"); public static final EnchantmentTarget DAGGER = ClassTinkerers.getEnum(EnchantmentTarget.class, "ADDITIONALARMOURY$DAGGER"); + public static final EnchantmentTarget BOOMERANG = ClassTinkerers.getEnum(EnchantmentTarget.class, "ADDITIONALARMOURY$BOOMERANG"); } diff --git a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantments.java b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantments.java index 836d03f..e58e68f 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantments.java +++ b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEnchantments.java @@ -1,6 +1,9 @@ package com.provismet.AdditionalArmoury.registries; import com.provismet.AdditionalArmoury.AdditionalArmouryMain; +import com.provismet.AdditionalArmoury.enchantments.boomerang.BoomerangEnchantment; +import com.provismet.AdditionalArmoury.enchantments.boomerang.MultiThrowEnchantment; +import com.provismet.AdditionalArmoury.enchantments.boomerang.RicochetEnchantment; import com.provismet.AdditionalArmoury.enchantments.dagger.AdhesiveEnchantment; import com.provismet.AdditionalArmoury.enchantments.staff.BoostEnchantment; import com.provismet.AdditionalArmoury.enchantments.staff.EruptionEnchantment; @@ -22,6 +25,9 @@ public class AAEnchantments { public static final AdhesiveEnchantment ADHESIVE = new AdhesiveEnchantment(); + public static final BoomerangEnchantment RICOCHET = new RicochetEnchantment(); + public static final BoomerangEnchantment MULTITHROW = new MultiThrowEnchantment(); + private static void register (String name, Enchantment enchantment) { Registry.register(Registries.ENCHANTMENT, AdditionalArmouryMain.identifier(name), enchantment); } @@ -34,5 +40,8 @@ public static void register () { register("frostball", FROSTBALL); register("adhesive", ADHESIVE); + + register("ricochet", RICOCHET); + register("multithrow", MULTITHROW); } } diff --git a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityRenderers.java b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityRenderers.java index 43541d4..5e48081 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityRenderers.java +++ b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityRenderers.java @@ -1,5 +1,7 @@ package com.provismet.AdditionalArmoury.registries; +import com.provismet.AdditionalArmoury.renderers.WorldItemRenderer; + import net.fabricmc.api.EnvType; import net.fabricmc.api.Environment; import net.fabricmc.fabric.api.client.rendering.v1.EntityRendererRegistry; @@ -10,5 +12,6 @@ public class AAEntityRenderers { public static void register () { EntityRendererRegistry.register(AAEntityTypes.FIREBALL, FlyingItemEntityRenderer::new); EntityRendererRegistry.register(AAEntityTypes.FROSTBALL, FlyingItemEntityRenderer::new); + EntityRendererRegistry.register(AAEntityTypes.BOOMERANG, FlyingItemEntityRenderer::new); } } diff --git a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityTypes.java b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityTypes.java index 252aa4b..0eaeb79 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityTypes.java +++ b/src/main/java/com/provismet/AdditionalArmoury/registries/AAEntityTypes.java @@ -2,10 +2,12 @@ import com.provismet.AdditionalArmoury.AdditionalArmouryMain; import com.provismet.AdditionalArmoury.entity.AbstractSpellEntity; +import com.provismet.AdditionalArmoury.entity.BoomerangProjectileEntity; import com.provismet.AdditionalArmoury.entity.FireballSpellEntity; import com.provismet.AdditionalArmoury.entity.FrostballSpellEntity; import net.fabricmc.fabric.api.object.builder.v1.entity.FabricEntityTypeBuilder; +import net.minecraft.entity.Entity; import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityType; import net.minecraft.entity.SpawnGroup; @@ -15,6 +17,7 @@ public class AAEntityTypes { public static final EntityType FIREBALL = AAEntityTypes.buildSpell(FireballSpellEntity::new, "fireball_spell"); public static final EntityType FROSTBALL = AAEntityTypes.buildSpell(FrostballSpellEntity::new, "frostball_spell"); + public static final EntityType BOOMERANG = AAEntityTypes.buildEntity(BoomerangProjectileEntity::new, "boomerang_projectile", EntityDimensions.fixed(0.25f, 0.25f)); private static EntityType buildSpell (EntityType.EntityFactory factory, String name) { return Registry.register( @@ -28,6 +31,16 @@ private static EntityType buildSpell (EntityT ); } + private static EntityType buildEntity (EntityType.EntityFactory factory, String name, EntityDimensions dimensions) { + return Registry.register( + Registries.ENTITY_TYPE, + AdditionalArmouryMain.identifier(name), + FabricEntityTypeBuilder.create(SpawnGroup.MISC, factory) + .dimensions(dimensions) + .build() + ); + } + // Exists purely to force the variables to load. public static void register () { diff --git a/src/main/java/com/provismet/AdditionalArmoury/registries/AAItemGroups.java b/src/main/java/com/provismet/AdditionalArmoury/registries/AAItemGroups.java index be45a00..ed12252 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/registries/AAItemGroups.java +++ b/src/main/java/com/provismet/AdditionalArmoury/registries/AAItemGroups.java @@ -28,6 +28,7 @@ public static void register () { ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(content -> content.addAfter(AAItems.ENDERNETHER_SWORD, AAItems.DAGGERS.toArray(new DaggerItem[0]))); ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(content -> content.addAfter(AAItems.ENDERNETHER_AXE, AAItems.MACES.toArray(new MaceItem[0]))); ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(content -> content.addAfter(Items.TRIDENT, AAItems.STAFF)); + ItemGroupEvents.modifyEntriesEvent(ItemGroups.COMBAT).register(content -> content.addAfter(Items.CROSSBOW, AAItems.BOOMERANG)); ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS).register(content -> content.addAfter(Items.NETHERITE_INGOT, AAItems.OVERNETHER_INGOT, AAItems.ENDERNETHER_INGOT)); ItemGroupEvents.modifyEntriesEvent(ItemGroups.INGREDIENTS).register(content -> content.addAfter(Items.NETHERITE_UPGRADE_SMITHING_TEMPLATE, AAItems.OVERNETHER_UPGRADE_SMITHING_TEMPLATE, AAItems.ENDERNETHER_UPGRADE_SMITHING_TEMPLATE)); diff --git a/src/main/java/com/provismet/AdditionalArmoury/registries/AAItems.java b/src/main/java/com/provismet/AdditionalArmoury/registries/AAItems.java index 64325f0..d6d9c31 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/registries/AAItems.java +++ b/src/main/java/com/provismet/AdditionalArmoury/registries/AAItems.java @@ -13,6 +13,7 @@ import com.provismet.AdditionalArmoury.items.AAExtraSwordItem; import com.provismet.AdditionalArmoury.items.AASmithingTemplateItem; import com.provismet.AdditionalArmoury.items.AAToolMaterials; +import com.provismet.AdditionalArmoury.items.BoomerangItem; import com.provismet.AdditionalArmoury.items.DaggerItem; import com.provismet.AdditionalArmoury.items.MaceItem; import com.provismet.AdditionalArmoury.items.StaffItem; @@ -78,6 +79,7 @@ public class AAItems { public static final ArmorItem ENDERNETHER_BOOTS = new AAExtraArmourItem(AAArmourMaterials.ENDERNETHER, ArmorItem.Type.BOOTS, new FabricItemSettings().maxCount(1).fireproof()); public static final StaffItem STAFF = new StaffItem(new FabricItemSettings().maxCount(1)); + public static final BoomerangItem BOOMERANG = new BoomerangItem(new FabricItemSettings().maxCount(1).maxDamage(256)); // Projectile Items (these exist so that magic projectiles can use them for rendering, they are not obtainable in survival) public static final FireballItem FIREBALL = new FireballItem(new FabricItemSettings().fireproof()); @@ -141,6 +143,7 @@ public static void register () { register(ENDERNETHER_BOOTS, "endernether_boots"); register(STAFF, "staff"); + register(BOOMERANG, "boomerang"); register(FIREBALL, "fireball_spell"); register(FROSTBALL, "frostball_spell"); diff --git a/src/main/java/com/provismet/AdditionalArmoury/renderers/WorldItemRenderer.java b/src/main/java/com/provismet/AdditionalArmoury/renderers/WorldItemRenderer.java new file mode 100644 index 0000000..871c50e --- /dev/null +++ b/src/main/java/com/provismet/AdditionalArmoury/renderers/WorldItemRenderer.java @@ -0,0 +1,48 @@ +package com.provismet.AdditionalArmoury.renderers; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; +import net.minecraft.client.render.OverlayTexture; +import net.minecraft.client.render.VertexConsumerProvider; +import net.minecraft.client.render.entity.EntityRenderer; +import net.minecraft.client.render.entity.EntityRendererFactory.Context; +import net.minecraft.client.render.item.ItemRenderer; +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.render.model.json.ModelTransformationMode; +import net.minecraft.client.texture.SpriteAtlasTexture; +import net.minecraft.client.util.math.MatrixStack; +import net.minecraft.entity.Entity; +import net.minecraft.entity.FlyingItemEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.util.Identifier; + +@Environment(EnvType.CLIENT) +public class WorldItemRenderer extends EntityRenderer { + private final ItemRenderer itemRenderer; + + public WorldItemRenderer (Context ctx) { + super(ctx); + this.itemRenderer = ctx.getItemRenderer(); + } + + @Override + public void render (T entity, float yaw, float tickDelta, MatrixStack matrices, VertexConsumerProvider vertexConsumers, int light) { + ItemStack itemStack; + if (entity instanceof FlyingItemEntity itemEntity) itemStack = itemEntity.getStack(); + else return; + + matrices.push(); + // TODO: render it somehow. Go see how ItemEntityRenderer::render works. + BakedModel model = this.itemRenderer.getModel(itemStack, entity.getWorld(), null, entity.getId()); + this.itemRenderer.renderItem(itemStack, ModelTransformationMode.GROUND, false, matrices, vertexConsumers, light, OverlayTexture.DEFAULT_UV, model); + matrices.pop(); + + super.render(entity, yaw, tickDelta, matrices, vertexConsumers, light); + } + + @Override + @SuppressWarnings("deprecation") + public Identifier getTexture (T entity) { + return SpriteAtlasTexture.BLOCK_ATLAS_TEXTURE; + } +} diff --git a/src/main/java/com/provismet/AdditionalArmoury/utility/AADamageSources.java b/src/main/java/com/provismet/AdditionalArmoury/utility/AADamageSources.java index 1126602..26c416c 100644 --- a/src/main/java/com/provismet/AdditionalArmoury/utility/AADamageSources.java +++ b/src/main/java/com/provismet/AdditionalArmoury/utility/AADamageSources.java @@ -15,6 +15,7 @@ public class AADamageSources { private static final RegistryKey FIREBALL = createDamageType("fireball_spell"); private static final RegistryKey FROSTBALL = createDamageType("frostball_spell"); private static final RegistryKey ERUPTION = createDamageType("eruption_spell"); + private static final RegistryKey BOOMERANG = createDamageType("boomerang"); public static DamageSource fireball (Entity source, @Nullable Entity attacker) { return AADamageSources.create(source.getDamageSources(), FIREBALL, source, attacker); @@ -28,6 +29,10 @@ public static DamageSource eruption (Entity attacker) { return AADamageSources.create(attacker.getDamageSources(), ERUPTION, attacker); } + public static DamageSource boomerang (Entity source, @Nullable Entity attacker) { + return AADamageSources.create(source.getDamageSources(), BOOMERANG, source, attacker); + } + @SuppressWarnings("unused") private static DamageSource create (DamageSources sources, RegistryKey damageType) { return sources.create(damageType); diff --git a/src/main/java/com/provismet/datagen/AdditionalArmoury/LanguageGenerator.java b/src/main/java/com/provismet/datagen/AdditionalArmoury/LanguageGenerator.java index 92fb288..f229388 100644 --- a/src/main/java/com/provismet/datagen/AdditionalArmoury/LanguageGenerator.java +++ b/src/main/java/com/provismet/datagen/AdditionalArmoury/LanguageGenerator.java @@ -75,12 +75,14 @@ public void generateTranslations (TranslationBuilder translationBuilder) { translationBuilder.add(AAItems.STAFF, "Unenchanted Staff"); translationBuilder.add(AAItems.STAFF.getTranslationKey() + ".enchanted", "Enchanted Staff"); + translationBuilder.add(AAItems.BOOMERANG, "Boomerang"); translationBuilder.add(AAItems.FIREBALL, "Fireball"); translationBuilder.add(AAItems.FROSTBALL, "Frostball"); translationBuilder.add(AAEntityTypes.FIREBALL, "Fireball Spell"); translationBuilder.add(AAEntityTypes.FROSTBALL, "Frostball Spell"); + translationBuilder.add(AAEntityTypes.BOOMERANG, "Boomerang"); translationBuilder.add(AAStatusEffects.SHATTERED, "Shattered"); @@ -90,10 +92,13 @@ public void generateTranslations (TranslationBuilder translationBuilder) { LanguageGenerator.addEnchantment(translationBuilder, AAEnchantments.FIREBALL, "Fireball", "Shoot a fireball that burns on hit."); LanguageGenerator.addEnchantment(translationBuilder, AAEnchantments.FROSTBALL, "Frostball", "Shoot a frostball that freezes on hit."); LanguageGenerator.addEnchantment(translationBuilder, AAEnchantments.ADHESIVE, "Adhesive", "Potion-tipped daggers have unlimited uses."); + LanguageGenerator.addEnchantment(translationBuilder, AAEnchantments.RICOCHET, "Ricochet", "Increases the number of boomerang bounces."); + LanguageGenerator.addEnchantment(translationBuilder, AAEnchantments.MULTITHROW, "MultiThrow", "Throws 3 boomerangs at once."); LanguageGenerator.addAttackDeathMessage(translationBuilder, "fireball_spell", "was blasted by"); LanguageGenerator.addAttackDeathMessage(translationBuilder, "frostball_spell", "was frozen by"); LanguageGenerator.addAttackDeathMessage(translationBuilder, "eruption_spell", "was launched by"); + LanguageGenerator.addAttackDeathMessage(translationBuilder, "boomerang", "was struck by a boomerang from"); translationBuilder.add("tooltip.additional-armoury.dagger_uses", "Remaining Splashes: %1$s"); } diff --git a/src/main/java/com/provismet/datagen/AdditionalArmoury/ModelGenerator.java b/src/main/java/com/provismet/datagen/AdditionalArmoury/ModelGenerator.java index a22a389..892033d 100644 --- a/src/main/java/com/provismet/datagen/AdditionalArmoury/ModelGenerator.java +++ b/src/main/java/com/provismet/datagen/AdditionalArmoury/ModelGenerator.java @@ -49,7 +49,8 @@ public void generateItemModels (ItemModelGenerator itemModelGenerator) { AAItems.ENDERNETHER_AXE, AAItems.ENDERNETHER_PICKAXE, AAItems.ENDERNETHER_SHOVEL, - AAItems.ENDERNETHER_HOE + AAItems.ENDERNETHER_HOE, + AAItems.BOOMERANG ); AAItems.DAGGERS.forEach(dagger -> ModelGenerator.registerDagger(itemModelGenerator, dagger)); diff --git a/src/main/resources/assets/additional-armoury/textures/item/boomerang.png b/src/main/resources/assets/additional-armoury/textures/item/boomerang.png new file mode 100644 index 0000000000000000000000000000000000000000..341d58365dca7296a3b2c81644f30fddc5b9f0e2 GIT binary patch literal 231 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbKJV{wqX6T`Z5GB1G~mUKs7M+SzC z{oH>NS%G~10G|+74LR=4bai!;8V2EdpxEZbh)F<-wIs+d_&*RZ{NBa~GKjOlBeIx* zf$uN~Gak=hkpdJ9@N{tu(Fo4%59DKTWN{AsZvT1PjWs!Y&b04yJoM=}hj46ZiQqw% zix*`JCI__L6Fb^t@VQ=hZ5!Vsv8ZoFB`FMsoiR