mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Added magic staffs:
3 sticks on a diagonal = meadowbrooks_staff 3 sticks + gem (optionally with spell) on a diagnoal = magic_staff
This commit is contained in:
parent
072f18d6f9
commit
8959c67d53
31 changed files with 667 additions and 127 deletions
|
@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||||
|
import com.minelittlepony.unicopia.item.ChargeableItem;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.util.TraceHelper;
|
import com.minelittlepony.unicopia.util.TraceHelper;
|
||||||
import com.minelittlepony.unicopia.util.VecHelper;
|
import com.minelittlepony.unicopia.util.VecHelper;
|
||||||
|
@ -89,13 +90,13 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
|
|
||||||
if (amulet.getResult().isAccepted()) {
|
if (amulet.getResult().isAccepted()) {
|
||||||
ItemStack stack = amulet.getValue();
|
ItemStack stack = amulet.getValue();
|
||||||
AmuletItem item = (AmuletItem)stack.getItem();
|
ChargeableItem item = (ChargeableItem)stack.getItem();
|
||||||
|
|
||||||
if (item.canCharge(stack)) {
|
if (item.canCharge(stack)) {
|
||||||
float amount = -Math.min(player.getMagicalReserves().getMana().get(), item.getChargeRemainder(stack));
|
float amount = -Math.min(player.getMagicalReserves().getMana().get(), item.getChargeRemainder(stack));
|
||||||
|
|
||||||
if (amount < 0) {
|
if (amount < 0) {
|
||||||
AmuletItem.consumeEnergy(stack, amount);
|
ChargeableItem.consumeEnergy(stack, amount);
|
||||||
player.getMagicalReserves().getMana().add(amount * player.getMagicalReserves().getMana().getMax());
|
player.getMagicalReserves().getMana().add(amount * player.getMagicalReserves().getMana().getMax());
|
||||||
player.asWorld().playSoundFromEntity(null, player.asEntity(), USounds.ITEM_AMULET_RECHARGE, SoundCategory.PLAYERS, 1, 1);
|
player.asWorld().playSoundFromEntity(null, player.asEntity(), USounds.ITEM_AMULET_RECHARGE, SoundCategory.PLAYERS, 1, 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.entity.UEntities;
|
import com.minelittlepony.unicopia.entity.UEntities;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||||
|
|
||||||
|
@ -59,7 +58,7 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
|
||||||
MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world);
|
MagicProjectileEntity projectile = UEntities.MAGIC_BEAM.create(world);
|
||||||
projectile.setPosition(entity.getX(), entity.getEyeY() - 0.1F, entity.getZ());
|
projectile.setPosition(entity.getX(), entity.getEyeY() - 0.1F, entity.getZ());
|
||||||
projectile.setOwner(entity);
|
projectile.setOwner(entity);
|
||||||
projectile.setItem(GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), spell.getType()));
|
projectile.setItem(UItems.GEMSTONE.getDefaultStack(spell.getType()));
|
||||||
projectile.getSpellSlot().put(spell);
|
projectile.getSpellSlot().put(spell);
|
||||||
projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, divergance);
|
projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, divergance);
|
||||||
projectile.setNoGravity(true);
|
projectile.setNoGravity(true);
|
||||||
|
|
|
@ -9,7 +9,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import com.google.gson.JsonArray;
|
import com.google.gson.JsonArray;
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
|
|
||||||
import net.minecraft.item.ItemStack;
|
import net.minecraft.item.ItemStack;
|
||||||
import net.minecraft.network.PacketByteBuf;
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
@ -32,7 +32,7 @@ public class IngredientWithSpell implements Predicate<ItemStack> {
|
||||||
@Override
|
@Override
|
||||||
public boolean test(ItemStack t) {
|
public boolean test(ItemStack t) {
|
||||||
boolean stackMatch = stack.map(m -> m.test(t)).orElse(true);
|
boolean stackMatch = stack.map(m -> m.test(t)).orElse(true);
|
||||||
boolean spellMatch = spell.map(m -> GemstoneItem.getSpellKey(t).equals(m)).orElse(true);
|
boolean spellMatch = spell.map(m -> EnchantableItem.getSpellKey(t).equals(m)).orElse(true);
|
||||||
return stackMatch && spellMatch;
|
return stackMatch && spellMatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,7 @@ public class IngredientWithSpell implements Predicate<ItemStack> {
|
||||||
stacks = stack.stream()
|
stacks = stack.stream()
|
||||||
.map(Ingredient::getMatchingStacks)
|
.map(Ingredient::getMatchingStacks)
|
||||||
.flatMap(Arrays::stream)
|
.flatMap(Arrays::stream)
|
||||||
.map(stack -> spell.map(spell -> GemstoneItem.enchant(stack, spell)).orElse(stack))
|
.map(stack -> spell.map(spell -> EnchantableItem.enchant(stack, spell)).orElse(stack))
|
||||||
.toArray(ItemStack[]::new);
|
.toArray(ItemStack[]::new);
|
||||||
}
|
}
|
||||||
return stacks;
|
return stacks;
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.google.gson.JsonObject;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory;
|
import com.minelittlepony.unicopia.container.inventory.SpellbookInventory;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
import com.minelittlepony.unicopia.item.URecipes;
|
import com.minelittlepony.unicopia.item.URecipes;
|
||||||
import com.minelittlepony.unicopia.util.InventoryUtil;
|
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||||
import com.mojang.datafixers.util.Pair;
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
@ -137,7 +137,7 @@ public class SpellCraftingRecipe implements SpellbookRecipe {
|
||||||
|
|
||||||
SpellType<?> spell = SpellType.getKey(Identifier.tryParse(JsonHelper.getString(json, "spell", "")));
|
SpellType<?> spell = SpellType.getKey(Identifier.tryParse(JsonHelper.getString(json, "spell", "")));
|
||||||
if (spell != SpellType.EMPTY_KEY) {
|
if (spell != SpellType.EMPTY_KEY) {
|
||||||
return GemstoneItem.enchant(stack, spell);
|
return EnchantableItem.enchant(stack, spell);
|
||||||
}
|
}
|
||||||
return stack;
|
return stack;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class SpellDuplicatingRecipe implements SpellbookRecipe {
|
||||||
public void buildCraftingTree(CraftingTreeBuilder builder) {
|
public void buildCraftingTree(CraftingTreeBuilder builder) {
|
||||||
ItemStack[] spells = SpellType.REGISTRY.stream()
|
ItemStack[] spells = SpellType.REGISTRY.stream()
|
||||||
.filter(SpellType::isObtainable)
|
.filter(SpellType::isObtainable)
|
||||||
.map(type -> GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), type))
|
.map(UItems.GEMSTONE::getDefaultStack)
|
||||||
.toArray(ItemStack[]::new);
|
.toArray(ItemStack[]::new);
|
||||||
builder.input(UItems.BOTCHED_GEM.getDefaultStack());
|
builder.input(UItems.BOTCHED_GEM.getDefaultStack());
|
||||||
builder.input(spells);
|
builder.input(spells);
|
||||||
|
@ -47,16 +47,16 @@ public class SpellDuplicatingRecipe implements SpellbookRecipe {
|
||||||
return InventoryUtil.stream(inventory)
|
return InventoryUtil.stream(inventory)
|
||||||
.limit(inventory.size() - 1)
|
.limit(inventory.size() - 1)
|
||||||
.filter(i -> !i.isEmpty())
|
.filter(i -> !i.isEmpty())
|
||||||
.noneMatch(i -> !i.isOf(UItems.GEMSTONE) || !GemstoneItem.isEnchanted(i))
|
.noneMatch(i -> !i.isOf(UItems.GEMSTONE) || !EnchantableItem.isEnchanted(i))
|
||||||
&& material.test(stack)
|
&& material.test(stack)
|
||||||
&& !GemstoneItem.isEnchanted(stack);
|
&& !EnchantableItem.isEnchanted(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ItemStack craft(SpellbookInventory inventory) {
|
public ItemStack craft(SpellbookInventory inventory) {
|
||||||
return InventoryUtil.stream(inventory)
|
return InventoryUtil.stream(inventory)
|
||||||
.filter(i -> i.isOf(UItems.GEMSTONE))
|
.filter(i -> i.isOf(UItems.GEMSTONE))
|
||||||
.filter(GemstoneItem::isEnchanted)
|
.filter(EnchantableItem::isEnchanted)
|
||||||
.map(stack -> stack.copy())
|
.map(stack -> stack.copy())
|
||||||
.map(stack -> {
|
.map(stack -> {
|
||||||
stack.setCount(2);
|
stack.setCount(2);
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class SpellEnhancingRecipe implements SpellbookRecipe {
|
||||||
@Override
|
@Override
|
||||||
public boolean matches(SpellbookInventory inventory, World world) {
|
public boolean matches(SpellbookInventory inventory, World world) {
|
||||||
ItemStack stack = inventory.getItemToModify();
|
ItemStack stack = inventory.getItemToModify();
|
||||||
return material.test(stack) && GemstoneItem.isEnchanted(stack);
|
return material.test(stack) && EnchantableItem.isEnchanted(stack);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.minelittlepony.unicopia.ability.magic.spell.crafting;
|
||||||
|
|
||||||
|
import com.google.gson.JsonObject;
|
||||||
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
|
import com.minelittlepony.unicopia.item.URecipes;
|
||||||
|
import com.minelittlepony.unicopia.util.InventoryUtil;
|
||||||
|
|
||||||
|
import net.minecraft.inventory.CraftingInventory;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.network.PacketByteBuf;
|
||||||
|
import net.minecraft.recipe.RecipeSerializer;
|
||||||
|
import net.minecraft.recipe.ShapedRecipe;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public class SpellShapedCraftingRecipe extends ShapedRecipe {
|
||||||
|
|
||||||
|
public SpellShapedCraftingRecipe(ShapedRecipe recipe) {
|
||||||
|
super(recipe.getId(), recipe.getGroup(), recipe.getCategory(), recipe.getWidth(), recipe.getHeight(), recipe.getIngredients(), recipe.getOutput());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack craft(CraftingInventory inventory) {
|
||||||
|
return InventoryUtil.stream(inventory)
|
||||||
|
.filter(stack -> stack.getItem() instanceof EnchantableItem)
|
||||||
|
.filter(EnchantableItem::isEnchanted)
|
||||||
|
.map(stack -> ((EnchantableItem)stack.getItem()).getSpellEffect(stack))
|
||||||
|
.findFirst()
|
||||||
|
.map(spell -> spell.traits().applyTo(EnchantableItem.enchant(super.craft(inventory), spell.type())))
|
||||||
|
.orElseGet(() -> super.craft(inventory));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RecipeSerializer<?> getSerializer() {
|
||||||
|
return URecipes.CRAFTING_MAGICAL_SERIALIZER;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Serializer extends ShapedRecipe.Serializer {
|
||||||
|
@Override
|
||||||
|
public ShapedRecipe read(Identifier id, JsonObject json) {
|
||||||
|
return new SpellShapedCraftingRecipe(super.read(id, json));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ShapedRecipe read(Identifier id, PacketByteBuf buffer) {
|
||||||
|
return new SpellShapedCraftingRecipe(super.read(id, buffer));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,7 +17,6 @@ import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.util.RegistryUtils;
|
import com.minelittlepony.unicopia.util.RegistryUtils;
|
||||||
|
|
||||||
|
@ -92,7 +91,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.traits = traits;
|
this.traits = traits;
|
||||||
traited = new CustomisedSpellType<>(this, traits);
|
traited = new CustomisedSpellType<>(this, traits);
|
||||||
defaultStack = GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), this);
|
defaultStack = UItems.GEMSTONE.getDefaultStack(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isObtainable() {
|
public boolean isObtainable() {
|
||||||
|
|
|
@ -17,7 +17,7 @@ import com.minelittlepony.unicopia.client.render.*;
|
||||||
import com.minelittlepony.unicopia.client.render.entity.*;
|
import com.minelittlepony.unicopia.client.render.entity.*;
|
||||||
import com.minelittlepony.unicopia.entity.UEntities;
|
import com.minelittlepony.unicopia.entity.UEntities;
|
||||||
import com.minelittlepony.unicopia.item.ChameleonItem;
|
import com.minelittlepony.unicopia.item.ChameleonItem;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.particle.UParticles;
|
import com.minelittlepony.unicopia.particle.UParticles;
|
||||||
|
|
||||||
|
@ -117,11 +117,17 @@ public interface URenderers {
|
||||||
PolearmRenderer.register(UItems.DIAMOND_POLEARM);
|
PolearmRenderer.register(UItems.DIAMOND_POLEARM);
|
||||||
PolearmRenderer.register(UItems.NETHERITE_POLEARM);
|
PolearmRenderer.register(UItems.NETHERITE_POLEARM);
|
||||||
ModelPredicateProviderRegistry.register(UItems.GEMSTONE, new Identifier("affinity"), (stack, world, entity, seed) -> {
|
ModelPredicateProviderRegistry.register(UItems.GEMSTONE, new Identifier("affinity"), (stack, world, entity, seed) -> {
|
||||||
return GemstoneItem.isEnchanted(stack) ? 1 + GemstoneItem.getSpellKey(stack).getAffinity().ordinal() : 0;
|
return EnchantableItem.isEnchanted(stack) ? 1 + EnchantableItem.getSpellKey(stack).getAffinity().ordinal() : 0;
|
||||||
});
|
});
|
||||||
ColorProviderRegistry.ITEM.register((stack, i) -> {
|
ColorProviderRegistry.ITEM.register((stack, i) -> {
|
||||||
return i > 0 || !GemstoneItem.isEnchanted(stack) ? -1 : GemstoneItem.getSpellKey(stack).getColor();
|
return i > 0 || !EnchantableItem.isEnchanted(stack) ? -1 : EnchantableItem.getSpellKey(stack).getColor();
|
||||||
}, UItems.GEMSTONE);
|
}, UItems.GEMSTONE);
|
||||||
|
ColorProviderRegistry.ITEM.register((stack, i) -> {
|
||||||
|
if (i == 1 && EnchantableItem.isEnchanted(stack)) {
|
||||||
|
return EnchantableItem.getSpellKey(stack).getColor();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}, UItems.MAGIC_STAFF);
|
||||||
|
|
||||||
BlockColorProvider tintedProvider = (state, view, pos, color) -> {
|
BlockColorProvider tintedProvider = (state, view, pos, color) -> {
|
||||||
if (view == null || pos == null) {
|
if (view == null || pos == null) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import org.jetbrains.annotations.Nullable;
|
||||||
import com.minelittlepony.unicopia.UTags;
|
import com.minelittlepony.unicopia.UTags;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.effect.UPotions;
|
import com.minelittlepony.unicopia.entity.effect.UPotions;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.util.RegistryUtils;
|
import com.minelittlepony.unicopia.util.RegistryUtils;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public interface UTradeOffers {
|
||||||
|
|
||||||
TradeOfferHelper.registerWanderingTraderOffers(1, factories -> {
|
TradeOfferHelper.registerWanderingTraderOffers(1, factories -> {
|
||||||
factories.add(buyTiered(UItems.GEMSTONE, 30, UItems.GOLDEN_FEATHER, 1, UItems.GOLDEN_WING, 1, 30, 2, 0.05F));
|
factories.add(buyTiered(UItems.GEMSTONE, 30, UItems.GOLDEN_FEATHER, 1, UItems.GOLDEN_WING, 1, 30, 2, 0.05F));
|
||||||
factories.add((e, rng) -> new TradeOffer(new ItemStack(UItems.GEMSTONE, 3), GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), SpellType.REGISTRY.getRandom(rng).get().value()), 20, 1, 0.05F));
|
factories.add((e, rng) -> new TradeOffer(new ItemStack(UItems.GEMSTONE, 3), EnchantableItem.enchant(UItems.GEMSTONE.getDefaultStack(), SpellType.REGISTRY.getRandom(rng).get().value()), 20, 1, 0.05F));
|
||||||
factories.add(buy(UItems.GEMSTONE, 20, UItems.HAY_FRIES, 5, 50, 3, 0.06F));
|
factories.add(buy(UItems.GEMSTONE, 20, UItems.HAY_FRIES, 5, 50, 3, 0.06F));
|
||||||
factories.add(buy(Items.WHEAT, 17, UItems.HAY_BURGER, 1, 10, 6, 0.08F));
|
factories.add(buy(Items.WHEAT, 17, UItems.HAY_BURGER, 1, 10, 6, 0.08F));
|
||||||
factories.add(buy(ItemTags.SMALL_FLOWERS, 2, UItems.DAFFODIL_DAISY_SANDWICH, 1, 10, 6, 0.08F));
|
factories.add(buy(ItemTags.SMALL_FLOWERS, 2, UItems.DAFFODIL_DAISY_SANDWICH, 1, 10, 6, 0.08F));
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.entity.player;
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
@ -36,8 +36,8 @@ public class PlayerCharmTracker implements NbtSerialisable {
|
||||||
|
|
||||||
public TypedActionResult<CustomisedSpellType<?>> getSpellInHand(Hand hand) {
|
public TypedActionResult<CustomisedSpellType<?>> getSpellInHand(Hand hand) {
|
||||||
return Streams.stream(pony.asEntity().getHandItems())
|
return Streams.stream(pony.asEntity().getHandItems())
|
||||||
.filter(GemstoneItem::isEnchanted)
|
.filter(EnchantableItem::isEnchanted)
|
||||||
.map(stack -> GemstoneItem.consumeSpell(stack, pony.asEntity(), null))
|
.map(stack -> EnchantableItem.consumeSpell(stack, pony.asEntity(), null))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(getEquippedSpell(hand).toAction());
|
.orElse(getEquippedSpell(hand).toAction());
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.entity.*;
|
||||||
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
|
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
|
||||||
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
|
import com.minelittlepony.unicopia.entity.player.MagicReserves.Bar;
|
||||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||||
|
import com.minelittlepony.unicopia.item.ChargeableItem;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||||
import com.minelittlepony.unicopia.particle.*;
|
import com.minelittlepony.unicopia.particle.*;
|
||||||
|
@ -389,9 +390,9 @@ public class PlayerPhysics extends EntityPhysics<PlayerEntity> implements Tickab
|
||||||
minDamage *= 3;
|
minDamage *= 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
AmuletItem.consumeEnergy(stack, energyConsumed);
|
ChargeableItem.consumeEnergy(stack, energyConsumed);
|
||||||
|
|
||||||
if (AmuletItem.getEnergy(stack) < 9) {
|
if (ChargeableItem.getEnergy(stack) < 9) {
|
||||||
entity.playSound(USounds.ITEM_ICARUS_WINGS_WARN, 0.13F, 0.5F);
|
entity.playSound(USounds.ITEM_ICARUS_WINGS_WARN, 0.13F, 0.5F);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,7 @@ import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class AmuletItem extends WearableItem {
|
public class AmuletItem extends WearableItem implements ChargeableItem {
|
||||||
|
|
||||||
private final int maxEnergy;
|
private final int maxEnergy;
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ public class AmuletItem extends WearableItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isChargable()) {
|
if (isChargable()) {
|
||||||
list.add(Text.translatable("item.unicopia.amulet.energy", (int)Math.floor(getEnergy(stack)), maxEnergy));
|
list.add(Text.translatable("item.unicopia.amulet.energy", (int)Math.floor(ChargeableItem.getEnergy(stack)), getMaxCharge()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ public class AmuletItem extends WearableItem {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasGlint(ItemStack stack) {
|
public boolean hasGlint(ItemStack stack) {
|
||||||
return !isChargable() || stack.hasEnchantments() || getEnergy(stack) > 0;
|
return !isChargable() || stack.hasEnchantments() || ChargeableItem.getEnergy(stack) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -82,13 +82,18 @@ public class AmuletItem extends WearableItem {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isApplicable(ItemStack stack) {
|
public boolean isApplicable(ItemStack stack) {
|
||||||
return stack.getItem() == this && (!isChargable() || getEnergy(stack) > 0);
|
return stack.getItem() == this && (!isChargable() || ChargeableItem.getEnergy(stack) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isApplicable(LivingEntity entity) {
|
public boolean isApplicable(LivingEntity entity) {
|
||||||
return isApplicable(getForEntity(entity));
|
return isApplicable(getForEntity(entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxCharge() {
|
||||||
|
return maxEnergy;
|
||||||
|
}
|
||||||
|
|
||||||
public static ItemStack getForEntity(LivingEntity entity) {
|
public static ItemStack getForEntity(LivingEntity entity) {
|
||||||
return TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.NECKLACE)
|
return TrinketsDelegate.getInstance().getEquipped(entity, TrinketsDelegate.NECKLACE)
|
||||||
.filter(stack -> stack.getItem() instanceof AmuletItem)
|
.filter(stack -> stack.getItem() instanceof AmuletItem)
|
||||||
|
@ -96,34 +101,6 @@ public class AmuletItem extends WearableItem {
|
||||||
.orElse(ItemStack.EMPTY);
|
.orElse(ItemStack.EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isChargable() {
|
|
||||||
return maxEnergy > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canCharge(ItemStack stack) {
|
|
||||||
return isChargable() && getEnergy(stack) < maxEnergy;
|
|
||||||
}
|
|
||||||
|
|
||||||
public float getChargeRemainder(ItemStack stack) {
|
|
||||||
return Math.max(0, maxEnergy - getEnergy(stack));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void consumeEnergy(ItemStack stack, float amount) {
|
|
||||||
setEnergy(stack, getEnergy(stack) - amount);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float getEnergy(ItemStack stack) {
|
|
||||||
return stack.hasNbt() && stack.getNbt().contains("energy") ? stack.getNbt().getFloat("energy") : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setEnergy(ItemStack stack, float energy) {
|
|
||||||
if (energy <= 0) {
|
|
||||||
stack.removeSubNbt("energy");
|
|
||||||
} else {
|
|
||||||
stack.getOrCreateNbt().putFloat("energy", energy);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ModifiersBuilder {
|
public static class ModifiersBuilder {
|
||||||
private static final UUID SLOT_UUID = UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E");
|
private static final UUID SLOT_UUID = UUID.fromString("9F3D476D-C118-4544-8365-64846904B48E");
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
|
||||||
|
public interface ChargeableItem {
|
||||||
|
|
||||||
|
int getMaxCharge();
|
||||||
|
|
||||||
|
default int getDefaultCharge() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean isChargable() {
|
||||||
|
return getMaxCharge() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean hasCharge(ItemStack stack) {
|
||||||
|
return getEnergy(stack) > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
default ItemStack recharge(ItemStack stack) {
|
||||||
|
return setEnergy(stack, getMaxCharge());
|
||||||
|
}
|
||||||
|
|
||||||
|
default boolean canCharge(ItemStack stack) {
|
||||||
|
return isChargable() && getEnergy(stack) < getMaxCharge();
|
||||||
|
}
|
||||||
|
|
||||||
|
default float getChargeRemainder(ItemStack stack) {
|
||||||
|
return Math.max(0, getMaxCharge() - getEnergy(stack));
|
||||||
|
}
|
||||||
|
|
||||||
|
default void onDischarge(ItemStack stack) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void consumeEnergy(ItemStack stack, float amount) {
|
||||||
|
setEnergy(stack, getEnergy(stack) - amount);
|
||||||
|
if (stack.getItem() instanceof ChargeableItem c) {
|
||||||
|
c.onDischarge(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static float getEnergy(ItemStack stack) {
|
||||||
|
return stack.hasNbt() && stack.getNbt().contains("energy") ? stack.getNbt().getFloat("energy") : (stack.getItem() instanceof ChargeableItem c) ? c.getDefaultCharge() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemStack setEnergy(ItemStack stack, float energy) {
|
||||||
|
if (energy <= 0) {
|
||||||
|
stack.removeSubNbt("energy");
|
||||||
|
} else {
|
||||||
|
stack.getOrCreateNbt().putFloat("energy", energy);
|
||||||
|
}
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,86 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemConvertible;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
|
||||||
|
public interface EnchantableItem extends ItemConvertible {
|
||||||
|
|
||||||
|
default ItemStack getDefaultStack(SpellType<?> spell) {
|
||||||
|
return enchant(asItem().getDefaultStack(), spell);
|
||||||
|
}
|
||||||
|
|
||||||
|
default CustomisedSpellType<?> getSpellEffect(ItemStack stack) {
|
||||||
|
return EnchantableItem.getSpellKey(stack).withTraits(SpellTraits.of(stack));
|
||||||
|
}
|
||||||
|
|
||||||
|
static TypedActionResult<CustomisedSpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable Predicate<CustomisedSpellType<?>> filter) {
|
||||||
|
|
||||||
|
if (!isEnchanted(stack)) {
|
||||||
|
return TypedActionResult.pass(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
SpellType<Spell> key = EnchantableItem.getSpellKey(stack);
|
||||||
|
|
||||||
|
if (key.isEmpty()) {
|
||||||
|
return TypedActionResult.fail(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
CustomisedSpellType<?> result = key.withTraits(SpellTraits.of(stack));
|
||||||
|
|
||||||
|
if (filter != null && !filter.test(result)) {
|
||||||
|
return TypedActionResult.fail(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!player.world.isClient) {
|
||||||
|
player.swingHand(player.getStackInHand(Hand.OFF_HAND) == stack ? Hand.OFF_HAND : Hand.MAIN_HAND);
|
||||||
|
|
||||||
|
if (stack.getCount() == 1) {
|
||||||
|
unenchant(stack);
|
||||||
|
} else {
|
||||||
|
player.giveItemStack(unenchant(stack.split(1)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TypedActionResult.consume(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isEnchanted(ItemStack stack) {
|
||||||
|
return !stack.isEmpty() && stack.hasNbt() && stack.getNbt().contains("spell");
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemStack enchant(ItemStack stack, SpellType<?> type) {
|
||||||
|
return enchant(stack, type, type.getAffinity());
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemStack enchant(ItemStack stack, SpellType<?> type, Affinity affinity) {
|
||||||
|
if (type.isEmpty()) {
|
||||||
|
return unenchant(stack);
|
||||||
|
}
|
||||||
|
stack.getOrCreateNbt().putString("spell", type.getId().toString());
|
||||||
|
return type.getTraits().applyTo(stack);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ItemStack unenchant(ItemStack stack) {
|
||||||
|
stack.removeSubNbt("spell");
|
||||||
|
stack.removeSubNbt("spell_traits");
|
||||||
|
return stack;
|
||||||
|
}
|
||||||
|
|
||||||
|
static <T extends Spell> SpellType<T> getSpellKey(ItemStack stack) {
|
||||||
|
return SpellType.getKey(isEnchanted(stack) ? new Identifier(stack.getNbt().getString("spell")) : SpellType.EMPTY_ID);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,206 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
|
import com.minelittlepony.unicopia.entity.CastSpellEntity;
|
||||||
|
import com.minelittlepony.unicopia.entity.UEntities;
|
||||||
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
|
||||||
|
import net.minecraft.client.item.TooltipContext;
|
||||||
|
import net.minecraft.entity.Entity;
|
||||||
|
import net.minecraft.entity.EntityType;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.damage.DamageSource;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.particle.ParticleTypes;
|
||||||
|
import net.minecraft.sound.SoundCategory;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.TypedActionResult;
|
||||||
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class EnchantedStaffItem extends StaffItem implements EnchantableItem, ChargeableItem {
|
||||||
|
|
||||||
|
private static final Map<EntityType<?>, SpellType<?>> ENTITY_TYPE_TO_SPELL = new HashMap<>();
|
||||||
|
public static <T extends Spell> SpellType<T> register(EntityType<?> entityType, SpellType<T> spellType) {
|
||||||
|
ENTITY_TYPE_TO_SPELL.put(entityType, spellType);
|
||||||
|
return spellType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SpellType<?> getSpellType(Entity entity) {
|
||||||
|
if (entity instanceof CastSpellEntity cast) {
|
||||||
|
return cast.getSpellSlot().get(c -> !SpellPredicate.IS_PLACED.test(c), true).map(Spell::getType).orElse(SpellType.empty());
|
||||||
|
}
|
||||||
|
if (entity instanceof PlayerEntity player) {
|
||||||
|
return Pony.of(player).getCharms().getEquippedSpell(Hand.MAIN_HAND).type();
|
||||||
|
}
|
||||||
|
return ENTITY_TYPE_TO_SPELL.getOrDefault(entity.getType(), SpellType.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
register(EntityType.DROWNED, SpellType.BUBBLE);
|
||||||
|
register(EntityType.DOLPHIN, SpellType.BUBBLE);
|
||||||
|
register(EntityType.BLAZE, SpellType.FIRE_BOLT);
|
||||||
|
register(EntityType.CHICKEN, SpellType.FEATHER_FALL);
|
||||||
|
register(EntityType.CREEPER, SpellType.CATAPULT);
|
||||||
|
register(EntityType.HUSK, SpellType.HYDROPHOBIC);
|
||||||
|
register(EntityType.SNOW_GOLEM, SpellType.FROST);
|
||||||
|
register(EntityType.FIREBALL, SpellType.FLAME);
|
||||||
|
register(EntityType.SMALL_FIREBALL, SpellType.FLAME);
|
||||||
|
register(EntityType.ENDER_DRAGON, SpellType.DISPLACEMENT);
|
||||||
|
register(EntityType.GUARDIAN, SpellType.AWKWARD);
|
||||||
|
register(EntityType.ELDER_GUARDIAN, SpellType.AWKWARD);
|
||||||
|
register(EntityType.DRAGON_FIREBALL, SpellType.INFERNAL);
|
||||||
|
register(EntityType.CAVE_SPIDER, SpellType.REVEALING);
|
||||||
|
register(EntityType.ZOMBIE, SpellType.NECROMANCY);
|
||||||
|
register(EntityType.VEX, SpellType.NECROMANCY);
|
||||||
|
register(EntityType.SKELETON, SpellType.CATAPULT);
|
||||||
|
register(EntityType.WITHER_SKELETON, SpellType.CATAPULT);
|
||||||
|
register(EntityType.SKELETON_HORSE, SpellType.CATAPULT);
|
||||||
|
register(UEntities.TWITTERMITE, SpellType.LIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EnchantedStaffItem(Settings settings) {
|
||||||
|
super(settings.maxDamage(500));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ItemStack getDefaultStack() {
|
||||||
|
return EnchantableItem.enchant(super.getDefaultStack(), SpellType.FIRE_BOLT);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> lines, TooltipContext context) {
|
||||||
|
|
||||||
|
if (EnchantableItem.isEnchanted(stack)) {
|
||||||
|
SpellType<?> key = EnchantableItem.getSpellKey(stack);
|
||||||
|
lines.add(Text.translatable(key.getTranslationKey()).formatted(key.getAffinity().getColor()));
|
||||||
|
lines.add(Text.translatable(getTranslationKey(stack) + ".charges", (int)Math.floor(ChargeableItem.getEnergy(stack)), getMaxCharge()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult useOnEntity(ItemStack stack, PlayerEntity player, LivingEntity target, Hand hand) {
|
||||||
|
if (EnchantableItem.isEnchanted(stack)) {
|
||||||
|
return ActionResult.PASS;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.useOnEntity(stack, player, target, hand);
|
||||||
|
|
||||||
|
SpellType<?> type = getSpellType(target);
|
||||||
|
if (!type.isEmpty()) {
|
||||||
|
target.setHealth(1);
|
||||||
|
target.setFrozenTicks(9000);
|
||||||
|
player.setStackInHand(hand, recharge(EnchantableItem.enchant(stack, type)));
|
||||||
|
}
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TypedActionResult<ItemStack> use(World world, PlayerEntity player, Hand hand) {
|
||||||
|
ItemStack itemstack = player.getStackInHand(hand);
|
||||||
|
player.setCurrentHand(hand);
|
||||||
|
return TypedActionResult.consume(itemstack);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStoppedUsing(ItemStack stack, World world, LivingEntity entity, int timeLeft) {
|
||||||
|
int i = getMaxUseTime(stack) - timeLeft;
|
||||||
|
|
||||||
|
if (EnchantableItem.isEnchanted(stack) && hasCharge(stack)) {
|
||||||
|
if (i > 20) {
|
||||||
|
Pony.of(entity).ifPresent(pony -> {
|
||||||
|
pony.subtractEnergyCost(4);
|
||||||
|
stack.damage(1, pony.asEntity(), p -> p.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
|
||||||
|
getSpellEffect(stack).create().toThrowable().throwProjectile(pony);
|
||||||
|
});
|
||||||
|
ChargeableItem.consumeEnergy(stack, 1);
|
||||||
|
} else if (i > 5) {
|
||||||
|
Pony.of(entity).ifPresent(pony -> {
|
||||||
|
pony.subtractEnergyCost(4);
|
||||||
|
stack.damage(1, pony.asEntity(), p -> p.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
|
||||||
|
getSpellEffect(stack).create().toThrowable().throwProjectile(pony);
|
||||||
|
});
|
||||||
|
ChargeableItem.consumeEnergy(stack, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean castContainedEffect(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||||
|
if (attacker.isSneaking() && hasCharge(stack)) {
|
||||||
|
stack.damage(50, attacker, p -> p.sendEquipmentBreakStatus(EquipmentSlot.MAINHAND));
|
||||||
|
Caster.of(attacker).ifPresent(c -> c.subtractEnergyCost(4));
|
||||||
|
Caster.of(target).ifPresent(c -> getSpellEffect(stack).create().apply(c));
|
||||||
|
ChargeableItem.consumeEnergy(stack, 1);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void usageTick(World world, LivingEntity entity, ItemStack stack, int ticksRemaining) {
|
||||||
|
if (entity instanceof LivingEntity) {
|
||||||
|
LivingEntity living = entity;
|
||||||
|
|
||||||
|
if (living.getActiveItem().getItem() == this) {
|
||||||
|
Vec3d eyes = entity.getCameraPosVec(1);
|
||||||
|
|
||||||
|
float i = getMaxUseTime(stack) - ticksRemaining;
|
||||||
|
|
||||||
|
world.addParticle(i > 150 ? ParticleTypes.LARGE_SMOKE : ParticleTypes.CLOUD, eyes.x, eyes.y, eyes.z,
|
||||||
|
(world.random.nextGaussian() - 0.5) / 10,
|
||||||
|
(world.random.nextGaussian() - 0.5) / 10,
|
||||||
|
(world.random.nextGaussian() - 0.5) / 10
|
||||||
|
);
|
||||||
|
world.playSound(null, entity.getBlockPos(), SoundEvents.ENTITY_GUARDIAN_ATTACK, SoundCategory.PLAYERS, 1, i / 20);
|
||||||
|
|
||||||
|
if (i > 200) {
|
||||||
|
living.clearActiveItem();
|
||||||
|
living.damage(DamageSource.MAGIC, 1);
|
||||||
|
if (EnchantableItem.isEnchanted(stack) && hasCharge(stack)) {
|
||||||
|
Caster.of(entity).ifPresent(c -> getSpellEffect(stack).create().apply(c));
|
||||||
|
ChargeableItem.consumeEnergy(stack, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxUseTime(ItemStack stack) {
|
||||||
|
return 72000;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxCharge() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getDefaultCharge() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDischarge(ItemStack stack) {
|
||||||
|
if ((stack.hasNbt() && stack.getNbt().contains("energy") ? stack.getNbt().getFloat("energy") : 0) == 0) {
|
||||||
|
EnchantableItem.unenchant(stack);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -8,10 +8,8 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
|
||||||
import com.minelittlepony.unicopia.client.FlowingText;
|
import com.minelittlepony.unicopia.client.FlowingText;
|
||||||
import com.minelittlepony.unicopia.entity.player.PlayerCharmTracker;
|
import com.minelittlepony.unicopia.entity.player.PlayerCharmTracker;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
@ -25,11 +23,10 @@ import net.minecraft.text.MutableText;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.Identifier;
|
|
||||||
import net.minecraft.util.TypedActionResult;
|
import net.minecraft.util.TypedActionResult;
|
||||||
import net.minecraft.world.World;
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
public class GemstoneItem extends Item implements MultiItem {
|
public class GemstoneItem extends Item implements MultiItem, EnchantableItem {
|
||||||
|
|
||||||
public GemstoneItem(Settings settings) {
|
public GemstoneItem(Settings settings) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
@ -43,16 +40,16 @@ public class GemstoneItem extends Item implements MultiItem {
|
||||||
ItemStack stack = user.getStackInHand(hand);
|
ItemStack stack = user.getStackInHand(hand);
|
||||||
PlayerCharmTracker charms = Pony.of(user).getCharms();
|
PlayerCharmTracker charms = Pony.of(user).getCharms();
|
||||||
|
|
||||||
TypedActionResult<CustomisedSpellType<?>> spell = consumeSpell(stack, user, ((Predicate<CustomisedSpellType<?>>)charms.getEquippedSpell(hand)::equals).negate());
|
TypedActionResult<CustomisedSpellType<?>> spell = EnchantableItem.consumeSpell(stack, user, ((Predicate<CustomisedSpellType<?>>)charms.getEquippedSpell(hand)::equals).negate());
|
||||||
|
|
||||||
CustomisedSpellType<?> existing = charms.getEquippedSpell(hand);
|
CustomisedSpellType<?> existing = charms.getEquippedSpell(hand);
|
||||||
|
|
||||||
if (!existing.isEmpty()) {
|
if (!existing.isEmpty()) {
|
||||||
|
|
||||||
if (stack.getCount() == 1) {
|
if (stack.getCount() == 1) {
|
||||||
stack = existing.traits().applyTo(enchant(stack, existing.type()));
|
stack = existing.traits().applyTo(EnchantableItem.enchant(stack, existing.type()));
|
||||||
} else {
|
} else {
|
||||||
user.giveItemStack(existing.traits().applyTo(enchant(stack.split(1), existing.type())));
|
user.giveItemStack(existing.traits().applyTo(EnchantableItem.enchant(stack.split(1), existing.type())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,8 +73,8 @@ public class GemstoneItem extends Item implements MultiItem {
|
||||||
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> lines, TooltipContext tooltipContext) {
|
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> lines, TooltipContext tooltipContext) {
|
||||||
super.appendTooltip(stack, world, lines, tooltipContext);
|
super.appendTooltip(stack, world, lines, tooltipContext);
|
||||||
|
|
||||||
if (isEnchanted(stack)) {
|
if (EnchantableItem.isEnchanted(stack)) {
|
||||||
SpellType<?> key = getSpellKey(stack);
|
SpellType<?> key = EnchantableItem.getSpellKey(stack);
|
||||||
|
|
||||||
MutableText line = Text.translatable(key.getTranslationKey() + ".lore").formatted(key.getAffinity().getColor());
|
MutableText line = Text.translatable(key.getTranslationKey() + ".lore").formatted(key.getAffinity().getColor());
|
||||||
|
|
||||||
|
@ -94,81 +91,26 @@ public class GemstoneItem extends Item implements MultiItem {
|
||||||
return Arrays.stream(Affinity.VALUES)
|
return Arrays.stream(Affinity.VALUES)
|
||||||
.flatMap(i -> SpellType.byAffinity(i).stream()
|
.flatMap(i -> SpellType.byAffinity(i).stream()
|
||||||
.filter(type -> type.isObtainable())
|
.filter(type -> type.isObtainable())
|
||||||
.map(type -> enchant(getDefaultStack(), type, i))
|
.map(type -> EnchantableItem.enchant(getDefaultStack(), type, i))
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasGlint(ItemStack stack) {
|
public boolean hasGlint(ItemStack stack) {
|
||||||
return super.hasGlint(stack) || (Unicopia.SIDE.getPlayerSpecies().canCast() && isEnchanted(stack));
|
return super.hasGlint(stack) || (Unicopia.SIDE.getPlayerSpecies().canCast() && EnchantableItem.isEnchanted(stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Text getName(ItemStack stack) {
|
public Text getName(ItemStack stack) {
|
||||||
if (isEnchanted(stack)) {
|
if (EnchantableItem.isEnchanted(stack)) {
|
||||||
if (!Unicopia.SIDE.getPlayerSpecies().canCast()) {
|
if (!Unicopia.SIDE.getPlayerSpecies().canCast()) {
|
||||||
return Text.translatable(getTranslationKey(stack) + ".obfuscated");
|
return Text.translatable(getTranslationKey(stack) + ".obfuscated");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Text.translatable(getTranslationKey(stack) + ".enchanted", getSpellKey(stack).getName());
|
return Text.translatable(getTranslationKey(stack) + ".enchanted", EnchantableItem.getSpellKey(stack).getName());
|
||||||
}
|
}
|
||||||
return super.getName();
|
return super.getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TypedActionResult<CustomisedSpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable Predicate<CustomisedSpellType<?>> filter) {
|
|
||||||
|
|
||||||
if (!isEnchanted(stack)) {
|
|
||||||
return TypedActionResult.pass(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
SpellType<Spell> key = getSpellKey(stack);
|
|
||||||
|
|
||||||
if (key.isEmpty()) {
|
|
||||||
return TypedActionResult.fail(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
CustomisedSpellType<?> result = key.withTraits(SpellTraits.of(stack));
|
|
||||||
|
|
||||||
if (filter != null && !filter.test(result)) {
|
|
||||||
return TypedActionResult.fail(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!player.world.isClient) {
|
|
||||||
player.swingHand(player.getStackInHand(Hand.OFF_HAND) == stack ? Hand.OFF_HAND : Hand.MAIN_HAND);
|
|
||||||
|
|
||||||
if (stack.getCount() == 1) {
|
|
||||||
unenchant(stack);
|
|
||||||
} else {
|
|
||||||
player.giveItemStack(unenchant(stack.split(1)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TypedActionResult.consume(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isEnchanted(ItemStack stack) {
|
|
||||||
return !stack.isEmpty() && stack.hasNbt() && stack.getNbt().contains("spell");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemStack enchant(ItemStack stack, SpellType<?> type) {
|
|
||||||
return enchant(stack, type, type.getAffinity());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemStack enchant(ItemStack stack, SpellType<?> type, Affinity affinity) {
|
|
||||||
if (type.isEmpty()) {
|
|
||||||
return unenchant(stack);
|
|
||||||
}
|
|
||||||
stack.getOrCreateNbt().putString("spell", type.getId().toString());
|
|
||||||
return type.getTraits().applyTo(stack);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ItemStack unenchant(ItemStack stack) {
|
|
||||||
stack.removeSubNbt("spell");
|
|
||||||
return stack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T extends Spell> SpellType<T> getSpellKey(ItemStack stack) {
|
|
||||||
return SpellType.getKey(isEnchanted(stack) ? new Identifier(stack.getNbt().getString("spell")) : SpellType.EMPTY_ID);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,99 @@
|
||||||
|
package com.minelittlepony.unicopia.item;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import com.google.common.collect.HashMultimap;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.minelittlepony.unicopia.entity.UEntityAttributes;
|
||||||
|
|
||||||
|
import net.minecraft.block.Blocks;
|
||||||
|
import net.minecraft.client.item.TooltipContext;
|
||||||
|
import net.minecraft.entity.EntityDimensions;
|
||||||
|
import net.minecraft.entity.EquipmentSlot;
|
||||||
|
import net.minecraft.entity.LivingEntity;
|
||||||
|
import net.minecraft.entity.attribute.EntityAttribute;
|
||||||
|
import net.minecraft.entity.attribute.EntityAttributeModifier;
|
||||||
|
import net.minecraft.entity.attribute.EntityAttributeModifier.Operation;
|
||||||
|
import net.minecraft.entity.attribute.EntityAttributes;
|
||||||
|
import net.minecraft.entity.player.PlayerEntity;
|
||||||
|
import net.minecraft.item.ItemStack;
|
||||||
|
import net.minecraft.item.SwordItem;
|
||||||
|
import net.minecraft.item.ToolMaterials;
|
||||||
|
import net.minecraft.particle.BlockStateParticleEffect;
|
||||||
|
import net.minecraft.particle.ParticleTypes;
|
||||||
|
import net.minecraft.sound.SoundEvents;
|
||||||
|
import net.minecraft.text.Text;
|
||||||
|
import net.minecraft.util.ActionResult;
|
||||||
|
import net.minecraft.util.Formatting;
|
||||||
|
import net.minecraft.util.Hand;
|
||||||
|
import net.minecraft.util.UseAction;
|
||||||
|
import net.minecraft.util.math.MathHelper;
|
||||||
|
import net.minecraft.world.World;
|
||||||
|
|
||||||
|
public class StaffItem extends SwordItem {
|
||||||
|
|
||||||
|
protected static final UUID ATTACK_REACH_MODIFIER = UUID.fromString("FA235E1C-4280-A865-B01B-CBAE9985ACA3");
|
||||||
|
|
||||||
|
public StaffItem(Settings settings) {
|
||||||
|
super(ToolMaterials.WOOD, 2, 4, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ActionResult useOnEntity(ItemStack stack, PlayerEntity player, LivingEntity target, Hand hand) {
|
||||||
|
World w = player.getEntityWorld();
|
||||||
|
|
||||||
|
EntityDimensions dims = target.getDimensions(target.getPose());
|
||||||
|
|
||||||
|
for (int i = 0; i < 130; i++) {
|
||||||
|
w.addParticle(new BlockStateParticleEffect(ParticleTypes.BLOCK, Blocks.OAK_LOG.getDefaultState()),
|
||||||
|
target.getX() + (target.world.random.nextFloat() - 0.5F) * (dims.width + 1),
|
||||||
|
(target.getY() + dims.height / 2) + (target.world.random.nextFloat() - 0.5F) * dims.height,
|
||||||
|
target.getZ() + (target.world.random.nextFloat() - 0.5F) * (dims.width + 1),
|
||||||
|
0, 0, 0
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ActionResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void appendTooltip(ItemStack stack, World world, List<Text> tooltip, TooltipContext context) {
|
||||||
|
tooltip.add(Text.translatable(getTranslationKey(stack) + ".lore").formatted(Formatting.GRAY));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean postHit(ItemStack stack, LivingEntity entity, LivingEntity attacker) {
|
||||||
|
super.postHit(stack, entity, attacker);
|
||||||
|
|
||||||
|
return castContainedEffect(stack, entity, attacker);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean castContainedEffect(ItemStack stack, LivingEntity target, LivingEntity attacker) {
|
||||||
|
target.getEntityWorld().playSound(null, target.getBlockPos(), SoundEvents.ENTITY_PLAYER_ATTACK_CRIT, attacker.getSoundCategory(), 1, 1);
|
||||||
|
|
||||||
|
target.takeKnockback(attacker.getVelocity().subtract(target.getVelocity()).horizontalLength(),
|
||||||
|
MathHelper.sin(attacker.getYaw() * 0.017453292F),
|
||||||
|
-MathHelper.cos(attacker.getYaw() * 0.017453292F)
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UseAction getUseAction(ItemStack stack) {
|
||||||
|
return UseAction.BOW;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Multimap<EntityAttribute, EntityAttributeModifier> getAttributeModifiers(EquipmentSlot slot) {
|
||||||
|
Multimap<EntityAttribute, EntityAttributeModifier> multimap = HashMultimap.create();
|
||||||
|
|
||||||
|
if (slot == EquipmentSlot.MAINHAND) {
|
||||||
|
multimap.put(EntityAttributes.GENERIC_ATTACK_DAMAGE, new EntityAttributeModifier(ATTACK_DAMAGE_MODIFIER_ID, "Weapon modifier", getAttackDamage(), Operation.ADDITION));
|
||||||
|
multimap.put(UEntityAttributes.EXTENDED_ATTACK_DISTANCE, new EntityAttributeModifier(ATTACK_REACH_MODIFIER, "Weapon modifier", 3, Operation.ADDITION));
|
||||||
|
}
|
||||||
|
|
||||||
|
return multimap;
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,7 +56,7 @@ public interface UItems {
|
||||||
Item CRYSTAL_HEART = register("crystal_heart", new CrystalHeartItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
Item CRYSTAL_HEART = register("crystal_heart", new CrystalHeartItem(new Item.Settings().maxCount(1)), ItemGroups.TOOLS);
|
||||||
Item CRYSTAL_SHARD = register("crystal_shard", new Item(new Item.Settings()), ItemGroups.NATURAL);
|
Item CRYSTAL_SHARD = register("crystal_shard", new Item(new Item.Settings()), ItemGroups.NATURAL);
|
||||||
|
|
||||||
Item GEMSTONE = register("gemstone", new GemstoneItem(new Item.Settings()), ItemGroups.NATURAL);
|
GemstoneItem GEMSTONE = register("gemstone", new GemstoneItem(new Item.Settings()), ItemGroups.NATURAL);
|
||||||
Item BOTCHED_GEM = register("botched_gem", new Item(new Item.Settings()), ItemGroups.NATURAL);
|
Item BOTCHED_GEM = register("botched_gem", new Item(new Item.Settings()), ItemGroups.NATURAL);
|
||||||
|
|
||||||
Item PEGASUS_FEATHER = register("pegasus_feather", new Item(new Item.Settings()), ItemGroups.NATURAL);
|
Item PEGASUS_FEATHER = register("pegasus_feather", new Item(new Item.Settings()), ItemGroups.NATURAL);
|
||||||
|
@ -99,6 +99,9 @@ public interface UItems {
|
||||||
Item GOLDEN_WING = register("golden_wing", new Item(new Item.Settings().rarity(Rarity.UNCOMMON)), ItemGroups.NATURAL);
|
Item GOLDEN_WING = register("golden_wing", new Item(new Item.Settings().rarity(Rarity.UNCOMMON)), ItemGroups.NATURAL);
|
||||||
|
|
||||||
Item DRAGON_BREATH_SCROLL = register("dragon_breath_scroll", new DragonBreathScrollItem(new Item.Settings().rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS);
|
Item DRAGON_BREATH_SCROLL = register("dragon_breath_scroll", new DragonBreathScrollItem(new Item.Settings().rarity(Rarity.UNCOMMON)), ItemGroups.TOOLS);
|
||||||
|
Item GROGARS_BELL = register("grogars_bell", new Item(new Item.Settings().rarity(Rarity.RARE)), ItemGroups.TOOLS);
|
||||||
|
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 WOODEN_POLEARM = register("wooden_polearm", new PolearmItem(ToolMaterials.WOOD, 2, -3.6F, 2, new Item.Settings()), 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 STONE_POLEARM = register("stone_polearm", new PolearmItem(ToolMaterials.STONE, 2, -3.6F, 2, new Item.Settings()), ItemGroups.COMBAT);
|
||||||
|
|
|
@ -10,6 +10,7 @@ import net.minecraft.loot.LootTable;
|
||||||
import net.minecraft.recipe.Ingredient;
|
import net.minecraft.recipe.Ingredient;
|
||||||
import net.minecraft.recipe.RecipeSerializer;
|
import net.minecraft.recipe.RecipeSerializer;
|
||||||
import net.minecraft.recipe.RecipeType;
|
import net.minecraft.recipe.RecipeType;
|
||||||
|
import net.minecraft.recipe.ShapedRecipe;
|
||||||
import net.minecraft.recipe.ShapelessRecipe;
|
import net.minecraft.recipe.ShapelessRecipe;
|
||||||
import net.minecraft.recipe.SpecialRecipeSerializer;
|
import net.minecraft.recipe.SpecialRecipeSerializer;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
@ -21,6 +22,7 @@ public interface URecipes {
|
||||||
RecipeSerializer<ShapelessRecipe> ZAP_APPLE_SERIALIZER = RecipeSerializer.register("unicopia:crafting_zap_apple", new ZapAppleRecipe.Serializer());
|
RecipeSerializer<ShapelessRecipe> ZAP_APPLE_SERIALIZER = RecipeSerializer.register("unicopia:crafting_zap_apple", new ZapAppleRecipe.Serializer());
|
||||||
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = RecipeSerializer.register("unicopia:crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
|
RecipeSerializer<GlowingRecipe> GLOWING_SERIALIZER = RecipeSerializer.register("unicopia:crafting_glowing", new SpecialRecipeSerializer<>(GlowingRecipe::new));
|
||||||
RecipeSerializer<JarInsertRecipe> JAR_INSERT_SERIALIZER = RecipeSerializer.register("unicopia:jar_insert", new SpecialRecipeSerializer<>(JarInsertRecipe::new));
|
RecipeSerializer<JarInsertRecipe> JAR_INSERT_SERIALIZER = RecipeSerializer.register("unicopia:jar_insert", new SpecialRecipeSerializer<>(JarInsertRecipe::new));
|
||||||
|
RecipeSerializer<ShapedRecipe> CRAFTING_MAGICAL_SERIALIZER = RecipeSerializer.register("unicopia:crafting_magical", new SpellShapedCraftingRecipe.Serializer());
|
||||||
RecipeSerializer<SpellCraftingRecipe> TRAIT_REQUIREMENT = RecipeSerializer.register("unicopia:spellbook/crafting", new SpellCraftingRecipe.Serializer());
|
RecipeSerializer<SpellCraftingRecipe> TRAIT_REQUIREMENT = RecipeSerializer.register("unicopia:spellbook/crafting", new SpellCraftingRecipe.Serializer());
|
||||||
RecipeSerializer<SpellEnhancingRecipe> TRAIT_COMBINING = RecipeSerializer.register("unicopia:spellbook/combining", new SpellEnhancingRecipe.Serializer());
|
RecipeSerializer<SpellEnhancingRecipe> TRAIT_COMBINING = RecipeSerializer.register("unicopia:spellbook/combining", new SpellEnhancingRecipe.Serializer());
|
||||||
RecipeSerializer<SpellDuplicatingRecipe> SPELL_DUPLICATING = RecipeSerializer.register("unicopia:spellbook/duplicating", new SpellDuplicatingRecipe.Serializer());
|
RecipeSerializer<SpellDuplicatingRecipe> SPELL_DUPLICATING = RecipeSerializer.register("unicopia:spellbook/duplicating", new SpellDuplicatingRecipe.Serializer());
|
||||||
|
|
|
@ -93,6 +93,11 @@
|
||||||
"item.unicopia.alicorn_amulet": "Alicorn Amulet",
|
"item.unicopia.alicorn_amulet": "Alicorn Amulet",
|
||||||
"item.unicopia.alicorn_amulet.lore": "Time worn: %d",
|
"item.unicopia.alicorn_amulet.lore": "Time worn: %d",
|
||||||
|
|
||||||
|
"item.unicopia.magic_staff": "Magic Staff",
|
||||||
|
"item.unicopia.magic_staff.charges": "Charges: %d / %d",
|
||||||
|
"item.unicopia.meadowbrooks_staff": "Meadowbrook's Staff",
|
||||||
|
"item.unicopia.meadowbrooks_staff.lore": "A Heavy Stick",
|
||||||
|
|
||||||
"item.unicopia.wooden_polearm": "Wooden Polearm",
|
"item.unicopia.wooden_polearm": "Wooden Polearm",
|
||||||
"item.unicopia.stone_polearm": "Stone Polearm",
|
"item.unicopia.stone_polearm": "Stone Polearm",
|
||||||
"item.unicopia.iron_polearm": "Iron Polearm",
|
"item.unicopia.iron_polearm": "Iron Polearm",
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
{
|
||||||
|
"parent": "item/handheld",
|
||||||
|
"display": {
|
||||||
|
"thirdperson_righthand": {
|
||||||
|
"rotation": [ 0, 90, 55 ],
|
||||||
|
"translation": [ 0, 4.0, 2.5 ],
|
||||||
|
"scale": [ 1.25, 1.25, 1.25 ]
|
||||||
|
},
|
||||||
|
"thirdperson_lefthand": {
|
||||||
|
"rotation": [ 0, -90, -55 ],
|
||||||
|
"translation": [ 0, 4.0, 2.5 ],
|
||||||
|
"scale": [ 1.25, 1.25, 1.25 ]
|
||||||
|
},
|
||||||
|
"firstperson_righthand": {
|
||||||
|
"rotation": [ 0, 90, 25 ],
|
||||||
|
"translation": [ 0, 1.9, 0.8 ],
|
||||||
|
"scale": [ 0.88, 0.88, 0.88 ]
|
||||||
|
},
|
||||||
|
"firstperson_lefthand": {
|
||||||
|
"rotation": [ 0, -90, -25 ],
|
||||||
|
"translation": [ 0, 1.9, 0.8 ],
|
||||||
|
"scale": [ 0.88, 0.88, 0.88 ]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"parent": "unicopia:item/handheld_staff",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/magic_staff_base",
|
||||||
|
"layer1": "unicopia:item/magic_staff_magic"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"parent": "unicopia:item/handheld_staff",
|
||||||
|
"textures": {
|
||||||
|
"layer0": "unicopia:item/meadowbrooks_staff"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.9 KiB |
Binary file not shown.
After Width: | Height: | Size: 3.1 KiB |
|
@ -0,0 +1,30 @@
|
||||||
|
{
|
||||||
|
"parent": "minecraft:recipes/root",
|
||||||
|
"rewards": {
|
||||||
|
"recipes": [
|
||||||
|
"unicopia:meadowbrooks_staff"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"criteria": {
|
||||||
|
"has_ingredients": {
|
||||||
|
"trigger": "minecraft:inventory_changed",
|
||||||
|
"conditions": {
|
||||||
|
"items": [
|
||||||
|
{ "item": "minecraft:stick" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has_the_recipe": {
|
||||||
|
"trigger": "minecraft:recipe_unlocked",
|
||||||
|
"conditions": {
|
||||||
|
"recipe": "unicopia:meadowbrooks_staff"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"requirements": [
|
||||||
|
[
|
||||||
|
"has_ingredients",
|
||||||
|
"has_the_recipe"
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
19
src/main/resources/data/unicopia/recipes/magic_staff.json
Normal file
19
src/main/resources/data/unicopia/recipes/magic_staff.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"type": "unicopia:crafting_magical",
|
||||||
|
"pattern": [
|
||||||
|
" o",
|
||||||
|
" # ",
|
||||||
|
"# "
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:stick"
|
||||||
|
},
|
||||||
|
"o": {
|
||||||
|
"item": "unicopia:gemstone"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "unicopia:magic_staff"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"type": "minecraft:crafting_shaped",
|
||||||
|
"pattern": [
|
||||||
|
" #",
|
||||||
|
" # ",
|
||||||
|
"# "
|
||||||
|
],
|
||||||
|
"key": {
|
||||||
|
"#": {
|
||||||
|
"item": "minecraft:stick"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"result": {
|
||||||
|
"item": "unicopia:meadowbrooks_staff"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"replace": false,
|
||||||
|
"values": [
|
||||||
|
"unicopia:gemstone",
|
||||||
|
"unicopia:magic_staff"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in a new issue