mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-08 06:26:43 +01:00
Unicorns can now equip spells to their active and passive ability slots
This commit is contained in:
parent
f10dcb59ec
commit
b11fabdecb
16 changed files with 193 additions and 83 deletions
|
@ -61,7 +61,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
|
|||
player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F);
|
||||
|
||||
iplayer.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, true)
|
||||
.orElseGet(() -> SpellType.CHANGELING_DISGUISE.apply(iplayer, SpellTraits.EMPTY))
|
||||
.orElseGet(() -> SpellType.CHANGELING_DISGUISE.withTraits().apply(iplayer))
|
||||
.setDisguise(looked);
|
||||
|
||||
if (!player.isCreative()) {
|
||||
|
|
|
@ -4,14 +4,11 @@ import java.util.Random;
|
|||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
|
@ -58,7 +55,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
return Hit.of(manaLevel > 0 && ((AmuletItem)amulet.getValue().getItem()).canCharge(amulet.getValue()));
|
||||
}
|
||||
|
||||
ActionResult spell = getNewSpell(player).getResult();
|
||||
ActionResult spell = player.getCharms().getSpellInHand(Hand.MAIN_HAND).getResult();
|
||||
|
||||
if (spell != ActionResult.PASS) {
|
||||
return Hit.of(spell != ActionResult.FAIL && manaLevel > 4F);
|
||||
|
@ -82,7 +79,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
return Math.min(manaLevel, ((AmuletItem)amulet.getValue().getItem()).getChargeRemainder(amulet.getValue()));
|
||||
}
|
||||
|
||||
if (getNewSpell(player).getResult() == ActionResult.CONSUME) {
|
||||
if (player.getCharms().getSpellInHand(Hand.MAIN_HAND).getResult() == ActionResult.CONSUME) {
|
||||
return 4F;
|
||||
}
|
||||
|
||||
|
@ -111,7 +108,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
TypedActionResult<CustomisedSpellType<?>> newSpell = getNewSpell(player);
|
||||
TypedActionResult<CustomisedSpellType<?>> newSpell = player.getCharms().getSpellInHand(Hand.MAIN_HAND);
|
||||
|
||||
if (newSpell.getResult() != ActionResult.FAIL) {
|
||||
CustomisedSpellType<?> spell = newSpell.getValue();
|
||||
|
@ -140,14 +137,6 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
return TypedActionResult.pass(stack);
|
||||
}
|
||||
|
||||
private TypedActionResult<CustomisedSpellType<?>> getNewSpell(Pony player) {
|
||||
return Streams.stream(player.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, null))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<CustomisedSpellType<?>>pass(SpellType.SHIELD.withTraits()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(Pony player, AbilitySlot slot) {
|
||||
player.getMagicalReserves().getExhaustion().multiply(3.3F);
|
||||
|
|
|
@ -1,17 +1,13 @@
|
|||
package com.minelittlepony.unicopia.ability;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
|
||||
|
@ -46,7 +42,7 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
|||
|
||||
@Override
|
||||
public Hit tryActivate(Pony player) {
|
||||
return Hit.of(getNewSpell(player).getResult() != ActionResult.FAIL);
|
||||
return Hit.of(player.getCharms().getSpellInHand(Hand.OFF_HAND).getResult() != ActionResult.FAIL);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -61,29 +57,14 @@ public class UnicornProjectileAbility implements Ability<Hit> {
|
|||
|
||||
@Override
|
||||
public void apply(Pony player, Hit data) {
|
||||
TypedActionResult<CustomisedSpellType<?>> thrown = getNewSpell(player);
|
||||
TypedActionResult<CustomisedSpellType<?>> thrown = player.getCharms().getSpellInHand(Hand.OFF_HAND);
|
||||
|
||||
if (thrown.getResult() != ActionResult.FAIL) {
|
||||
@Nullable
|
||||
CustomisedSpellType<?> spell = thrown.getValue();
|
||||
|
||||
if (spell == null) {
|
||||
spell = SpellType.VORTEX.withTraits();
|
||||
}
|
||||
|
||||
player.subtractEnergyCost(getCostEstimate(player));
|
||||
spell.create().toThrowable().throwProjectile(player);
|
||||
thrown.getValue().create().toThrowable().throwProjectile(player);
|
||||
}
|
||||
}
|
||||
|
||||
private TypedActionResult<CustomisedSpellType<?>> getNewSpell(Pony player) {
|
||||
return Streams.stream(player.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), null, null))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<CustomisedSpellType<?>>pass(null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void preApply(Pony player, AbilitySlot slot) {
|
||||
player.getMagicalReserves().getExhaustion().multiply(3.3F);
|
||||
|
|
|
@ -49,7 +49,7 @@ public final class ThrowableSpell extends AbstractDelegatingSpell {
|
|||
if (!caster.isClient()) {
|
||||
MagicProjectileEntity projectile = new MagicProjectileEntity(world, entity);
|
||||
|
||||
projectile.setItem(GemstoneItem.enchanted(UItems.GEMSTONE.getDefaultStack(), spell.getType()));
|
||||
projectile.setItem(GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), spell.getType()));
|
||||
projectile.getSpellSlot().put(this);
|
||||
projectile.setVelocity(entity, entity.getPitch(), entity.getYaw(), 0, 1.5F, 1);
|
||||
projectile.setHydrophobic();
|
||||
|
|
|
@ -74,7 +74,7 @@ public class TraitRequirementRecipe implements SpellbookRecipe {
|
|||
|
||||
SpellType<?> spell = SpellType.getKey(Identifier.tryParse(JsonHelper.getString(json, "spell", "")));
|
||||
if (spell != SpellType.EMPTY_KEY) {
|
||||
return GemstoneItem.enchanted(stack, spell);
|
||||
return GemstoneItem.enchant(stack, spell);
|
||||
}
|
||||
return stack;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,7 @@ public class CatapultSpell extends AbstractSpell implements ProjectileSpell {
|
|||
} else {
|
||||
e.addVelocity(
|
||||
((caster.getWorld().random.nextFloat() * HORIZONTAL_VARIANCE) - HORIZONTAL_VARIANCE + vel.x * 0.8F) * 0.1F,
|
||||
0.1F + (getTraits().get(Trait.STRENGTH, -MAX_STRENGTH, MAX_STRENGTH) - 50) / 16D,
|
||||
0.1F + (getTraits().get(Trait.STRENGTH, -MAX_STRENGTH, MAX_STRENGTH) - 40) / 16D,
|
||||
((caster.getWorld().random.nextFloat() * HORIZONTAL_VARIANCE) - HORIZONTAL_VARIANCE + vel.z * 0.8F) * 0.1F
|
||||
);
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
|
||||
public class CustomisedSpellType<T extends Spell> implements SpellPredicate<T> {
|
||||
private final SpellType<T> type;
|
||||
private final SpellTraits traits;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
|
||||
public CustomisedSpellType(SpellType<T> type, SpellTraits traits) {
|
||||
this.type = type;
|
||||
this.traits = traits;
|
||||
}
|
||||
public record CustomisedSpellType<T extends Spell> (
|
||||
SpellType<T> type,
|
||||
SpellTraits traits
|
||||
) implements SpellPredicate<T> {
|
||||
|
||||
public boolean isEmpty() {
|
||||
return type.isEmpty();
|
||||
|
@ -33,4 +33,26 @@ public class CustomisedSpellType<T extends Spell> implements SpellPredicate<T> {
|
|||
public boolean test(Spell spell) {
|
||||
return type.test(spell);
|
||||
}
|
||||
|
||||
public ItemStack getDefaultStack() {
|
||||
return type.getDefualtStack();
|
||||
}
|
||||
|
||||
public TypedActionResult<CustomisedSpellType<?>> toAction() {
|
||||
return isEmpty() ? TypedActionResult.fail(this) : TypedActionResult.pass(this);
|
||||
}
|
||||
|
||||
public NbtCompound toNBT() {
|
||||
NbtCompound tag = new NbtCompound();
|
||||
type.writeId(tag);
|
||||
tag.put("traits", traits.toNbt());
|
||||
return tag;
|
||||
}
|
||||
|
||||
public static CustomisedSpellType<?> fromNBT(NbtCompound compound) {
|
||||
SpellType<?> type = SpellType.getKey(compound);
|
||||
SpellTraits traits = SpellTraits.fromNbt(compound.getCompound("traits")).orElse(type.getTraits());
|
||||
|
||||
return type.withTraits(traits);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,8 +20,11 @@ import com.minelittlepony.unicopia.ability.magic.spell.PlaceableSpell;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.ThrowableSpell;
|
||||
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.util.Registries;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
|
@ -75,6 +78,8 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
private final CustomisedSpellType<T> traited;
|
||||
private final SpellTraits traits;
|
||||
|
||||
private final ItemStack defaultStack;
|
||||
|
||||
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, SpellTraits traits, Factory<T> factory) {
|
||||
this.id = id;
|
||||
this.affinity = affinity;
|
||||
|
@ -83,6 +88,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
this.factory = factory;
|
||||
this.traits = traits;
|
||||
traited = new CustomisedSpellType<>(this, traits);
|
||||
defaultStack = GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), this);
|
||||
}
|
||||
|
||||
public boolean isObtainable() {
|
||||
|
@ -93,6 +99,10 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
return id;
|
||||
}
|
||||
|
||||
public ItemStack getDefualtStack() {
|
||||
return defaultStack;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the tint for this spell when applied to a gem.
|
||||
*/
|
||||
|
@ -182,9 +192,13 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
return (SpellType<T>)EMPTY_KEY;
|
||||
}
|
||||
|
||||
public static <T extends Spell> SpellType<T> getKey(NbtCompound tag) {
|
||||
return getKey(Identifier.tryParse(tag.getString("effect_id")));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Spell> SpellType<T> getKey(Identifier id) {
|
||||
return (SpellType<T>)(EMPTY_ID.equals(id) ? EMPTY_KEY : REGISTRY.getOrEmpty(id).orElse(EMPTY_KEY));
|
||||
public static <T extends Spell> SpellType<T> getKey(@Nullable Identifier id) {
|
||||
return (SpellType<T>)(id == null || EMPTY_ID.equals(id) ? EMPTY_KEY : REGISTRY.getOrEmpty(id).orElse(EMPTY_KEY));
|
||||
}
|
||||
|
||||
public static SpellType<?> random(Random random) {
|
||||
|
@ -198,7 +212,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
@Nullable
|
||||
public static Spell fromNBT(@Nullable NbtCompound compound) {
|
||||
if (compound != null && compound.contains("effect_id")) {
|
||||
Spell effect = getKey(new Identifier(compound.getString("effect_id"))).create(SpellTraits.EMPTY);
|
||||
Spell effect = getKey(compound).create(SpellTraits.EMPTY);
|
||||
|
||||
if (effect != null) {
|
||||
effect.fromNBT(compound);
|
||||
|
@ -212,12 +226,14 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
|
||||
public static NbtCompound toNBT(Spell effect) {
|
||||
NbtCompound compound = effect.toNBT();
|
||||
|
||||
compound.putString("effect_id", effect.getType().getId().toString());
|
||||
|
||||
effect.getType().writeId(compound);
|
||||
return compound;
|
||||
}
|
||||
|
||||
public void writeId(NbtCompound tag) {
|
||||
tag.putString("effect_id", getId().toString());
|
||||
}
|
||||
|
||||
public interface Factory<T extends Spell> {
|
||||
T create(SpellType<T> type, SpellTraits traits);
|
||||
}
|
||||
|
|
|
@ -127,6 +127,16 @@ public final class SpellTraits implements Iterable<Map.Entry<Trait, Float>> {
|
|||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return traits.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return this == other || other instanceof SpellTraits && Objects.equals(traits, ((SpellTraits) other).traits);
|
||||
}
|
||||
|
||||
public static SpellTraits union(SpellTraits...many) {
|
||||
Map<Trait, Float> traits = new HashMap<>();
|
||||
for (SpellTraits i : many) {
|
||||
|
|
|
@ -10,6 +10,7 @@ import com.minelittlepony.unicopia.USounds;
|
|||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.AbstractDisguiseSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.client.KeyBindingsHandler;
|
||||
import com.minelittlepony.unicopia.client.sound.LoopingSoundInstance;
|
||||
|
@ -29,6 +30,7 @@ import net.minecraft.entity.EntityDimensions;
|
|||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Arm;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Quaternion;
|
||||
|
@ -42,6 +44,8 @@ public class UHud extends DrawableHelper {
|
|||
|
||||
public static final int PRIMARY_SLOT_SIZE = 49;
|
||||
|
||||
private static final float EQUIPPED_GEMSTONE_SCALE = 0.7F;
|
||||
|
||||
public TextRenderer font;
|
||||
|
||||
final MinecraftClient client = MinecraftClient.getInstance();
|
||||
|
@ -82,15 +86,23 @@ public class UHud extends DrawableHelper {
|
|||
xDirection = client.player.getMainArm() == Arm.LEFT ? -1 : 1;
|
||||
|
||||
matrices.push();
|
||||
matrices.translate(((scaledWidth - 50) / 2) + (104 * xDirection), scaledHeight - 50, 0);
|
||||
|
||||
int hudX = ((scaledWidth - 50) / 2) + (104 * xDirection);
|
||||
int hudY = scaledHeight - 50;
|
||||
int hudZ = 0;
|
||||
|
||||
|
||||
float exhaustion = pony.getMagicalReserves().getExhaustion().getPercentFill();
|
||||
|
||||
if (exhaustion > 0.5F) {
|
||||
Random rng = client.world.random;
|
||||
matrices.translate(rng.nextFloat() - 0.5F, rng.nextFloat() - 0.5F, rng.nextFloat() - 0.5F);
|
||||
hudX += rng.nextFloat() - 0.5F;
|
||||
hudY += rng.nextFloat() - 0.5F;
|
||||
hudZ += rng.nextFloat() - 0.5F;
|
||||
}
|
||||
|
||||
matrices.translate(hudX, hudY, hudZ);
|
||||
|
||||
AbilityDispatcher abilities = pony.getAbilities();
|
||||
|
||||
if (message != null && messageTime > 0) {
|
||||
|
@ -106,10 +118,15 @@ public class UHud extends DrawableHelper {
|
|||
slots.forEach(slot -> slot.renderBackground(matrices, abilities, swap, tickDelta));
|
||||
slots.forEach(slot -> slot.renderLabel(matrices, abilities, tickDelta));
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
|
||||
matrices.pop();
|
||||
|
||||
if (pony.getSpecies().canCast()) {
|
||||
renderSpell(pony.getCharms().getEquippedSpell(Hand.MAIN_HAND), hudX + 15 - xDirection * 8, hudY + 2);
|
||||
renderSpell(pony.getCharms().getEquippedSpell(Hand.OFF_HAND), hudX + 15 - xDirection * 0, hudY - 3);
|
||||
}
|
||||
|
||||
RenderSystem.disableBlend();
|
||||
|
||||
if (pony.getSpecies() == Race.CHANGELING && !client.player.isSneaking()) {
|
||||
pony.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, false).map(AbstractDisguiseSpell::getDisguise)
|
||||
.map(EntityAppearance::getAppearance)
|
||||
|
@ -137,15 +154,25 @@ public class UHud extends DrawableHelper {
|
|||
}
|
||||
}
|
||||
|
||||
private void renderMessage(MatrixStack matrices, float tickDelta) {
|
||||
private void renderSpell(CustomisedSpellType<?> spell, int x, int y) {
|
||||
if (!spell.isEmpty()) {
|
||||
MatrixStack modelStack = RenderSystem.getModelViewStack();
|
||||
modelStack.push();
|
||||
modelStack.translate(x, y, 0);
|
||||
modelStack.scale(EQUIPPED_GEMSTONE_SCALE, EQUIPPED_GEMSTONE_SCALE, EQUIPPED_GEMSTONE_SCALE);
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
client.getItemRenderer().renderGuiItemIcon(spell.getDefaultStack(), 0, 0);
|
||||
modelStack.pop();
|
||||
RenderSystem.applyModelViewMatrix();
|
||||
}
|
||||
}
|
||||
|
||||
private void renderMessage(MatrixStack matrices, float tickDelta) {
|
||||
float time = messageTime - tickDelta;
|
||||
int progress = Math.min(255, (int)(time * 255F / 20F));
|
||||
|
||||
if (progress > 8) {
|
||||
|
||||
int color = 0xFFFFFF;
|
||||
|
||||
int alpha = progress << 24 & -16777216;
|
||||
|
||||
color |= alpha;
|
||||
|
@ -239,5 +266,4 @@ public class UHud extends DrawableHelper {
|
|||
RenderSystem.setShaderTexture(0, HUD_TEXTURE);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -84,7 +84,7 @@ public class DisguiseCommand {
|
|||
|
||||
Pony iplayer = Pony.of(player);
|
||||
iplayer.getSpellSlot().get(SpellType.CHANGELING_DISGUISE, true)
|
||||
.orElseGet(() -> SpellType.CHANGELING_DISGUISE.apply(iplayer, SpellTraits.EMPTY))
|
||||
.orElseGet(() -> SpellType.CHANGELING_DISGUISE.withTraits().apply(iplayer))
|
||||
.setDisguise(entity);
|
||||
|
||||
if (source.getEntity() == player) {
|
||||
|
|
|
@ -36,7 +36,7 @@ public interface UTradeOffers {
|
|||
|
||||
TradeOfferHelper.registerWanderingTraderOffers(1, factories -> {
|
||||
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.enchanted(UItems.GEMSTONE.getDefaultStack(), SpellType.random(rng)), 20, 1, 0.05F));
|
||||
factories.add((e, rng) -> new TradeOffer(new ItemStack(UItems.GEMSTONE, 3), GemstoneItem.enchant(UItems.GEMSTONE.getDefaultStack(), SpellType.random(rng)), 20, 1, 0.05F));
|
||||
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(ItemTags.SMALL_FLOWERS, 2, UItems.DAFFODIL_DAISY_SANDWICH, 1, 10, 6, 0.08F));
|
||||
|
|
|
@ -7,14 +7,23 @@ import java.util.Objects;
|
|||
import java.util.Set;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import com.google.common.collect.Streams;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.item.GemstoneItem;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
import com.minelittlepony.unicopia.util.Tickable;
|
||||
|
||||
import net.minecraft.item.ItemConvertible;
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.nbt.NbtElement;
|
||||
import net.minecraft.nbt.NbtList;
|
||||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
import net.minecraft.util.registry.Registry;
|
||||
|
||||
public class PlayerCharmTracker implements Tickable, NbtSerialisable {
|
||||
|
@ -23,6 +32,11 @@ public class PlayerCharmTracker implements Tickable, NbtSerialisable {
|
|||
|
||||
private final ItemTracker armour = new ItemTracker();
|
||||
|
||||
private CustomisedSpellType<?>[] handSpells = new CustomisedSpellType<?>[] {
|
||||
SpellType.SHIELD.withTraits(),
|
||||
SpellType.CATAPULT.withTraits()
|
||||
};
|
||||
|
||||
PlayerCharmTracker(Pony pony) {
|
||||
this.pony = pony;
|
||||
}
|
||||
|
@ -36,14 +50,47 @@ public class PlayerCharmTracker implements Tickable, NbtSerialisable {
|
|||
return armour;
|
||||
}
|
||||
|
||||
public CustomisedSpellType<?>[] getHandSpells() {
|
||||
return handSpells;
|
||||
}
|
||||
|
||||
public CustomisedSpellType<?> getEquippedSpell(Hand hand) {
|
||||
return handSpells[hand.ordinal()];
|
||||
}
|
||||
|
||||
public TypedActionResult<CustomisedSpellType<?>> getSpellInHand(Hand hand) {
|
||||
return Streams.stream(pony.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, pony.getMaster(), null))
|
||||
.findFirst()
|
||||
.orElse(getEquippedSpell(hand).toAction());
|
||||
}
|
||||
|
||||
public void equipSpell(Hand hand, CustomisedSpellType<?> spell) {
|
||||
handSpells[hand.ordinal()] = spell;
|
||||
pony.getMaster().playSound(SoundEvents.UI_BUTTON_CLICK, 0.25F, 1.75F);
|
||||
pony.setDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
compound.put("armour", armour.toNBT());
|
||||
NbtList equippedSpells = new NbtList();
|
||||
for (CustomisedSpellType<?> spell : handSpells) {
|
||||
equippedSpells.add(spell.toNBT());
|
||||
}
|
||||
compound.put("handSpells", equippedSpells);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
armour.fromNBT(compound.getCompound("armour"));
|
||||
if (compound.contains("handSpells", NbtElement.LIST_TYPE)) {
|
||||
NbtList list = compound.getList("handSpells", NbtElement.COMPOUND_TYPE);
|
||||
for (int i = 0; i < handSpells.length && i < list.size(); i++) {
|
||||
handSpells[i] = CustomisedSpellType.fromNBT(list.getCompound(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class ItemTracker implements NbtSerialisable {
|
||||
|
|
|
@ -59,6 +59,7 @@ import net.minecraft.server.network.ServerPlayerEntity;
|
|||
import net.minecraft.server.world.ServerWorld;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.text.TranslatableText;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.BlockPos;
|
||||
import net.minecraft.util.math.Direction;
|
||||
|
||||
|
@ -511,6 +512,8 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
|||
oldPlayer.getSpellSlot().put(null);
|
||||
setSpecies(oldPlayer.getSpecies());
|
||||
getDiscoveries().copyFrom(oldPlayer.getDiscoveries());
|
||||
getCharms().equipSpell(Hand.MAIN_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.MAIN_HAND));
|
||||
getCharms().equipSpell(Hand.OFF_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.OFF_HAND));
|
||||
setDirty();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.unicopia.item;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Predicate;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
@ -12,6 +11,8 @@ 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 com.minelittlepony.unicopia.entity.player.PlayerCharmTracker;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
|
||||
import net.minecraft.client.item.TooltipContext;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
|
@ -34,6 +35,24 @@ public class GemstoneItem extends Item {
|
|||
super(settings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypedActionResult<ItemStack> use(World world, PlayerEntity user, Hand hand) {
|
||||
TypedActionResult<ItemStack> result = super.use(world, user, hand);
|
||||
|
||||
if (!result.getResult().isAccepted()) {
|
||||
ItemStack stack = user.getStackInHand(hand);
|
||||
PlayerCharmTracker charms = Pony.of(user).getCharms();
|
||||
|
||||
TypedActionResult<CustomisedSpellType<?>> spell = consumeSpell(stack, user, ((Predicate<CustomisedSpellType<?>>)charms.getEquippedSpell(hand)::equals).negate());
|
||||
if (spell.getResult().isAccepted()) {
|
||||
charms.equipSpell(hand, spell.getValue());
|
||||
return TypedActionResult.success(stack, true);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> lines, TooltipContext tooltipContext) {
|
||||
super.appendTooltip(stack, world, lines, tooltipContext);
|
||||
|
@ -58,7 +77,7 @@ public class GemstoneItem extends Item {
|
|||
for (Affinity i : Affinity.VALUES) {
|
||||
SpellType.byAffinity(i).forEach(type -> {
|
||||
if (type.isObtainable()) {
|
||||
items.add(enchanted(getDefaultStack(), type, i));
|
||||
items.add(enchant(getDefaultStack(), type, i));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -82,20 +101,21 @@ public class GemstoneItem extends Item {
|
|||
return super.getName();
|
||||
}
|
||||
|
||||
public static TypedActionResult<CustomisedSpellType<?>> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, @Nullable Predicate<SpellType<?>> test) {
|
||||
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);
|
||||
SpellTraits traits = SpellTraits.of(stack);
|
||||
|
||||
if (Objects.equals(key, exclude)) {
|
||||
if (key.isEmpty()) {
|
||||
return TypedActionResult.fail(null);
|
||||
}
|
||||
|
||||
if (key.isEmpty() || (test != null && !test.test(key))) {
|
||||
CustomisedSpellType<?> result = key.withTraits(SpellTraits.of(stack));
|
||||
|
||||
if (filter != null && !filter.test(result)) {
|
||||
return TypedActionResult.fail(null);
|
||||
}
|
||||
|
||||
|
@ -103,29 +123,29 @@ public class GemstoneItem extends Item {
|
|||
player.swingHand(player.getStackInHand(Hand.OFF_HAND) == stack ? Hand.OFF_HAND : Hand.MAIN_HAND);
|
||||
|
||||
if (stack.getCount() == 1) {
|
||||
unenchanted(stack);
|
||||
unenchant(stack);
|
||||
} else {
|
||||
player.giveItemStack(unenchanted(stack.split(1)));
|
||||
player.giveItemStack(unenchant(stack.split(1)));
|
||||
}
|
||||
}
|
||||
|
||||
return TypedActionResult.consume(key.withTraits(traits));
|
||||
return TypedActionResult.consume(result);
|
||||
}
|
||||
|
||||
public static boolean isEnchanted(ItemStack stack) {
|
||||
return !stack.isEmpty() && stack.hasNbt() && stack.getNbt().contains("spell");
|
||||
}
|
||||
|
||||
public static ItemStack enchanted(ItemStack stack, SpellType<?> type) {
|
||||
return enchanted(stack, type, type.getAffinity());
|
||||
public static ItemStack enchant(ItemStack stack, SpellType<?> type) {
|
||||
return enchant(stack, type, type.getAffinity());
|
||||
}
|
||||
|
||||
public static ItemStack enchanted(ItemStack stack, SpellType<?> type, Affinity affinity) {
|
||||
public static ItemStack enchant(ItemStack stack, SpellType<?> type, Affinity affinity) {
|
||||
stack.getOrCreateNbt().putString("spell", type.getId().toString());
|
||||
return type.getTraits().applyTo(stack);
|
||||
}
|
||||
|
||||
public static ItemStack unenchanted(ItemStack stack) {
|
||||
public static ItemStack unenchant(ItemStack stack) {
|
||||
stack.removeSubNbt("spell");
|
||||
return stack;
|
||||
}
|
||||
|
|
|
@ -15,18 +15,14 @@ public interface NbtSerialisable {
|
|||
*
|
||||
* @param compound Compound tag to write to.
|
||||
*/
|
||||
default void toNBT(NbtCompound compound) {
|
||||
|
||||
}
|
||||
void toNBT(NbtCompound compound);
|
||||
|
||||
/**
|
||||
* Called to load this state from nbt
|
||||
*
|
||||
* @param compound Compound tag to read from.
|
||||
*/
|
||||
default void fromNBT(NbtCompound compound) {
|
||||
|
||||
}
|
||||
void fromNBT(NbtCompound compound);
|
||||
|
||||
default NbtCompound toNBT() {
|
||||
NbtCompound compound = new NbtCompound();
|
||||
|
|
Loading…
Reference in a new issue