From a58c6a0a44f53925d72bd32042dcf4ae657832aa Mon Sep 17 00:00:00 2001 From: Sollace Date: Tue, 2 Mar 2021 15:40:37 +0200 Subject: [PATCH] More work on spells and gemstones --- .../com/minelittlepony/unicopia/Affinity.java | 21 ++--- .../unicopia/ability/magic/Affine.java | 4 + .../unicopia/ability/magic/Spell.java | 6 -- .../magic/spell/AbstractRangedAreaSpell.java | 5 +- .../ability/magic/spell/AbstractSpell.java | 13 ++- .../ability/magic/spell/AttractiveSpell.java | 12 +-- .../ability/magic/spell/AwkwardSpell.java | 5 +- .../ability/magic/spell/DisguiseSpell.java | 5 +- .../ability/magic/spell/FireSpell.java | 5 +- .../ability/magic/spell/GenericSpell.java | 5 +- .../ability/magic/spell/IceSpell.java | 5 +- .../ability/magic/spell/InfernoSpell.java | 5 +- .../ability/magic/spell/JoustingSpell.java | 6 +- .../ability/magic/spell/NecromancySpell.java | 10 +-- .../ability/magic/spell/RevealingSpell.java | 10 +-- .../ability/magic/spell/ScorchSpell.java | 5 +- .../ability/magic/spell/ShieldSpell.java | 8 +- .../ability/magic/spell/SiphoningSpell.java | 8 +- .../ability/magic/spell/SpellType.java | 63 ++++++++------- .../unicopia/client/URenderers.java | 9 +++ .../unicopia/item/GemstoneItem.java | 49 ++++++++---- .../projectile/MagicProjectileEntity.java | 9 ++- .../resources/assets/unicopia/lang/en_us.json | 74 +++++++----------- .../assets/unicopia/models/item/gemstone.json | 16 +++- .../models/item/gemstone_corrupted.json | 6 ++ .../unicopia/models/item/gemstone_pure.json | 6 ++ .../textures/item/gemstone_corrupted.png | Bin 0 -> 3285 bytes .../unicopia/textures/item/gemstone_pure.png | Bin 0 -> 3262 bytes 28 files changed, 213 insertions(+), 157 deletions(-) create mode 100644 src/main/resources/assets/unicopia/models/item/gemstone_corrupted.json create mode 100644 src/main/resources/assets/unicopia/models/item/gemstone_pure.json create mode 100644 src/main/resources/assets/unicopia/textures/item/gemstone_corrupted.png create mode 100644 src/main/resources/assets/unicopia/textures/item/gemstone_pure.png diff --git a/src/main/java/com/minelittlepony/unicopia/Affinity.java b/src/main/java/com/minelittlepony/unicopia/Affinity.java index 9bda0a1a..23cdfd84 100644 --- a/src/main/java/com/minelittlepony/unicopia/Affinity.java +++ b/src/main/java/com/minelittlepony/unicopia/Affinity.java @@ -1,7 +1,5 @@ package com.minelittlepony.unicopia; -import net.minecraft.text.Text; -import net.minecraft.text.TranslatableText; import net.minecraft.util.Formatting; public enum Affinity { @@ -15,12 +13,14 @@ public enum Affinity { private Affinity[] implications; + public static final Affinity[] VALUES = values(); + Affinity(Formatting color, int corruption) { this.color = color; this.corruption = corruption; } - public Formatting getColourCode() { + public Formatting getColor() { return color; } @@ -28,10 +28,6 @@ public enum Affinity { return this == BAD ? "curse" : "spell"; } - public Text getName() { - return new TranslatableText("affinity." + getTranslationKey()).styled(s -> s.withColor(getColourCode())); - } - public int getCorruption() { return corruption; } @@ -50,7 +46,7 @@ public enum Affinity { } if (this == NEUTRAL) { - implications = values(); + implications = new Affinity[] { GOOD, BAD }; } else { implications = new Affinity[] { this }; } @@ -58,12 +54,7 @@ public enum Affinity { return implications; } - public static Affinity of(String s) { - try { - if (s != null) - return valueOf(s.toUpperCase()); - } catch (Throwable e) {} - - return Affinity.NEUTRAL; + public static Affinity of(int ordinal, Affinity fallback) { + return ordinal < 0 || ordinal >= VALUES.length ? fallback : VALUES[ordinal]; } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Affine.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Affine.java index 03d829e9..007da627 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Affine.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Affine.java @@ -15,4 +15,8 @@ public interface Affine { default boolean isEnemy(Affine other) { return !getAffinity().alignsWith(other.getAffinity()); } + + default boolean isFriendlyTogether(Affine other) { + return getAffinity() != Affinity.BAD && other.getAffinity() != Affinity.BAD; + } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java index 26982e5e..56283190 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/Spell.java @@ -1,6 +1,5 @@ package com.minelittlepony.unicopia.ability.magic; -import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.spell.SpellType; import com.minelittlepony.unicopia.util.NbtSerialisable; @@ -83,11 +82,6 @@ public interface Spell extends NbtSerialisable, Affine { */ void render(Caster source); - @Override - default Affinity getAffinity() { - return getType().getAffinity(); - } - /** * Return true to allow the gem update and move. */ diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractRangedAreaSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractRangedAreaSpell.java index 36b991df..ed7ebd7a 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractRangedAreaSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractRangedAreaSpell.java @@ -1,12 +1,13 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Attached; import com.minelittlepony.unicopia.ability.magic.Caster; public abstract class AbstractRangedAreaSpell extends AbstractSpell implements Attached { - protected AbstractRangedAreaSpell(SpellType type) { - super(type); + protected AbstractRangedAreaSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java index 09449e2a..b8352c51 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AbstractSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Spell; @@ -12,8 +13,11 @@ public abstract class AbstractSpell implements Spell { private final SpellType type; - protected AbstractSpell(SpellType type) { + private Affinity affinity; + + protected AbstractSpell(SpellType type, Affinity affinity) { this.type = type; + this.affinity = affinity; } @Override @@ -56,14 +60,21 @@ public abstract class AbstractSpell implements Spell { return 0; } + @Override + public Affinity getAffinity() { + return affinity; + } + @Override public void toNBT(CompoundTag compound) { compound.putBoolean("dead", isDead); + compound.putInt("affinity", affinity.ordinal()); } @Override public void fromNBT(CompoundTag compound) { setDirty(false); isDead = compound.getBoolean("dead"); + affinity = Affinity.of(compound.getInt("affinity"), getType().getAffinity()); } } diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java index 3dbbcf28..03c5ec91 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AttractiveSpell.java @@ -26,8 +26,8 @@ public class AttractiveSpell extends ShieldSpell implements Thrown { @Nullable private BlockPos homingPos; - protected AttractiveSpell(SpellType type) { - super(type); + protected AttractiveSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override @@ -61,17 +61,19 @@ public class AttractiveSpell extends ShieldSpell implements Thrown { double force = 2.5F * distance; - if (source.getAffinity() != Affinity.BAD && target instanceof PlayerEntity) { + boolean isGood = isFriendlyTogether(source); + + if (isGood && target instanceof PlayerEntity) { force *= calculateAdjustedForce(Pony.of((PlayerEntity)target)); } - if (source.getAffinity() == Affinity.BAD && source.getWorld().random.nextInt(4500) == 0) { + if (!isGood && source.getWorld().random.nextInt(4500) == 0) { source.getEntity().damage(MagicalDamageSource.create("vortex"), 4); } applyForce(pos, target, -force, 0); - float maxVel = source.getAffinity() == Affinity.BAD ? 1 : 1.6f; + float maxVel = !isFriendlyTogether(source) ? 1 : 1.6f; Vec3d vel = target.getVelocity(); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java index 570b2a30..90a60414 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/AwkwardSpell.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell; import java.util.ArrayList; import java.util.List; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Thrown; import com.minelittlepony.unicopia.util.shape.Sphere; @@ -17,8 +18,8 @@ import net.minecraft.util.registry.Registry; public class AwkwardSpell extends AbstractSpell implements Thrown { - protected AwkwardSpell(SpellType type) { - super(type); + protected AwkwardSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java index 7885f849..3ca23ff0 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/DisguiseSpell.java @@ -4,6 +4,7 @@ import java.util.Optional; import javax.annotation.Nullable; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.FlightType; import com.minelittlepony.unicopia.Owned; import com.minelittlepony.unicopia.ability.magic.Attached; @@ -31,8 +32,8 @@ public class DisguiseSpell extends AbstractSpell implements Attached, Suppressab private int suppressionCounter; - protected DisguiseSpell(SpellType type) { - super(type); + protected DisguiseSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java index 6b450488..9f633f85 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/FireSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.EquinePredicates; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Magical; @@ -39,8 +40,8 @@ public class FireSpell extends AbstractRangedAreaSpell implements Thrown { private static final Shape VISUAL_EFFECT_RANGE = new Sphere(false, 0.5); private static final Shape EFFECT_RANGE = new Sphere(false, 4); - protected FireSpell(SpellType type) { - super(type); + protected FireSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/GenericSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/GenericSpell.java index 061f8ca5..c9de6148 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/GenericSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/GenericSpell.java @@ -1,12 +1,13 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.particle.MagicParticleEffect; public class GenericSpell extends AbstractSpell { - protected GenericSpell(SpellType type) { - super(type); + protected GenericSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java index 6b1c0b2f..d8550cfd 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/IceSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Thrown; import com.minelittlepony.unicopia.block.state.StateMaps; @@ -28,8 +29,8 @@ public class IceSpell extends AbstractRangedAreaSpell implements Thrown { private final int rad = 3; private final Shape effect_range = new Sphere(false, rad); - protected IceSpell(SpellType type) { - super(type); + protected IceSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java index ea687884..bb2b6a0a 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/InfernoSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.block.state.StateMaps; import com.minelittlepony.unicopia.util.MagicalDamageSource; @@ -16,8 +17,8 @@ import net.minecraft.world.World; public class InfernoSpell extends FireSpell { - protected InfernoSpell(SpellType type) { - super(type); + protected InfernoSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java index 8027cadf..89ac3132 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/JoustingSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.UTags; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Thrown; @@ -29,9 +30,8 @@ public class JoustingSpell extends AbstractRangedAreaSpell implements Thrown { private int age; - protected JoustingSpell(SpellType type) { - super(type); - // TODO Auto-generated constructor stub + protected JoustingSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java index e998cbe8..9b2faee1 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/NecromancySpell.java @@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell; import java.util.List; import com.google.common.collect.Lists; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.util.WorldEvent; import com.minelittlepony.unicopia.util.shape.Shape; @@ -25,8 +26,8 @@ public class NecromancySpell extends AbstractRangedAreaSpell { EntityType.ZOMBIFIED_PIGLIN ); - protected NecromancySpell(SpellType type) { - super(type); + protected NecromancySpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override @@ -36,7 +37,6 @@ public class NecromancySpell extends AbstractRangedAreaSpell { return true; } - float additional = source.getWorld().getLocalDifficulty(source.getOrigin()).getLocalDifficulty(); int radius = source.getLevel().get() + 1; @@ -61,7 +61,7 @@ public class NecromancySpell extends AbstractRangedAreaSpell { if (source.getWorld().isAir(loc.up()) && !source.getWorld().isAir(loc)) { spawnMonster(source, pos); - return true; + return false; } } @@ -72,8 +72,8 @@ public class NecromancySpell extends AbstractRangedAreaSpell { protected void spawnMonster(Caster source, Vec3d pos) { int index = (int)MathHelper.nextDouble(source.getWorld().random, 0, spawns.size()); LivingEntity zombie = spawns.get(index).create(source.getWorld()); - zombie.setPos(pos.x, pos.y, pos.z); + zombie.updatePositionAndAngles(pos.x, pos.y, pos.z, 0, 0); zombie.setVelocity(0, 0.3, 0); source.getWorld().syncWorldEvent(WorldEvent.ZOMBIE_BREAK_WOODEN_DOOR, zombie.getBlockPos(), 0); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java index 795b3ea2..0b66c5ee 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/RevealingSpell.java @@ -1,5 +1,6 @@ package com.minelittlepony.unicopia.ability.magic.spell; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Suppressable; import com.minelittlepony.unicopia.ability.magic.Thrown; @@ -15,9 +16,10 @@ import net.minecraft.util.math.Vec3d; * A spell for revealing changelings. */ public class RevealingSpell extends AbstractSpell implements Thrown { + private static final Shape AREA = new Sphere(false, 15); - protected RevealingSpell(SpellType type) { - super(type); + protected RevealingSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override @@ -41,11 +43,9 @@ public class RevealingSpell extends AbstractSpell implements Thrown { @Override public void render(Caster source) { - Shape area = new Sphere(false, 15); - MagicParticleEffect effect = new MagicParticleEffect(getType().getColor()); - source.spawnParticles(area, 5, pos -> { + source.spawnParticles(AREA, 5, pos -> { source.addParticle(effect, pos, Vec3d.ZERO); }); source.spawnParticles(effect, 5); diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java index 71e6c23c..741eb89e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ScorchSpell.java @@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.ability.magic.spell; import javax.annotation.Nullable; +import com.minelittlepony.unicopia.Affinity; import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.block.state.StateMaps; import com.minelittlepony.unicopia.particle.MagicParticleEffect; @@ -16,8 +17,8 @@ import net.minecraft.util.math.Vec3d; public class ScorchSpell extends FireSpell { - protected ScorchSpell(SpellType type) { - super(type); + protected ScorchSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java index 1ef4a91d..d18aeb00 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/ShieldSpell.java @@ -39,8 +39,8 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached { private final Map targets = new TreeMap<>(); - protected ShieldSpell(SpellType type) { - super(type); + protected ShieldSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override @@ -101,7 +101,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached { Entity owner = source.getMaster(); - boolean ownerIsValid = source.getAffinity() != Affinity.BAD && (EquinePredicates.PLAYER_UNICORN.test(owner) && owner.isSneaking()); + boolean ownerIsValid = isFriendlyTogether(source) && (EquinePredicates.PLAYER_UNICORN.test(owner) && owner.isSneaking()); return source.findAllEntitiesInRange(radius) .filter(entity -> { @@ -157,7 +157,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached { } else if (target instanceof LivingEntity) { double force = Math.max(0.1, radius / 4); - if (source.getAffinity() != Affinity.BAD && target instanceof PlayerEntity) { + if (isFriendlyTogether(source) && target instanceof PlayerEntity) { force *= calculateAdjustedForce(Pony.of((PlayerEntity)target)); } else { force *= 0.75; diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java index ecf851ae..7ca81373 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SiphoningSpell.java @@ -23,8 +23,8 @@ import net.minecraft.util.math.Vec3d; */ public class SiphoningSpell extends AbstractRangedAreaSpell implements Thrown { - protected SiphoningSpell(SpellType type) { - super(type); + protected SiphoningSpell(SpellType type, Affinity affinity) { + super(type, affinity); } @Override @@ -41,7 +41,7 @@ public class SiphoningSpell extends AbstractRangedAreaSpell implements Thrown { DamageSource damage = damageSource(owner); - if (source.getAffinity() == Affinity.BAD) { + if (!isFriendlyTogether(source)) { if (owner != null) { float healthGain = 0; float maxHealthGain = owner.getMaxHealth() - owner.getHealth(); @@ -108,7 +108,7 @@ public class SiphoningSpell extends AbstractRangedAreaSpell implements Thrown { int radius = 4 + source.getLevel().get(); Vec3d origin = source.getOriginVector(); - int direction = source.getAffinity() == Affinity.GOOD ? 1 : -1; + int direction = !isEnemy(source) ? 1 : -1; source.spawnParticles(new Sphere(true, radius, 1, 0, 1), 1, pos -> { if (!source.getWorld().isAir(new BlockPos(pos).down())) { diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java index 295daacf..6ef04e3e 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/spell/SpellType.java @@ -5,11 +5,11 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; -import java.util.function.Function; import javax.annotation.Nullable; import com.minelittlepony.unicopia.Affinity; +import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Spell; import net.minecraft.nbt.CompoundTag; @@ -18,37 +18,37 @@ import net.minecraft.text.TranslatableText; import net.minecraft.util.Identifier; import net.minecraft.util.Util; -public class SpellType { +public class SpellType implements Affine { public static final Identifier EMPTY_ID = new Identifier("unicopia", "null"); - public static final SpellType EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, t -> null); + public static final SpellType EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, (t, a) -> null); private static final Map> REGISTRY = new HashMap<>(); private static final Map>> BY_AFFINITY = new EnumMap<>(Affinity.class); - public static final SpellType ICE = register("ice", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new); - public static final SpellType FIRE = register("fire", Affinity.GOOD, 0xFF5D00, true, FireSpell::new); - public static final SpellType INFERNO = register("inferno", Affinity.BAD, 0xF00F00, true, InfernoSpell::new); + public static final SpellType FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new); public static final SpellType SCORCH = register("scorch", Affinity.BAD, 0, true, ScorchSpell::new); + public static final SpellType FLAME = register("flame", Affinity.GOOD, 0xFF5D00, true, FireSpell::new); + public static final SpellType INFERNAL = register("infernal", Affinity.BAD, 0xF00F00, true, InfernoSpell::new); public static final SpellType SHIELD = register("shield", Affinity.NEUTRAL, 0x66CDAA, true, ShieldSpell::new); public static final SpellType VORTEX = register("vortex", Affinity.NEUTRAL, 0x4CDEE7, true, AttractiveSpell::new); public static final SpellType NECROMANCY = register("necromancy", Affinity.BAD, 0x3A3A3A, true, NecromancySpell::new); - public static final SpellType SIPHONING = register("siphon", Affinity.NEUTRAL, 0xe308ab, true, SiphoningSpell::new); + public static final SpellType SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xe308ab, true, SiphoningSpell::new); public static final SpellType DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new); public static final SpellType REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new); public static final SpellType JOUSTING = register("joust", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new); - public static final SpellType AWKWARD = register("awkward", Affinity.NEUTRAL, 0xE1239C, true, AwkwardSpell::new); - final Identifier id; - final Affinity affinity; - final int color; - final boolean obtainable; + public static final SpellType AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new); - final Function, T> factory; + private final Identifier id; + private final Affinity affinity; + private final int color; + private final boolean obtainable; - @Nullable - private String translationKey; + private final Factory factory; - SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Function, T> factory) { + private final Map translationKeys = new EnumMap<>(Affinity.class); + + SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Factory factory) { this.id = id; this.affinity = affinity; this.color = color; @@ -71,25 +71,28 @@ public class SpellType { return color; } + @Override public Affinity getAffinity() { return affinity; } - public String getTranslationKey() { - if (translationKey == null) { - translationKey = Util.createTranslationKey("spell", getId()); - } - return translationKey; + public String getTranslationKey(Affinity affinity) { + return translationKeys.computeIfAbsent(affinity, a -> Util.createTranslationKey(a.getTranslationKey(), getId())); } - public Text getName() { - return new TranslatableText(getTranslationKey()); + public Text getName(Affinity affinity) { + return new TranslatableText(getTranslationKey(affinity)); } @Nullable public T create() { + return create(getAffinity()); + } + + @Nullable + public T create(Affinity affinity) { try { - return factory.apply(this); + return factory.create(this, affinity); } catch (Exception e) { e.printStackTrace(); } @@ -97,18 +100,18 @@ public class SpellType { return null; } - public static SpellType register(Identifier id, Affinity affinity, int color, boolean obtainable, Function, T> factory) { + public static SpellType register(Identifier id, Affinity affinity, int color, boolean obtainable, Factory factory) { SpellType type = new SpellType<>(id, affinity, color, obtainable, factory); for (Affinity i : affinity.getImplicators()) { - BY_AFFINITY.computeIfAbsent(i, a -> new HashSet<>()).add(type); + byAffinity(i).add(type); } REGISTRY.put(id, type); return type; } - public static SpellType register(String name, Affinity affinity, int color, boolean obtainable, Function, T> factory) { + public static SpellType register(String name, Affinity affinity, int color, boolean obtainable, Factory factory) { return register(new Identifier("unicopia", name), affinity, color, obtainable, factory); } @@ -118,7 +121,7 @@ public class SpellType { } public static Set> byAffinity(Affinity affinity) { - return BY_AFFINITY.get(affinity); + return BY_AFFINITY.computeIfAbsent(affinity, a -> new HashSet<>()); } @SuppressWarnings("unchecked") @@ -148,4 +151,8 @@ public class SpellType { return compound; } + + public interface Factory { + T create(SpellType type, Affinity affinity); + } } diff --git a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java index df5cb893..cdec16d3 100644 --- a/src/main/java/com/minelittlepony/unicopia/client/URenderers.java +++ b/src/main/java/com/minelittlepony/unicopia/client/URenderers.java @@ -17,6 +17,7 @@ import com.minelittlepony.unicopia.client.render.BraceletFeatureRenderer; import com.minelittlepony.unicopia.client.render.FloatingArtefactEntityRenderer; import com.minelittlepony.unicopia.client.render.WingsFeatureRenderer; import com.minelittlepony.unicopia.item.ChameleonItem; +import com.minelittlepony.unicopia.item.GemstoneItem; import com.minelittlepony.unicopia.item.UItems; import com.minelittlepony.unicopia.particle.UParticles; import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry; @@ -24,6 +25,7 @@ import net.fabricmc.fabric.api.client.particle.v1.ParticleFactoryRegistry.Pendin import net.fabricmc.fabric.api.client.rendereregistry.v1.EntityRendererRegistry; import net.fabricmc.fabric.api.client.rendering.v1.BuiltinItemRendererRegistry; import net.fabricmc.fabric.api.client.rendering.v1.ColorProviderRegistry; +import net.fabricmc.fabric.api.object.builder.v1.client.model.FabricModelPredicateProviderRegistry; import net.minecraft.client.MinecraftClient; import net.minecraft.client.particle.Particle; import net.minecraft.client.particle.SpriteProvider; @@ -36,6 +38,7 @@ import net.minecraft.client.render.model.json.ModelTransformation; import net.minecraft.client.world.ClientWorld; import net.minecraft.item.DyeableItem; import net.minecraft.particle.ParticleEffect; +import net.minecraft.util.Identifier; public interface URenderers { static void bootstrap() { @@ -89,6 +92,12 @@ public interface URenderers { matrices.push(); }); + FabricModelPredicateProviderRegistry.register(UItems.GEMSTONE, new Identifier("affinity"), (stack, world, entity) -> { + return GemstoneItem.isEnchanted(stack) ? 1 + GemstoneItem.getAffinity(stack).ordinal() : 0; + }); + ColorProviderRegistry.ITEM.register((stack, i) -> { + return i > 0 || !GemstoneItem.isEnchanted(stack) ? -1 : GemstoneItem.getSpellKey(stack).getColor(); + }, UItems.GEMSTONE); } static PendingParticleFactory createFactory(ParticleSupplier supplier) { diff --git a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java index 83ad279b..56e45614 100644 --- a/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java +++ b/src/main/java/com/minelittlepony/unicopia/item/GemstoneItem.java @@ -31,17 +31,26 @@ public class GemstoneItem extends Item { @Override public void appendTooltip(ItemStack stack, @Nullable World world, List list, TooltipContext tooltipContext) { + + if (isEnchanted(stack)) { + SpellType key = getSpellKey(stack); + Affinity affinity = getAffinity(stack); + + list.add(new TranslatableText(key.getTranslationKey(affinity) + ".lore").formatted(affinity.getColor())); + } } @Override public void appendStacks(ItemGroup tab, DefaultedList items) { super.appendStacks(tab, items); if (isIn(tab)) { - SpellType.byAffinity(Affinity.GOOD).forEach(type -> { - if (type.isObtainable()) { - items.add(enchanted(getDefaultStack(), type)); - } - }); + for (Affinity i : Affinity.VALUES) { + SpellType.byAffinity(i).forEach(type -> { + if (type.isObtainable()) { + items.add(enchanted(getDefaultStack(), type, i)); + } + }); + } } } @@ -53,7 +62,7 @@ public class GemstoneItem extends Item { @Override public Text getName(ItemStack stack) { if (isEnchanted(stack)) { - return new TranslatableText(getTranslationKey(stack) + ".enchanted", getSpellKey(stack).getName()); + return new TranslatableText(getTranslationKey(stack) + ".enchanted", getSpellKey(stack).getName(getAffinity(stack))); } return super.getName(); } @@ -61,11 +70,11 @@ public class GemstoneItem extends Item { public static Stream consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType exclude, Predicate test) { SpellType key = GemstoneItem.getSpellKey(stack); - if (key == null || Objects.equals(key, exclude)) { + if (Objects.equals(key, exclude)) { return Stream.empty(); } - Spell spell = key.create(); + Spell spell = key.create(getAffinity(stack)); if (spell == null || !test.test(spell)) { return Stream.empty(); @@ -87,23 +96,31 @@ public class GemstoneItem extends Item { } public static ItemStack enchanted(ItemStack stack, SpellType type) { + return enchanted(stack, type, type.getAffinity()); + } + + public static ItemStack enchanted(ItemStack stack, SpellType type, Affinity affinity) { stack.getOrCreateTag().putString("spell", type.getId().toString()); + stack.getOrCreateTag().putInt("affinity", affinity.ordinal()); return stack; } public static ItemStack unenchanted(ItemStack stack) { - if (isEnchanted(stack)) { - stack.getTag().remove("spell"); - - if (stack.getTag().isEmpty()) { - stack.setTag(null); - } - } - + stack.removeSubTag("spell"); + stack.removeSubTag("affinity"); return stack; } public static SpellType getSpellKey(ItemStack stack) { return SpellType.getKey(isEnchanted(stack) ? new Identifier(stack.getTag().getString("spell")) : SpellType.EMPTY_ID); } + + public static Affinity getAffinity(ItemStack stack) { + Affinity fallback = getSpellKey(stack).getAffinity(); + + if (stack.hasTag() && stack.getTag().contains("affinity")) { + return Affinity.of(stack.getTag().getInt("affinity"), fallback); + } + return fallback; + } } diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java index a4cff69d..de6ee9cc 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicProjectileEntity.java @@ -76,8 +76,11 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical, @Override protected Item getDefaultItem() { - Spell spell = this.getSpell(false); - return spell == null ? Items.AIR : spell.getAffinity() == Affinity.BAD ? Items.MAGMA_CREAM : Items.SNOWBALL; + switch (getSpellOrEmpty(Spell.class, false).map(Spell::getAffinity).orElse(Affinity.NEUTRAL)) { + case GOOD: return Items.SNOWBALL; + case BAD: return Items.MAGMA_CREAM; + default: return Items.AIR; + } } @Override @@ -107,7 +110,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical, @Override public Affinity getAffinity() { - return hasSpell() ? Affinity.NEUTRAL : getSpell(true).getAffinity(); + return hasSpell() ? getSpell(true).getAffinity() : Affinity.NEUTRAL; } @Override diff --git a/src/main/resources/assets/unicopia/lang/en_us.json b/src/main/resources/assets/unicopia/lang/en_us.json index 908ff51b..014655b3 100644 --- a/src/main/resources/assets/unicopia/lang/en_us.json +++ b/src/main/resources/assets/unicopia/lang/en_us.json @@ -92,60 +92,44 @@ "item.minecraft.lingering_potion.effect.unicopia.tribe_swap_bat": "Lingering Potion of Bat Pony Metamorphosis", "item.minecraft.tipped_arrow.effect.unicopia.tribe_swap_bat": "Arrow of Bat Pony Metamorphosis", - "affinity.good": "Pure", - "affinity.neutral": "Neutral", - "affinity.curse": "Corrupt", + "spell.unicopia.frost": "Frost", + "spell.unicopia.frost.lore": "Ice I", + "curse.unicopia.scorch": "Scorching", + "curse.unicopia.scorch.lore": "Fire I", + + "spell.unicopia.flame": "Flaming", + "spell.unicopia.flame.lore": "Fire II", + + "curse.unicopia.infernal": "Infernal", + "curse.unicopia.infernal.lore": "Fire III", + "spell.unicopia.shield": "Protective", - "spell.unicopia.shield.tagline": "Protection I", - - "spell.unicopia.awkward": "Unstable", - "spell.unicopia.awkward.tagline": "*Derp*", - - "spell.unicopia.light": "Illumination", - "spell.unicopia.light.tagline": "Discovery I", - - "spell.unicopia.reveal": "Revealing", - "spell.unicopia.reveal.tagline": "Discovery II", - - "spell.unicopia.flame": "Burning", - "spell.unicopia.flame.tagline": "Fire I", - - "spell.unicopia.fire": "Flaming", - "spell.unicopia.fire.tagline": "Fire II", - - "spell.unicopia.vortex": "Retention", - "spell.unicopia.vortex.tagline": "Containment I", - - "spell.unicopia.siphon": "Siphoning", - "spell.unicopia.siphon.tagline": "Energy II", - - "spell.unicopia.ice": "Frost", - "spell.unicopia.ice.tagline": "Ice I", + "spell.unicopia.shield.lore": "Protection I", "curse.unicopia.shield": "Repulsive", - "curse.unicopia.shield.tagline": "Hostility I", - - "curse.unicopia.darkness": "Dark", - "curse.unicopia.darkness.tagline": "Golomancy I/Resurrection II", - - "curse.unicopia.harm": "Harmful", - "curse.unicopia.harm.tagline": "Hostility II", - - "curse.unicopia.awkward": "Awkward", - "curse.unicopia.awkward.tagline": "*Derp*", + "curse.unicopia.shield.lore": "Hostility I", + + "spell.unicopia.vortex": "Attractive", + "spell.unicopia.vortex.lore": "Containment I", "curse.unicopia.vortex": "Suffering", - "curse.unicopia.vortex.tagline": "Torture I", - + "curse.unicopia.vortex.lore": "Torture I", + "curse.unicopia.necromancy": "Resurrection", - "curse.unicopia.necromancy.tagline": "Resurrection I", + "curse.unicopia.necromancy.lore": "Resurrection I", + + "spell.unicopia.siphoning": "Siphoning", + "spell.unicopia.siphoning.lore": "Energy II", - "curse.unicopia.inferno": "Inferno", - "curse.unicopia.inferno.tagline": "Fire III", + "curse.unicopia.siphoning": "Siphoning", + "curse.unicopia.siphoning.lore": "Energy III", + + "spell.unicopia.reveal": "Revealing", + "spell.unicopia.reveal.lore": "Discovery II", - "curse.unicopia.siphon": "Siphoning", - "curse.unicopia.siphon.tagline": "Energy III", + "spell.unicopia.awkward": "Unstable", + "spell.unicopia.awkward.lore": "Chaos I", "toxicity.safe.name": "Safe", "toxicity.mild.name": "Mildly Toxic", diff --git a/src/main/resources/assets/unicopia/models/item/gemstone.json b/src/main/resources/assets/unicopia/models/item/gemstone.json index 422261ea..c3865b7c 100644 --- a/src/main/resources/assets/unicopia/models/item/gemstone.json +++ b/src/main/resources/assets/unicopia/models/item/gemstone.json @@ -2,5 +2,19 @@ "parent": "item/generated", "textures": { "layer0": "unicopia:item/gemstone" - } + }, + "overrides": [ + { + "predicate": { + "affinity": 1 + }, + "model": "unicopia:item/gemstone_pure" + }, + { + "predicate": { + "affinity": 3 + }, + "model": "unicopia:item/gemstone_corrupted" + } + ] } diff --git a/src/main/resources/assets/unicopia/models/item/gemstone_corrupted.json b/src/main/resources/assets/unicopia/models/item/gemstone_corrupted.json new file mode 100644 index 00000000..b3647430 --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/gemstone_corrupted.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/gemstone_corrupted" + } +} diff --git a/src/main/resources/assets/unicopia/models/item/gemstone_pure.json b/src/main/resources/assets/unicopia/models/item/gemstone_pure.json new file mode 100644 index 00000000..2aac6a7c --- /dev/null +++ b/src/main/resources/assets/unicopia/models/item/gemstone_pure.json @@ -0,0 +1,6 @@ +{ + "parent": "item/generated", + "textures": { + "layer0": "unicopia:item/gemstone_pure" + } +} diff --git a/src/main/resources/assets/unicopia/textures/item/gemstone_corrupted.png b/src/main/resources/assets/unicopia/textures/item/gemstone_corrupted.png new file mode 100644 index 0000000000000000000000000000000000000000..8268fc1ae456a7b11fb625ecf4c1aa438815b21f GIT binary patch literal 3285 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 TJ-=2300000NkvXXu0mjfRA)>F literal 0 HcmV?d00001 diff --git a/src/main/resources/assets/unicopia/textures/item/gemstone_pure.png b/src/main/resources/assets/unicopia/textures/item/gemstone_pure.png new file mode 100644 index 0000000000000000000000000000000000000000..bef8f3cfaab4c2041c986043f603144f4cf9b0d2 GIT binary patch literal 3262 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 literal 0 HcmV?d00001