diff --git a/src/main/java/com/minelittlepony/unicopia/UTags.java b/src/main/java/com/minelittlepony/unicopia/UTags.java index fb924166..c6ba480c 100644 --- a/src/main/java/com/minelittlepony/unicopia/UTags.java +++ b/src/main/java/com/minelittlepony/unicopia/UTags.java @@ -29,6 +29,7 @@ public interface UTags { TagKey FLOATS_ON_CLOUDS = item("floats_on_clouds"); TagKey POLEARMS = item("polearms"); + TagKey HORSE_SHOES = item("horse_shoes"); TagKey APPLE_SEEDS = item("apple_seeds"); TagKey ACORNS = item("acorns"); diff --git a/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java b/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java new file mode 100644 index 00000000..a7899e8d --- /dev/null +++ b/src/main/java/com/minelittlepony/unicopia/item/HorseShoeItem.java @@ -0,0 +1,112 @@ +package com.minelittlepony.unicopia.item; + +import java.util.List; + +import org.jetbrains.annotations.Nullable; + +import com.google.common.collect.ImmutableMultimap; +import com.google.common.collect.Multimap; +import com.minelittlepony.unicopia.Race; +import com.minelittlepony.unicopia.USounds; +import com.minelittlepony.unicopia.Unicopia; +import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; +import com.minelittlepony.unicopia.entity.player.Pony; +import com.minelittlepony.unicopia.projectile.PhysicsBodyProjectileEntity; + +import net.minecraft.client.item.TooltipContext; +import net.minecraft.entity.EquipmentSlot; +import net.minecraft.entity.attribute.EntityAttribute; +import net.minecraft.entity.attribute.EntityAttributeModifier; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.sound.SoundEvent; +import net.minecraft.text.Text; +import net.minecraft.util.Formatting; +import net.minecraft.world.World; + +public class HorseShoeItem extends HeavyProjectileItem { + + private final float projectileInnacuracy; + private final float baseProjectileSpeed; + + private final Multimap attributeModifiers; + + public HorseShoeItem(Settings settings, float projectileDamage, float projectileInnacuracy, float baseProjectileSpeed) { + super(settings, projectileDamage); + this.projectileInnacuracy = projectileInnacuracy; + this.baseProjectileSpeed = baseProjectileSpeed; + + ImmutableMultimap.Builder builder = ImmutableMultimap.builder(); + builder.put(UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(PolearmItem.ATTACK_RANGE_MODIFIER_ID, "Weapon modifier", -3F, EntityAttributeModifier.Operation.ADDITION)); + attributeModifiers = builder.build(); + } + + @Override + public boolean canRepair(ItemStack stack, ItemStack ingredient) { + return ingredient.isOf(this); + } + + @Override + public void appendTooltip(ItemStack stack, @Nullable World world, List tooltip, TooltipContext context) { + float degradation = (stack.getDamage() / (float)stack.getMaxDamage()); + float inaccuracy = projectileInnacuracy + degradation * 30; + tooltip.add(Text.empty()); + + Pony pony = Unicopia.SIDE.getPony().orElse(null); + float speed = baseProjectileSpeed; + if (pony != null) { + var race = pony.getCompositeRace(); + + if (race.any(Race::canUseEarth)) { + speed += 0.5F; + } + if (!race.includes(Race.ALICORN) && race.physical().canFly()) { + speed /= 1.5F; + } + + } + speed /= 1.5F; + speed *= 1 - (0.6F * degradation); + + tooltip.add(Text.translatable("item.unicopia.horse_shoe.accuracy", 100 * (30 - inaccuracy) / 30).formatted(Formatting.GRAY)); + tooltip.add(Text.translatable("item.unicopia.horse_shoe.speed", Math.max(0.2F, speed)).formatted(Formatting.GRAY)); + } + + @Override + protected PhysicsBodyProjectileEntity createProjectile(ItemStack stack, World world, @Nullable PlayerEntity player) { + PhysicsBodyProjectileEntity projectile = super.createProjectile(stack, world, player); + + float degradation = (stack.getDamage() / (float)stack.getMaxDamage()); + + if (player != null) { + Pony pony = Pony.of(player); + var race = pony.getCompositeRace(); + float speed = baseProjectileSpeed + 0.1F; + if (race.any(Race::canUseEarth)) { + speed += 0.5F; + } + if (!race.includes(Race.ALICORN) && race.physical().canFly()) { + speed /= 1.5F; + } + speed /= 1.5F; + speed *= 1 - (0.6F * degradation); + float inaccuracy = projectileInnacuracy + degradation * 30; + projectile.setVelocity(player, player.getPitch(), player.getYaw(), 0, Math.max(0.2F, speed), inaccuracy); + } + return projectile; + } + + @Override + protected SoundEvent getThrowSound(ItemStack stack) { + return USounds.Vanilla.ITEM_TRIDENT_THROW; + } + + @Override + public Multimap getAttributeModifiers(EquipmentSlot slot) { + if (slot == EquipmentSlot.MAINHAND) { + return attributeModifiers; + } + return super.getAttributeModifiers(slot); + } + +} diff --git a/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java b/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java index 2658cb01..a7f430c4 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/PolearmItem.java @@ -15,7 +15,7 @@ import net.minecraft.entity.attribute.*; import net.minecraft.item.*; public class PolearmItem extends SwordItem { - protected static final UUID ATTACK_RANGE_MODIFIER_ID = UUID.fromString("A7B3659C-AA74-469C-963A-09A391DCAA0F"); + static final UUID ATTACK_RANGE_MODIFIER_ID = UUID.fromString("A7B3659C-AA74-469C-963A-09A391DCAA0F"); private final Multimap attributeModifiers; diff --git a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java index 767d098c..5e7a643d 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/ProjectileItem.java @@ -40,7 +40,7 @@ abstract class ProjectileItem extends Item { 0.4F / (world.random.nextFloat() * 0.4F + 0.8F)); if (!world.isClient) { - world.spawnEntity(createProjectile(stack, world, player)); + world.spawnEntity(createProjectile(stack.copyWithCount(1), world, player)); } player.incrementStat(Stats.USED.getOrCreateStat(this)); diff --git a/src/main/java/com/minelittlepony/unicopia/item/UItems.java b/src/main/java/com/minelittlepony/unicopia/item/UItems.java index 9604ea65..8da9d346 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/UItems.java +++ b/src/main/java/com/minelittlepony/unicopia/item/UItems.java @@ -127,6 +127,11 @@ public interface UItems { Item MEADOWBROOKS_STAFF = register("meadowbrooks_staff", new StaffItem(new Settings().rarity(Rarity.UNCOMMON).maxCount(1).maxDamage(120)), ItemGroups.TOOLS); Item MAGIC_STAFF = register("magic_staff", new EnchantedStaffItem(new Settings().rarity(Rarity.UNCOMMON).maxCount(1).maxDamage(120)), ItemGroups.TOOLS); + Item IRON_HORSE_SHOE = register("iron_horse_shoe", new HorseShoeItem(new Item.Settings().maxDamage(200), 4, 0.6F, 1), ItemGroups.COMBAT); + Item GOLDEN_HORSE_SHOE = register("golden_horse_shoe", new HorseShoeItem(new Item.Settings().maxDamage(100), 5, 0.1F, 0.5F), ItemGroups.COMBAT); + Item COPPER_HORSE_SHOE = register("copper_horse_shoe", new HorseShoeItem(new Item.Settings().maxDamage(250), 6, 0.5F, 0.8F), ItemGroups.COMBAT); + Item NETHERITE_HORSE_SHOE = register("netherite_horse_shoe", new HorseShoeItem(new Item.Settings().maxDamage(800), 3, 0.7F, 1.2F), ItemGroups.COMBAT); + Item WOODEN_POLEARM = register("wooden_polearm", new PolearmItem(ToolMaterials.WOOD, 2, -3.6F, 2, new Item.Settings()), ItemGroups.COMBAT); Item STONE_POLEARM = register("stone_polearm", new PolearmItem(ToolMaterials.STONE, 2, -3.6F, 2, new Item.Settings()), ItemGroups.COMBAT); Item IRON_POLEARM = register("iron_polearm", new PolearmItem(ToolMaterials.IRON, 2, -3.6F, 3, new Item.Settings()), ItemGroups.COMBAT); diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java index 93eb890f..13d49ce9 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/PhysicsBodyProjectileEntity.java @@ -7,7 +7,6 @@ import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.entity.damage.UDamageTypes; import com.minelittlepony.unicopia.entity.mob.UEntities; - import net.minecraft.block.BlockState; import net.minecraft.block.ButtonBlock; import net.minecraft.block.HopperBlock; @@ -131,6 +130,16 @@ public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity impl setYaw(getYaw() + 180); prevYaw += 180; return; + } else { + ItemStack stack = asItemStack(); + if (stack.isIn(UTags.HORSE_SHOES)) { + if (stack.damage(1 + random.nextInt(10), random, null)) { + playSound(USounds.Vanilla.ENTITY_ITEM_BREAK, 1, 1); + } else { + dropStack(stack); + } + setStack(ItemStack.EMPTY); + } } super.onEntityHit(hit); } @@ -221,12 +230,28 @@ public class PhysicsBodyProjectileEntity extends PersistentProjectileEntity impl } setSound(state.getSoundGroup().getStepSound()); - getWorld().playSoundFromEntity(null, this, state.getSoundGroup().getStepSound(), SoundCategory.BLOCKS, 1, 1); emitGameEvent(GameEvent.STEP); + + if (!isBouncy()) { + if (stack.isIn(UTags.HORSE_SHOES)) { + if (stack.damage(1 + random.nextInt(10), random, null)) { + playSound(USounds.Vanilla.ENTITY_ITEM_BREAK, 1, 1); + discard(); + return; + } + } + + getWorld().playSoundFromEntity(null, this, getHitSound(), SoundCategory.BLOCKS, 0.6F, 1); + } else { + getWorld().playSoundFromEntity(null, this, state.getSoundGroup().getStepSound(), SoundCategory.BLOCKS, 1, 1); + } } @Override protected SoundEvent getHitSound() { + if (getStack().isIn(UTags.HORSE_SHOES)) { + return USounds.Vanilla.ITEM_TRIDENT_HIT_GROUND; + } return isBouncy() ? USounds.ITEM_MUFFIN_BOUNCE.value() : USounds.ITEM_ROCK_LAND; } diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index b8ee61f3..59154b94 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -141,6 +141,13 @@ "item.unicopia.alicorn_amulet": "Alicorn Amulet", "item.unicopia.alicorn_amulet.lore": "Time worn: %d", + "item.unicopia.horse_shoe.accuracy": "Accuracy: %d%%", + "item.unicopia.horse_shoe.speed": "Speed: %d", + "item.unicopia.iron_horse_shoe": "Iron Horse Shoe", + "item.unicopia.golden_horse_shoe": "Golden Horse Shoe", + "item.unicopia.copper_horse_shoe": "Copper Horse Shoe", + "item.unicopia.netherite_horse_shoe": "Netherite Horse Shoe", + "item.unicopia.broken_alicorn_amulet": "Broken Alicorn Amulet", "item.unicopia.unicorn_amulet": "Unicorn Amulet", "item.unicopia.unicorn_amulet.lore": "Grants magical abilities to whoever wears it", diff --git a/src/main/resources/assets/unicopia/models/item/copper_horse_shoe.json b/src/main/resources/assets/unicopia/models/item/copper_horse_shoe.json new file mode 100644 index 00000000..a395cc95 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/copper_horse_shoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/copper_horse_shoe" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/golden_horse_shoe.json b/src/main/resources/assets/unicopia/models/item/golden_horse_shoe.json new file mode 100644 index 00000000..0b035f8a --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/golden_horse_shoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/golden_horse_shoe" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/iron_horse_shoe.json b/src/main/resources/assets/unicopia/models/item/iron_horse_shoe.json new file mode 100644 index 00000000..1d8fc483 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/iron_horse_shoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/iron_horse_shoe" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/netherite_horse_shoe.json b/src/main/resources/assets/unicopia/models/item/netherite_horse_shoe.json new file mode 100644 index 00000000..3138e8d6 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/netherite_horse_shoe.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/netherite_horse_shoe" + } +} diff --git a/src/main/resources/assets/unicopia/textures/item/copper_horse_shoe.png b/src/main/resources/assets/unicopia/textures/item/copper_horse_shoe.png new file mode 100644 index 00000000..b16bfd05 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/item/copper_horse_shoe.png differ diff --git a/src/main/resources/assets/unicopia/textures/item/golden_horse_shoe.png b/src/main/resources/assets/unicopia/textures/item/golden_horse_shoe.png new file mode 100644 index 00000000..c36db5e5 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/item/golden_horse_shoe.png differ diff --git a/src/main/resources/assets/unicopia/textures/item/iron_horse_shoe.png b/src/main/resources/assets/unicopia/textures/item/iron_horse_shoe.png new file mode 100644 index 00000000..1f1f55ec Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/item/iron_horse_shoe.png differ diff --git a/src/main/resources/assets/unicopia/textures/item/netherite_horse_shoe.png b/src/main/resources/assets/unicopia/textures/item/netherite_horse_shoe.png new file mode 100644 index 00000000..60d88ec8 Binary files /dev/null and b/src/main/resources/assets/unicopia/textures/item/netherite_horse_shoe.png differ diff --git a/src/main/resources/data/unicopia/recipes/copper_horse_shoe.json b/src/main/resources/data/unicopia/recipes/copper_horse_shoe.json new file mode 100644 index 00000000..275c7652 --- /dev/null +++ b/src/main/resources/data/unicopia/recipes/copper_horse_shoe.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "* *", + "* *", + " * " + ], + "key": { + "*": { + "item": "minecraft:copper_ingot" + } + }, + "result": { + "item": "unicopia:copper_horse_shoe" + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/golden_horse_shoe.json b/src/main/resources/data/unicopia/recipes/golden_horse_shoe.json new file mode 100644 index 00000000..81ccb8a1 --- /dev/null +++ b/src/main/resources/data/unicopia/recipes/golden_horse_shoe.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "* *", + "* *", + " * " + ], + "key": { + "*": { + "item": "minecraft:gold_ingot" + } + }, + "result": { + "item": "unicopia:golden_horse_shoe" + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/iron_horse_shoe.json b/src/main/resources/data/unicopia/recipes/iron_horse_shoe.json new file mode 100644 index 00000000..4adc2b0b --- /dev/null +++ b/src/main/resources/data/unicopia/recipes/iron_horse_shoe.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "* *", + "* *", + " * " + ], + "key": { + "*": { + "item": "minecraft:iron_ingot" + } + }, + "result": { + "item": "unicopia:iron_horse_shoe" + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json b/src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json new file mode 100644 index 00000000..12ab6bed --- /dev/null +++ b/src/main/resources/data/unicopia/recipes/netherite_horse_shoe.json @@ -0,0 +1,16 @@ +{ + "type": "minecraft:crafting_shaped", + "pattern": [ + "* *", + "* *", + " * " + ], + "key": { + "*": { + "item": "minecraft:netherite_ingot" + } + }, + "result": { + "item": "unicopia:netherite_horse_shoe" + } +} \ No newline at end of file diff --git a/src/main/resources/data/unicopia/tags/items/horse_shoes.json b/src/main/resources/data/unicopia/tags/items/horse_shoes.json new file mode 100644 index 00000000..ca3dcfd4 --- /dev/null +++ b/src/main/resources/data/unicopia/tags/items/horse_shoes.json @@ -0,0 +1,9 @@ +{ + "replace": false, + "values": [ + "unicopia:iron_horse_shoe", + "unicopia:golden_horse_shoe", + "unicopia:copper_horse_shoe", + "unicopia:netherite_horse_shoe" + ] +}