More work on spells and gemstones

This commit is contained in:
Sollace 2021-03-02 15:40:37 +02:00
parent 4843a5c5f8
commit a58c6a0a44
28 changed files with 213 additions and 157 deletions

View file

@ -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];
}
}

View file

@ -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;
}
}

View file

@ -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.
*/

View file

@ -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

View file

@ -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());
}
}

View file

@ -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();

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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

View file

@ -39,8 +39,8 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements Attached {
private final Map<UUID, Target> 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;

View file

@ -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())) {

View file

@ -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<T extends Spell> {
public class SpellType<T extends Spell> 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<Identifier, SpellType<?>> REGISTRY = new HashMap<>();
private static final Map<Affinity, Set<SpellType<?>>> BY_AFFINITY = new EnumMap<>(Affinity.class);
public static final SpellType<IceSpell> ICE = register("ice", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new);
public static final SpellType<FireSpell> FIRE = register("fire", Affinity.GOOD, 0xFF5D00, true, FireSpell::new);
public static final SpellType<InfernoSpell> INFERNO = register("inferno", Affinity.BAD, 0xF00F00, true, InfernoSpell::new);
public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xBDBDF9, true, IceSpell::new);
public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0, true, ScorchSpell::new);
public static final SpellType<FireSpell> FLAME = register("flame", Affinity.GOOD, 0xFF5D00, true, FireSpell::new);
public static final SpellType<InfernoSpell> INFERNAL = register("infernal", Affinity.BAD, 0xF00F00, true, InfernoSpell::new);
public static final SpellType<ShieldSpell> SHIELD = register("shield", Affinity.NEUTRAL, 0x66CDAA, true, ShieldSpell::new);
public static final SpellType<AttractiveSpell> VORTEX = register("vortex", Affinity.NEUTRAL, 0x4CDEE7, true, AttractiveSpell::new);
public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0x3A3A3A, true, NecromancySpell::new);
public static final SpellType<SiphoningSpell> SIPHONING = register("siphon", Affinity.NEUTRAL, 0xe308ab, true, SiphoningSpell::new);
public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xe308ab, true, SiphoningSpell::new);
public static final SpellType<DisguiseSpell> DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, DisguiseSpell::new);
public static final SpellType<RevealingSpell> REVEALING = register("reveal", Affinity.GOOD, 0x5CE81F, true, RevealingSpell::new);
public static final SpellType<JoustingSpell> JOUSTING = register("joust", Affinity.GOOD, 0xBDBDF9, false, JoustingSpell::new);
public static final SpellType<AwkwardSpell> 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<AwkwardSpell> AWKWARD = register("awkward", Affinity.GOOD, 0xE1239C, true, AwkwardSpell::new);
final Function<SpellType<?>, 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<T> factory;
SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Function<SpellType<?>, T> factory) {
private final Map<Affinity, String> translationKeys = new EnumMap<>(Affinity.class);
SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
this.id = id;
this.affinity = affinity;
this.color = color;
@ -71,25 +71,28 @@ public class SpellType<T extends Spell> {
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<T extends Spell> {
return null;
}
public static <T extends Spell> SpellType<T> register(Identifier id, Affinity affinity, int color, boolean obtainable, Function<SpellType<?>, T> factory) {
public static <T extends Spell> SpellType<T> register(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
SpellType<T> 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 <T extends Spell> SpellType<T> register(String name, Affinity affinity, int color, boolean obtainable, Function<SpellType<?>, T> factory) {
public static <T extends Spell> SpellType<T> register(String name, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
return register(new Identifier("unicopia", name), affinity, color, obtainable, factory);
}
@ -118,7 +121,7 @@ public class SpellType<T extends Spell> {
}
public static Set<SpellType<?>> 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<T extends Spell> {
return compound;
}
public interface Factory<T extends Spell> {
T create(SpellType<T> type, Affinity affinity);
}
}

View file

@ -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 <T extends ParticleEffect> PendingParticleFactory<T> createFactory(ParticleSupplier<T> supplier) {

View file

@ -31,17 +31,26 @@ public class GemstoneItem extends Item {
@Override
public void appendTooltip(ItemStack stack, @Nullable World world, List<Text> 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<ItemStack> 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<Spell> consumeSpell(ItemStack stack, PlayerEntity player, @Nullable SpellType<?> exclude, Predicate<Spell> test) {
SpellType<Spell> 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 <T extends Spell> SpellType<T> 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;
}
}

View file

@ -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

View file

@ -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",

View file

@ -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"
}
]
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:item/gemstone_corrupted"
}
}

View file

@ -0,0 +1,6 @@
{
"parent": "item/generated",
"textures": {
"layer0": "unicopia:item/gemstone_pure"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB