mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Serialize spell type and traits together, and make affinity names translatable
This commit is contained in:
parent
1d15630566
commit
95ffe5b0b5
21 changed files with 188 additions and 130 deletions
|
@ -2,8 +2,10 @@ package com.minelittlepony.unicopia;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
import net.minecraft.text.Text;
|
||||||
import net.minecraft.util.Formatting;
|
import net.minecraft.util.Formatting;
|
||||||
import net.minecraft.util.StringIdentifiable;
|
import net.minecraft.util.StringIdentifiable;
|
||||||
|
import net.minecraft.util.Util;
|
||||||
|
|
||||||
public enum Affinity implements StringIdentifiable {
|
public enum Affinity implements StringIdentifiable {
|
||||||
GOOD(Formatting.BLUE, -1, 0),
|
GOOD(Formatting.BLUE, -1, 0),
|
||||||
|
@ -20,10 +22,13 @@ public enum Affinity implements StringIdentifiable {
|
||||||
|
|
||||||
public static final Affinity[] VALUES = values();
|
public static final Affinity[] VALUES = values();
|
||||||
|
|
||||||
|
private final String translationKey;
|
||||||
|
|
||||||
Affinity(Formatting color, int corruption, float alignment) {
|
Affinity(Formatting color, int corruption, float alignment) {
|
||||||
this.color = color;
|
this.color = color;
|
||||||
this.corruption = corruption;
|
this.corruption = corruption;
|
||||||
this.alignment = alignment;
|
this.alignment = alignment;
|
||||||
|
this.translationKey = Util.createTranslationKey("affinity", Unicopia.id(name().toLowerCase(Locale.ROOT)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -36,7 +41,11 @@ public enum Affinity implements StringIdentifiable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTranslationKey() {
|
public String getTranslationKey() {
|
||||||
return this == BAD ? "curse" : "spell";
|
return translationKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Text getDisplayName() {
|
||||||
|
return Text.translatable(getTranslationKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCorruption() {
|
public int getCorruption() {
|
||||||
|
|
|
@ -108,9 +108,7 @@ public class UnicornCastingAbility extends AbstractSpellCastingAbility {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean hasExact = player.getSpellSlot().contains(spell);
|
boolean hasExact = player.getSpellSlot().contains(spell);
|
||||||
boolean removed = player.getSpellSlot().removeWhere(s -> {
|
boolean removed = !spell.isStackable() && player.getSpellSlot().removeWhere(s -> s.findMatches(spell.type()).findAny().isPresent(), true);
|
||||||
return s.findMatches(spell.type()).findAny().isPresent() && (spell.isEmpty() || !SpellType.PLACED_SPELL.test(s));
|
|
||||||
}, true);
|
|
||||||
player.subtractEnergyCost(removed ? 2 : 4);
|
player.subtractEnergyCost(removed ? 2 : 4);
|
||||||
if (!hasExact && !spell.isEmpty()) {
|
if (!hasExact && !spell.isEmpty()) {
|
||||||
Spell s = spell.apply(player, CastingMethod.DIRECT);
|
Spell s = spell.apply(player, CastingMethod.DIRECT);
|
||||||
|
|
|
@ -5,11 +5,8 @@ import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
|
||||||
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
import com.minelittlepony.unicopia.projectile.ProjectileDelegate;
|
||||||
|
|
||||||
|
@ -26,10 +23,10 @@ public abstract class AbstractDelegatingSpell implements Spell,
|
||||||
|
|
||||||
private UUID uuid = UUID.randomUUID();
|
private UUID uuid = UUID.randomUUID();
|
||||||
|
|
||||||
private final SpellType<?> type;
|
private final CustomisedSpellType<?> type;
|
||||||
|
|
||||||
public AbstractDelegatingSpell(CustomisedSpellType<?> type) {
|
public AbstractDelegatingSpell(CustomisedSpellType<?> type) {
|
||||||
this.type = type.type();
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract Collection<Spell> getDelegates();
|
public abstract Collection<Spell> getDelegates();
|
||||||
|
@ -45,20 +42,10 @@ public abstract class AbstractDelegatingSpell implements Spell,
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Affinity getAffinity() {
|
public CustomisedSpellType<?> getTypeAndTraits() {
|
||||||
return Affinity.NEUTRAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpellType<?> getType() {
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public SpellTraits getTraits() {
|
|
||||||
return getDelegates().stream().map(Spell::getTraits).reduce(SpellTraits.EMPTY, SpellTraits::union);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final UUID getUuid() {
|
public final UUID getUuid() {
|
||||||
return uuid;
|
return uuid;
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkDetachment(Caster<?> source, EntityValues<?> target) {
|
private void checkDetachment(Caster<?> source, EntityValues<?> target) {
|
||||||
if (getWorld(source).map(Ether::get).map(ether -> ether.get(getType(), target, placedSpellId)).isEmpty()) {
|
if (getWorld(source).map(Ether::get).map(ether -> ether.get(getTypeAndTraits().type(), target, placedSpellId)).isEmpty()) {
|
||||||
setDead();
|
setDead();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -202,7 +202,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell implements OrientedS
|
||||||
if (!source.isClient()) {
|
if (!source.isClient()) {
|
||||||
castEntity.getTarget().ifPresent(target -> {
|
castEntity.getTarget().ifPresent(target -> {
|
||||||
getWorld(source).map(Ether::get)
|
getWorld(source).map(Ether::get)
|
||||||
.ifPresent(ether -> ether.remove(getType(), target.uuid()));
|
.ifPresent(ether -> ether.remove(getTypeAndTraits().type(), target.uuid()));
|
||||||
});
|
});
|
||||||
castEntity.set(null);
|
castEntity.set(null);
|
||||||
getSpellEntity(source).ifPresent(e -> {
|
getSpellEntity(source).ifPresent(e -> {
|
||||||
|
|
|
@ -7,11 +7,12 @@ import java.util.stream.Stream;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.spongepowered.include.com.google.common.base.Objects;
|
import org.spongepowered.include.com.google.common.base.Objects;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
|
||||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||||
|
|
||||||
import net.minecraft.nbt.NbtCompound;
|
import net.minecraft.nbt.NbtCompound;
|
||||||
|
@ -24,14 +25,18 @@ public interface Spell extends NbtSerialisable, Affine {
|
||||||
Serializer<Spell> SERIALIZER = Serializer.of(Spell::readNbt, Spell::writeNbt);
|
Serializer<Spell> SERIALIZER = Serializer.of(Spell::readNbt, Spell::writeNbt);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the registered type of this spell.
|
* Returns the full type that describes this spell.
|
||||||
*/
|
*/
|
||||||
SpellType<?> getType();
|
CustomisedSpellType<?> getTypeAndTraits();
|
||||||
|
|
||||||
/**
|
default boolean isOf(SpellType<?> type) {
|
||||||
* Gets the traits of this spell.
|
return getTypeAndTraits().type() == type;
|
||||||
*/
|
}
|
||||||
SpellTraits getTraits();
|
|
||||||
|
@Override
|
||||||
|
default Affinity getAffinity() {
|
||||||
|
return getTypeAndTraits().type().getAffinity();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The unique id of this particular spell instance.
|
* The unique id of this particular spell instance.
|
||||||
|
@ -132,15 +137,8 @@ public interface Spell extends NbtSerialisable, Affine {
|
||||||
@Nullable
|
@Nullable
|
||||||
static <T extends Spell> T readNbt(@Nullable NbtCompound compound) {
|
static <T extends Spell> T readNbt(@Nullable NbtCompound compound) {
|
||||||
try {
|
try {
|
||||||
if (compound != null && compound.contains("effect_id")) {
|
if (compound != null) {
|
||||||
@SuppressWarnings("unchecked")
|
return CustomisedSpellType.<T>fromNBT(compound).create(compound);
|
||||||
T effect = (T)SpellType.getKey(compound).withTraits().create();
|
|
||||||
|
|
||||||
if (effect != null) {
|
|
||||||
effect.fromNBT(compound);
|
|
||||||
}
|
|
||||||
|
|
||||||
return effect;
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Unicopia.LOGGER.fatal("Invalid spell nbt {}", e);
|
Unicopia.LOGGER.fatal("Invalid spell nbt {}", e);
|
||||||
|
@ -155,7 +153,7 @@ public interface Spell extends NbtSerialisable, Affine {
|
||||||
|
|
||||||
static NbtCompound writeNbt(Spell effect) {
|
static NbtCompound writeNbt(Spell effect) {
|
||||||
NbtCompound compound = effect.toNBT();
|
NbtCompound compound = effect.toNBT();
|
||||||
effect.getType().toNbt(compound);
|
effect.getTypeAndTraits().toNbt(compound);
|
||||||
return compound;
|
return compound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ public final class SpellReference<T extends Spell> implements NbtSerialisable {
|
||||||
public void toNBT(NbtCompound compound) {
|
public void toNBT(NbtCompound compound) {
|
||||||
if (spell != null && !spell.isDead()) {
|
if (spell != null && !spell.isDead()) {
|
||||||
spell.toNBT(compound);
|
spell.toNBT(compound);
|
||||||
spell.getType().toNbt(compound);
|
spell.getTypeAndTraits().type().toNbt(compound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||||
|
@ -17,7 +16,7 @@ public abstract class AbstractSpell implements Spell {
|
||||||
private boolean hidden;
|
private boolean hidden;
|
||||||
private boolean destroyed;
|
private boolean destroyed;
|
||||||
|
|
||||||
private CustomisedSpellType<?> type;
|
private final CustomisedSpellType<?> type;
|
||||||
|
|
||||||
private UUID uuid = UUID.randomUUID();
|
private UUID uuid = UUID.randomUUID();
|
||||||
|
|
||||||
|
@ -30,17 +29,16 @@ public abstract class AbstractSpell implements Spell {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected final SpellType<?> getType() {
|
||||||
public final SpellType<?> getType() {
|
|
||||||
return type.type();
|
return type.type();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
public final CustomisedSpellType<?> getTypeAndTraits() {
|
public final CustomisedSpellType<?> getTypeAndTraits() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
protected final SpellTraits getTraits() {
|
||||||
public final SpellTraits getTraits() {
|
|
||||||
return type.traits();
|
return type.traits();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,11 +78,6 @@ public abstract class AbstractSpell implements Spell {
|
||||||
this.hidden = hidden;
|
this.hidden = hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Affinity getAffinity() {
|
|
||||||
return getType().getAffinity();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onDestroyed(Caster<?> caster) {
|
protected void onDestroyed(Caster<?> caster) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,9 +114,6 @@ public abstract class AbstractSpell implements Spell {
|
||||||
dying = compound.getBoolean("dying");
|
dying = compound.getBoolean("dying");
|
||||||
dead = compound.getBoolean("dead");
|
dead = compound.getBoolean("dead");
|
||||||
hidden = compound.getBoolean("hidden");
|
hidden = compound.getBoolean("hidden");
|
||||||
if (compound.contains("traits")) {
|
|
||||||
type = type.type().withTraits(SpellTraits.fromNbt(compound.getCompound("traits")).orElse(SpellTraits.EMPTY));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,10 @@ public record CustomisedSpellType<T extends Spell> (
|
||||||
return type.isEmpty();
|
return type.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isStackable() {
|
||||||
|
return type().isStackable();
|
||||||
|
}
|
||||||
|
|
||||||
public T create() {
|
public T create() {
|
||||||
try {
|
try {
|
||||||
return type.getFactory().create(this);
|
return type.getFactory().create(this);
|
||||||
|
@ -31,6 +35,14 @@ public record CustomisedSpellType<T extends Spell> (
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public T create(NbtCompound compound) {
|
||||||
|
T spell = create();
|
||||||
|
if (spell != null) {
|
||||||
|
spell.fromNBT(compound);
|
||||||
|
}
|
||||||
|
return spell;
|
||||||
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public T apply(Caster<?> caster, CastingMethod method) {
|
public T apply(Caster<?> caster, CastingMethod method) {
|
||||||
|
@ -50,8 +62,8 @@ public record CustomisedSpellType<T extends Spell> (
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(Spell spell) {
|
public boolean test(@Nullable Spell spell) {
|
||||||
return type.test(spell) && spell.getTraits().equals(traits);
|
return spell != null && spell.getTypeAndTraits().equals(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public ItemStack getDefaultStack() {
|
public ItemStack getDefaultStack() {
|
||||||
|
@ -62,17 +74,14 @@ public record CustomisedSpellType<T extends Spell> (
|
||||||
return isEmpty() ? TypedActionResult.fail(this) : TypedActionResult.pass(this);
|
return isEmpty() ? TypedActionResult.fail(this) : TypedActionResult.pass(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NbtCompound toNBT() {
|
public NbtCompound toNbt(NbtCompound compound) {
|
||||||
NbtCompound tag = new NbtCompound();
|
type.toNbt(compound);
|
||||||
type.toNbt(tag);
|
compound.put("traits", traits.toNbt());
|
||||||
tag.put("traits", traits.toNbt());
|
return compound;
|
||||||
return tag;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static CustomisedSpellType<?> fromNBT(NbtCompound compound) {
|
public static <T extends Spell> CustomisedSpellType<T> fromNBT(NbtCompound compound) {
|
||||||
SpellType<?> type = SpellType.getKey(compound);
|
SpellType<T> type = SpellType.getKey(compound);
|
||||||
SpellTraits traits = SpellTraits.fromNbt(compound.getCompound("traits")).orElse(type.getTraits());
|
return type.withTraits(SpellTraits.fromNbt(compound.getCompound("traits")).orElse(type.getTraits()));
|
||||||
|
|
||||||
return type.withTraits(traits);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,47 +34,47 @@ import net.minecraft.server.command.ServerCommandSource;
|
||||||
|
|
||||||
public final class SpellType<T extends Spell> implements Affine, SpellPredicate<T> {
|
public final class SpellType<T extends Spell> implements Affine, SpellPredicate<T> {
|
||||||
public static final Identifier EMPTY_ID = Unicopia.id("none");
|
public static final Identifier EMPTY_ID = Unicopia.id("none");
|
||||||
public static final SpellType<?> EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, GemstoneItem.Shape.ROUND, SpellTraits.EMPTY, t -> null);
|
public static final SpellType<?> EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, false, GemstoneItem.Shape.ROUND, SpellTraits.EMPTY, t -> null);
|
||||||
|
|
||||||
public static final Registry<SpellType<?>> REGISTRY = RegistryUtils.createSimple(Unicopia.id("spells"));
|
public static final Registry<SpellType<?>> REGISTRY = RegistryUtils.createSimple(Unicopia.id("spells"));
|
||||||
public static final RegistryKey<? extends Registry<SpellType<?>>> REGISTRY_KEY = REGISTRY.getKey();
|
public static final RegistryKey<? extends Registry<SpellType<?>>> REGISTRY_KEY = REGISTRY.getKey();
|
||||||
|
|
||||||
private static final DynamicCommandExceptionType UNKNOWN_SPELL_TYPE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("spell_type.unknown", id));
|
private static final DynamicCommandExceptionType UNKNOWN_SPELL_TYPE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("spell_type.unknown", id));
|
||||||
|
|
||||||
public static final SpellType<PlaceableSpell> PLACED_SPELL = register("placed", Affinity.NEUTRAL, 0, false, GemstoneItem.Shape.DONUT, SpellTraits.EMPTY, PlaceableSpell::new);
|
public static final SpellType<PlaceableSpell> PLACED_SPELL = register("placed", builder(PlaceableSpell::new).affinity(Affinity.NEUTRAL).unobtainable().stackable().shape(GemstoneItem.Shape.DONUT));
|
||||||
public static final SpellType<ThrowableSpell> THROWN_SPELL = register("thrown", Affinity.NEUTRAL, 0, false, GemstoneItem.Shape.DONUT, SpellTraits.EMPTY, ThrowableSpell::new);
|
public static final SpellType<ThrowableSpell> THROWN_SPELL = register("thrown", builder(ThrowableSpell::new).affinity(Affinity.NEUTRAL).unobtainable().shape(GemstoneItem.Shape.DONUT));
|
||||||
|
|
||||||
public static final SpellType<DispersableDisguiseSpell> CHANGELING_DISGUISE = register("disguise", Affinity.BAD, 0x19E48E, false, GemstoneItem.Shape.ARROW, SpellTraits.EMPTY, DispersableDisguiseSpell::new);
|
public static final SpellType<DispersableDisguiseSpell> CHANGELING_DISGUISE = register("disguise", builder(DispersableDisguiseSpell::new).affinity(Affinity.BAD).color(0x19E48E).unobtainable().shape(GemstoneItem.Shape.ARROW));
|
||||||
public static final SpellType<ChangelingFeedingSpell> FEED = register("feed", Affinity.BAD, 0xBDBDF9, false, GemstoneItem.Shape.ARROW, SpellTraits.EMPTY, ChangelingFeedingSpell::new);
|
public static final SpellType<ChangelingFeedingSpell> FEED = register("feed", SpellType.<ChangelingFeedingSpell>builder(ChangelingFeedingSpell::new).affinity(Affinity.BAD).color(0xBDBDF9).unobtainable().shape(GemstoneItem.Shape.ARROW));
|
||||||
public static final SpellType<RainboomAbilitySpell> RAINBOOM = register("rainboom", Affinity.GOOD, 0xBDBDF9, false, GemstoneItem.Shape.ROCKET, SpellTraits.EMPTY, RainboomAbilitySpell::new);
|
public static final SpellType<RainboomAbilitySpell> RAINBOOM = register("rainboom", builder(RainboomAbilitySpell::new).color(0xBDBDF9).unobtainable().shape(GemstoneItem.Shape.ROCKET));
|
||||||
public static final SpellType<RageAbilitySpell> RAGE = register("rage", Affinity.GOOD, 0xBDBDF9, false, GemstoneItem.Shape.FLAME, SpellTraits.EMPTY, RageAbilitySpell::new);
|
public static final SpellType<RageAbilitySpell> RAGE = register("rage", builder(RageAbilitySpell::new).color(0xBDBDF9).unobtainable().shape(GemstoneItem.Shape.FLAME));
|
||||||
public static final SpellType<TimeControlAbilitySpell> TIME_CONTROL = register("time_control", Affinity.GOOD, 0xBDBDF9, false, GemstoneItem.Shape.STAR, SpellTraits.EMPTY, TimeControlAbilitySpell::new);
|
public static final SpellType<TimeControlAbilitySpell> TIME_CONTROL = register("time_control", builder(TimeControlAbilitySpell::new).color(0xBDBDF9).unobtainable().shape(GemstoneItem.Shape.STAR));
|
||||||
|
|
||||||
public static final SpellType<IceSpell> FROST = register("frost", Affinity.GOOD, 0xEABBFF, true, GemstoneItem.Shape.TRIANGLE, IceSpell.DEFAULT_TRAITS, IceSpell::new);
|
public static final SpellType<IceSpell> FROST = register("frost", builder(IceSpell::new).color(0xEABBFF).shape(GemstoneItem.Shape.TRIANGLE).traits(IceSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<ChillingBreathSpell> CHILLING_BREATH = register("chilling_breath", Affinity.NEUTRAL, 0xFFEAFF, true, GemstoneItem.Shape.TRIANGLE, ChillingBreathSpell.DEFAULT_TRAITS, ChillingBreathSpell::new);
|
public static final SpellType<ChillingBreathSpell> CHILLING_BREATH = register("chilling_breath", builder(ChillingBreathSpell::new).affinity(Affinity.NEUTRAL).color(0xFFEAFF).shape(GemstoneItem.Shape.TRIANGLE).traits(ChillingBreathSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<ScorchSpell> SCORCH = register("scorch", Affinity.BAD, 0xF8EC1F, true, GemstoneItem.Shape.FLAME, ScorchSpell.DEFAULT_TRAITS, ScorchSpell::new);
|
public static final SpellType<ScorchSpell> SCORCH = register("scorch", builder(ScorchSpell::new).affinity(Affinity.BAD).color(0xF8EC1F).shape(GemstoneItem.Shape.FLAME).traits(ScorchSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<FireSpell> FLAME = register("flame", Affinity.GOOD, 0xFFBB99, true, GemstoneItem.Shape.FLAME, FireSpell.DEFAULT_TRAITS, FireSpell::new);
|
public static final SpellType<FireSpell> FLAME = register("flame", builder(FireSpell::new).color(0xFFBB99).shape(GemstoneItem.Shape.FLAME).traits(FireSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<InfernoSpell> INFERNAL = register("infernal", Affinity.BAD, 0xFFAA00, true, GemstoneItem.Shape.FLAME, InfernoSpell.DEFAULT_TRAITS, InfernoSpell::new);
|
public static final SpellType<InfernoSpell> INFERNAL = register("infernal", builder(InfernoSpell::new).affinity(Affinity.BAD).color(0xFFAA00).shape(GemstoneItem.Shape.FLAME).traits(InfernoSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<ShieldSpell> SHIELD = register("shield", Affinity.NEUTRAL, 0x66CDAA, true, GemstoneItem.Shape.SHIELD, ShieldSpell.DEFAULT_TRAITS, ShieldSpell::new);
|
public static final SpellType<ShieldSpell> SHIELD = register("shield", builder(ShieldSpell::new).affinity(Affinity.NEUTRAL).color(0x66CDAA).shape(GemstoneItem.Shape.SHIELD).traits(ShieldSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<AreaProtectionSpell> ARCANE_PROTECTION = register("arcane_protection", Affinity.BAD, 0x99CDAA, true, GemstoneItem.Shape.SHIELD, AreaProtectionSpell.DEFAULT_TRAITS, AreaProtectionSpell::new);
|
public static final SpellType<AreaProtectionSpell> ARCANE_PROTECTION = register("arcane_protection", builder(AreaProtectionSpell::new).affinity(Affinity.BAD).color(0x99CDAA).shape(GemstoneItem.Shape.SHIELD).traits(AreaProtectionSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<AttractiveSpell> VORTEX = register("vortex", Affinity.NEUTRAL, 0xFFEA88, true, GemstoneItem.Shape.VORTEX, AttractiveSpell.DEFAULT_TRAITS, AttractiveSpell::new);
|
public static final SpellType<AttractiveSpell> VORTEX = register("vortex", builder(AttractiveSpell::new).affinity(Affinity.NEUTRAL).color(0xFFEA88).shape(GemstoneItem.Shape.VORTEX).traits(AttractiveSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<DarkVortexSpell> DARK_VORTEX = register("dark_vortex", Affinity.BAD, 0xA33333, true, GemstoneItem.Shape.VORTEX, DarkVortexSpell.DEFAULT_TRAITS, DarkVortexSpell::new);
|
public static final SpellType<DarkVortexSpell> DARK_VORTEX = register("dark_vortex", builder(DarkVortexSpell::new).affinity(Affinity.BAD).color(0xA33333).shape(GemstoneItem.Shape.VORTEX).traits(DarkVortexSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", Affinity.BAD, 0xFA3A3A, true, GemstoneItem.Shape.SKULL, SpellTraits.EMPTY, NecromancySpell::new);
|
public static final SpellType<NecromancySpell> NECROMANCY = register("necromancy", builder(NecromancySpell::new).affinity(Affinity.BAD).color(0xFA3A3A).shape(GemstoneItem.Shape.SKULL));
|
||||||
public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", Affinity.NEUTRAL, 0xFFA3AA, true, GemstoneItem.Shape.LAMBDA, SpellTraits.EMPTY, SiphoningSpell::new);
|
public static final SpellType<SiphoningSpell> SIPHONING = register("siphoning", builder(SiphoningSpell::new).affinity(Affinity.NEUTRAL).color(0xFFA3AA).shape(GemstoneItem.Shape.LAMBDA));
|
||||||
public static final SpellType<DisperseIllusionSpell> REVEALING = register("reveal", Affinity.GOOD, 0xFFFFAF, true, GemstoneItem.Shape.CROSS, SpellTraits.EMPTY, DisperseIllusionSpell::new);
|
public static final SpellType<DisperseIllusionSpell> REVEALING = register("reveal", builder(DisperseIllusionSpell::new).color(0xFFFFAF).shape(GemstoneItem.Shape.CROSS));
|
||||||
public static final SpellType<AwkwardSpell> AWKWARD = register("awkward", Affinity.GOOD, 0x3A59FF, true, GemstoneItem.Shape.ICE, SpellTraits.EMPTY, AwkwardSpell::new);
|
public static final SpellType<AwkwardSpell> AWKWARD = register("awkward", builder(AwkwardSpell::new).affinity(Affinity.NEUTRAL).color(0x3A59FF).shape(GemstoneItem.Shape.ICE));
|
||||||
public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", Affinity.GOOD, 0x19E48E, true, GemstoneItem.Shape.BRUSH, SpellTraits.EMPTY, TransformationSpell::new);
|
public static final SpellType<TransformationSpell> TRANSFORMATION = register("transformation", builder(TransformationSpell::new).color(0x19E48E).shape(GemstoneItem.Shape.BRUSH));
|
||||||
public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", Affinity.GOOD, 0x00EEFF, true, GemstoneItem.Shape.LAMBDA, FeatherFallSpell.DEFAULT_TRAITS, FeatherFallSpell::new);
|
public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", builder(FeatherFallSpell::new).color(0x00EEFF).shape(GemstoneItem.Shape.LAMBDA).traits(FeatherFallSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<CatapultSpell> CATAPULT = register("catapult", Affinity.GOOD, 0x22FF00, true, GemstoneItem.Shape.ROCKET, CatapultSpell.DEFAULT_TRAITS, CatapultSpell::new);
|
public static final SpellType<CatapultSpell> CATAPULT = register("catapult", builder(CatapultSpell::new).color(0x22FF00).shape(GemstoneItem.Shape.ROCKET).traits(CatapultSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<FireBoltSpell> FIRE_BOLT = register("fire_bolt", Affinity.GOOD, 0xFF8811, true, GemstoneItem.Shape.FLAME, FireBoltSpell.DEFAULT_TRAITS, FireBoltSpell::new);
|
public static final SpellType<FireBoltSpell> FIRE_BOLT = register("fire_bolt", builder(FireBoltSpell::new).color(0xFF8811).shape(GemstoneItem.Shape.FLAME).traits(FireBoltSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<LightSpell> LIGHT = register("light", Affinity.GOOD, 0xEEFFAA, true, GemstoneItem.Shape.STAR, LightSpell.DEFAULT_TRAITS, LightSpell::new);
|
public static final SpellType<LightSpell> LIGHT = register("light", builder(LightSpell::new).color(0xEEFFAA).shape(GemstoneItem.Shape.STAR).traits(LightSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<DisplacementSpell> DISPLACEMENT = register("displacement", Affinity.NEUTRAL, 0x9900FF, true, GemstoneItem.Shape.BRUSH, PortalSpell.DEFAULT_TRAITS, DisplacementSpell::new);
|
public static final SpellType<DisplacementSpell> DISPLACEMENT = register("displacement", builder(DisplacementSpell::new).affinity(Affinity.NEUTRAL).color(0x9900FF).shape(GemstoneItem.Shape.BRUSH).traits(PortalSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<PortalSpell> PORTAL = register("portal", Affinity.GOOD, 0x99FFFF, true, GemstoneItem.Shape.RING, PortalSpell.DEFAULT_TRAITS, PortalSpell::new);
|
public static final SpellType<PortalSpell> PORTAL = register("portal", builder(PortalSpell::new).color(0x99FFFF).shape(GemstoneItem.Shape.RING).traits(PortalSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<MimicSpell> MIMIC = register("mimic", Affinity.GOOD, 0xFFFF00, true, GemstoneItem.Shape.ARROW, SpellTraits.EMPTY, MimicSpell::new);
|
public static final SpellType<MimicSpell> MIMIC = register("mimic", builder(MimicSpell::new).color(0xFFFF00).shape(GemstoneItem.Shape.ARROW));
|
||||||
public static final SpellType<MindSwapSpell> MIND_SWAP = register("mind_swap", Affinity.BAD, 0xF9FF99, true, GemstoneItem.Shape.WAVE, SpellTraits.EMPTY, MindSwapSpell::new);
|
public static final SpellType<MindSwapSpell> MIND_SWAP = register("mind_swap", builder(MindSwapSpell::new).affinity(Affinity.BAD).color(0xF9FF99).shape(GemstoneItem.Shape.WAVE));
|
||||||
public static final SpellType<HydrophobicSpell> HYDROPHOBIC = register("hydrophobic", Affinity.NEUTRAL, 0xF999FF, true, GemstoneItem.Shape.ROCKET, SpellTraits.EMPTY, s -> new HydrophobicSpell(s, FluidTags.WATER));
|
public static final SpellType<HydrophobicSpell> HYDROPHOBIC = register("hydrophobic", SpellType.<HydrophobicSpell>builder(s -> new HydrophobicSpell(s, FluidTags.WATER)).affinity(Affinity.NEUTRAL).color(0xF999FF).shape(GemstoneItem.Shape.ROCKET));
|
||||||
public static final SpellType<BubbleSpell> BUBBLE = register("bubble", Affinity.NEUTRAL, 0xF999FF, true, GemstoneItem.Shape.DONUT, BubbleSpell.DEFAULT_TRAITS, BubbleSpell::new);
|
public static final SpellType<BubbleSpell> BUBBLE = register("bubble", builder(BubbleSpell::new).affinity(Affinity.NEUTRAL).color(0xF999FF).shape(GemstoneItem.Shape.DONUT).traits(BubbleSpell.DEFAULT_TRAITS));
|
||||||
public static final SpellType<DispellEvilSpell> DISPEL_EVIL = register("dispel_evil", Affinity.GOOD, 0x00FF00, true, GemstoneItem.Shape.CROSS, DispellEvilSpell.DEFAULT_TRAITS, DispellEvilSpell::new);
|
public static final SpellType<DispellEvilSpell> DISPEL_EVIL = register("dispel_evil", builder(DispellEvilSpell::new).color(0x00FF00).shape(GemstoneItem.Shape.CROSS).traits(DispellEvilSpell.DEFAULT_TRAITS));
|
||||||
|
|
||||||
public static void bootstrap() {}
|
public static void bootstrap() {}
|
||||||
|
|
||||||
|
@ -82,6 +82,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
private final Affinity affinity;
|
private final Affinity affinity;
|
||||||
private final int color;
|
private final int color;
|
||||||
private final boolean obtainable;
|
private final boolean obtainable;
|
||||||
|
private final boolean stackable;
|
||||||
private final GemstoneItem.Shape shape;
|
private final GemstoneItem.Shape shape;
|
||||||
|
|
||||||
private final Factory<T> factory;
|
private final Factory<T> factory;
|
||||||
|
@ -94,7 +95,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
|
|
||||||
private final ItemStack defaultStack;
|
private final ItemStack defaultStack;
|
||||||
|
|
||||||
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, GemstoneItem.Shape shape, SpellTraits traits, Factory<T> factory) {
|
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, boolean stackable, GemstoneItem.Shape shape, SpellTraits traits, Factory<T> factory) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.affinity = affinity;
|
this.affinity = affinity;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
@ -102,6 +103,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
this.shape = shape;
|
this.shape = shape;
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.traits = traits;
|
this.traits = traits;
|
||||||
|
this.stackable = stackable;
|
||||||
traited = new CustomisedSpellType<>(this, traits);
|
traited = new CustomisedSpellType<>(this, traits);
|
||||||
defaultStack = UItems.GEMSTONE.getDefaultStack(this);
|
defaultStack = UItems.GEMSTONE.getDefaultStack(this);
|
||||||
}
|
}
|
||||||
|
@ -110,6 +112,10 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
return obtainable;
|
return obtainable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isStackable() {
|
||||||
|
return stackable;
|
||||||
|
}
|
||||||
|
|
||||||
public Identifier getId() {
|
public Identifier getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +169,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean test(@Nullable Spell spell) {
|
public boolean test(@Nullable Spell spell) {
|
||||||
return spell != null && spell.getType() == this;
|
return spell != null && spell.getTypeAndTraits().type() == this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void toNbt(NbtCompound tag) {
|
public void toNbt(NbtCompound tag) {
|
||||||
|
@ -179,12 +185,12 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
return "SpellType[" + getTranslationKey() + "]";
|
return "SpellType[" + getTranslationKey() + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Spell> SpellType<T> register(String name, Affinity affinity, int color, boolean obtainable, GemstoneItem.Shape shape, SpellTraits traits, Factory<T> factory) {
|
public static <T extends Spell> SpellType<T> register(String name, Builder<T> builder) {
|
||||||
return register(Unicopia.id(name), affinity, color, obtainable, shape, traits, factory);
|
return register(Unicopia.id(name), builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends Spell> SpellType<T> register(Identifier id, Affinity affinity, int color, boolean obtainable, GemstoneItem.Shape shape, SpellTraits traits, Factory<T> factory) {
|
public static <T extends Spell> SpellType<T> register(Identifier id, Builder<T> builder) {
|
||||||
return Registry.register(REGISTRY, id, new SpellType<>(id, affinity, color, obtainable, shape, traits, factory));
|
return Registry.register(REGISTRY, id, builder.build(id));
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -209,4 +215,56 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
||||||
public interface Factory<T extends Spell> {
|
public interface Factory<T extends Spell> {
|
||||||
T create(CustomisedSpellType<T> type);
|
T create(CustomisedSpellType<T> type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T extends Spell> Builder<T> builder(Factory<T> factory) {
|
||||||
|
return new Builder<>(factory);
|
||||||
|
}
|
||||||
|
|
||||||
|
static class Builder<T extends Spell> {
|
||||||
|
private final Factory<T> factory;
|
||||||
|
private Affinity affinity = Affinity.GOOD;
|
||||||
|
private int color;
|
||||||
|
private boolean obtainable = true;
|
||||||
|
private boolean stackable = false;
|
||||||
|
private GemstoneItem.Shape shape = GemstoneItem.Shape.ROUND;
|
||||||
|
private SpellTraits traits = SpellTraits.EMPTY;
|
||||||
|
|
||||||
|
Builder(Factory<T> factory) {
|
||||||
|
this.factory = factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> affinity(Affinity affinity) {
|
||||||
|
this.affinity = affinity;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> color(int color) {
|
||||||
|
this.color = color;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> unobtainable() {
|
||||||
|
obtainable = false;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> stackable() {
|
||||||
|
stackable = true;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> shape(GemstoneItem.Shape shape) {
|
||||||
|
this.shape = shape;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder<T> traits(SpellTraits traits) {
|
||||||
|
this.traits = traits;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SpellType<T> build(Identifier id) {
|
||||||
|
return new SpellType<>(id, affinity, color, obtainable, stackable, shape, traits, factory);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -164,18 +164,19 @@ public class DismissSpellScreen extends GameGui {
|
||||||
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
|
public void render(DrawContext context, int mouseX, int mouseY, float tickDelta) {
|
||||||
MatrixStack matrices = context.getMatrices();
|
MatrixStack matrices = context.getMatrices();
|
||||||
|
|
||||||
var type = actualSpell.getType().withTraits(actualSpell.getTraits());
|
var type = actualSpell.getTypeAndTraits();
|
||||||
|
var affinity = actualSpell.getAffinity();
|
||||||
|
|
||||||
copy.set(mouseX - width * 0.5F - x * 0.5F, mouseY - height * 0.5F - y * 0.5F, 0, 0);
|
copy.set(mouseX - width * 0.5F - x * 0.5F, mouseY - height * 0.5F - y * 0.5F, 0, 0);
|
||||||
|
|
||||||
DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, actualSpell.getAffinity().getColor().getColorValue());
|
DrawableUtil.drawLine(matrices, 0, 0, (int)x, (int)y, affinity.getColor().getColorValue());
|
||||||
DrawableUtil.renderItemIcon(context, actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(),
|
DrawableUtil.renderItemIcon(context, actualSpell.isDead() ? UItems.BOTCHED_GEM.getDefaultStack() : type.getDefaultStack(),
|
||||||
x - 8 - copy.x * 0.2F,
|
x - 8 - copy.x * 0.2F,
|
||||||
y - 8 - copy.y * 0.2F,
|
y - 8 - copy.y * 0.2F,
|
||||||
1
|
1
|
||||||
);
|
);
|
||||||
|
|
||||||
int color = actualSpell.getType().getColor() << 2;
|
int color = type.type().getColor() << 2;
|
||||||
|
|
||||||
matrices.push();
|
matrices.push();
|
||||||
matrices.translate(x, y, 0);
|
matrices.translate(x, y, 0);
|
||||||
|
@ -187,15 +188,15 @@ public class DismissSpellScreen extends GameGui {
|
||||||
|
|
||||||
List<Text> tooltip = new ArrayList<>();
|
List<Text> tooltip = new ArrayList<>();
|
||||||
|
|
||||||
MutableText name = actualSpell.getType().getName().copy();
|
MutableText name = type.type().getName().copy();
|
||||||
color = actualSpell.getType().getColor();
|
color = type.type().getColor();
|
||||||
name.setStyle(name.getStyle().withColor(color == 0 ? 0xFFAAAAAA : color));
|
name.setStyle(name.getStyle().withColor(color == 0 ? 0xFFAAAAAA : color));
|
||||||
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.spell_type", name));
|
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.spell_type", name));
|
||||||
actualSpell.getType().getTraits().appendTooltip(tooltip);
|
type.traits().appendTooltip(tooltip);
|
||||||
tooltip.add(ScreenTexts.EMPTY);
|
tooltip.add(ScreenTexts.EMPTY);
|
||||||
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.affinity", actualSpell.getAffinity().name()).formatted(actualSpell.getAffinity().getColor()));
|
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.affinity", affinity.getDisplayName()).formatted(affinity.getColor()));
|
||||||
tooltip.add(ScreenTexts.EMPTY);
|
tooltip.add(ScreenTexts.EMPTY);
|
||||||
tooltip.addAll(TextHelper.wrap(Text.translatable(actualSpell.getType().getTranslationKey() + ".lore").formatted(actualSpell.getAffinity().getColor()), 180).toList());
|
tooltip.addAll(TextHelper.wrap(Text.translatable(type.type().getTranslationKey() + ".lore").formatted(affinity.getColor()), 180).toList());
|
||||||
if (spell instanceof TimedSpell timed) {
|
if (spell instanceof TimedSpell timed) {
|
||||||
tooltip.add(ScreenTexts.EMPTY);
|
tooltip.add(ScreenTexts.EMPTY);
|
||||||
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.time_left", StringHelper.formatTicks(timed.getTimer().getTicksRemaining())));
|
tooltip.add(Text.translatable("gui.unicopia.dispell_screen.time_left", StringHelper.formatTicks(timed.getTimer().getTicksRemaining())));
|
||||||
|
|
|
@ -55,7 +55,7 @@ public class HornFeatureRenderer<E extends LivingEntity> implements AccessoryFea
|
||||||
return pony.getAbilities().getActiveStat()
|
return pony.getAbilities().getActiveStat()
|
||||||
.flatMap(Stat::getActiveAbility)
|
.flatMap(Stat::getActiveAbility)
|
||||||
.map(ability -> ability.getColor(pony))
|
.map(ability -> ability.getColor(pony))
|
||||||
.filter(i -> i != -1).or(() -> pony.getSpellSlot().get(SpellPredicate.IS_NOT_PLACED, false).map(spell -> spell.getType().getColor()));
|
.filter(i -> i != -1).or(() -> pony.getSpellSlot().get(SpellPredicate.IS_NOT_PLACED, false).map(spell -> spell.getTypeAndTraits().type().getColor()));
|
||||||
}).ifPresent(color -> {
|
}).ifPresent(color -> {
|
||||||
model.setState(true);
|
model.setState(true);
|
||||||
model.render(stack, ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayers.getMagicColored((0x99 << 24) | color), false, false), lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
model.render(stack, ItemRenderer.getArmorGlintConsumer(renderContext, RenderLayers.getMagicColored((0x99 << 24) | color), false, false), lightUv, OverlayTexture.DEFAULT_UV, 1, 1, 1, 1);
|
||||||
|
|
|
@ -57,7 +57,7 @@ public class MagicBeamEntityRenderer extends EntityRenderer<MagicBeamEntity> {
|
||||||
);
|
);
|
||||||
|
|
||||||
RenderLayer layer = entity.getSpellSlot().get(true)
|
RenderLayer layer = entity.getSpellSlot().get(true)
|
||||||
.map(spell -> (0x99 << 24) | spell.getType().getColor())
|
.map(spell -> (0x99 << 24) | spell.getTypeAndTraits().type().getColor())
|
||||||
.map(RenderLayers::getMagicColored)
|
.map(RenderLayers::getMagicColored)
|
||||||
.orElseGet(RenderLayers::getMagicColored);
|
.orElseGet(RenderLayers::getMagicColored);
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class PlacedSpellRenderer extends SpellRenderer<PlaceableSpell> {
|
||||||
|
|
||||||
float angle = (animationProgress / 9F) % 360;
|
float angle = (animationProgress / 9F) % 360;
|
||||||
|
|
||||||
int color = delegate.getType().getColor();
|
int color = delegate.getTypeAndTraits().type().getColor();
|
||||||
|
|
||||||
float red = Color.r(color);
|
float red = Color.r(color);
|
||||||
float green = Color.g(color);
|
float green = Color.g(color);
|
||||||
|
|
|
@ -27,7 +27,7 @@ public class ShieldSpellRenderer extends SpellRenderer<ShieldSpell> {
|
||||||
double height = caster.asEntity().getEyeY() - caster.getOriginVector().y;
|
double height = caster.asEntity().getEyeY() - caster.getOriginVector().y;
|
||||||
matrices.translate(0, height, 0);
|
matrices.translate(0, height, 0);
|
||||||
|
|
||||||
int typeColor = spell.getType().getColor();
|
int typeColor = spell.getTypeAndTraits().type().getColor();
|
||||||
int ponyColor = MineLPDelegate.getInstance().getMagicColor(caster.getOriginatingCaster().asEntity());
|
int ponyColor = MineLPDelegate.getInstance().getMagicColor(caster.getOriginatingCaster().asEntity());
|
||||||
|
|
||||||
int color = ColorHelper.lerp(caster.getCorruption().getScaled(1) * (tickDelta / (1 + caster.asWorld().random.nextFloat())),
|
int color = ColorHelper.lerp(caster.getCorruption().getScaled(1) * (tickDelta / (1 + caster.asWorld().random.nextFloat())),
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <S extends Spell> SpellRenderer<S> getRenderer(S spell) {
|
public <S extends Spell> SpellRenderer<S> getRenderer(S spell) {
|
||||||
return (SpellRenderer<S>)renderers.getOrDefault(spell.getType(), SpellRenderer.DEFAULT);
|
return (SpellRenderer<S>)renderers.getOrDefault(spell.getTypeAndTraits().type(), SpellRenderer.DEFAULT);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void render(MatrixStack matrices, VertexConsumerProvider vertices, Spell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
public void render(MatrixStack matrices, VertexConsumerProvider vertices, Spell spell, Caster<?> caster, int light, float limbAngle, float limbDistance, float tickDelta, float animationProgress, float headYaw, float headPitch) {
|
||||||
|
@ -127,8 +127,8 @@ public class SpellEffectsRenderDispatcher implements SynchronousResourceReloader
|
||||||
caster.getSpellSlot().stream(AllSpells.INSTANCE, false).flatMap(spell ->
|
caster.getSpellSlot().stream(AllSpells.INSTANCE, false).flatMap(spell ->
|
||||||
Stream.of(
|
Stream.of(
|
||||||
Text.literal("UUID: " + spell.getUuid()),
|
Text.literal("UUID: " + spell.getUuid()),
|
||||||
Text.literal("|>Type: ").append(Text.literal(spell.getType().getId().toString()).styled(s -> s.withColor(spell.getType().getColor()))),
|
Text.literal("|>Type: ").append(Text.literal(spell.getTypeAndTraits().type().getId().toString()).styled(s -> s.withColor(spell.getTypeAndTraits().type().getColor()))),
|
||||||
Text.of("|>Traits: " + spell.getTraits()),
|
Text.of("|>Traits: " + spell.getTypeAndTraits().traits()),
|
||||||
Text.literal("|>HasRenderer: ").append(Text.literal((getRenderer(spell) != null) + "").formatted(getRenderer(spell) != null ? Formatting.GREEN : Formatting.RED))
|
Text.literal("|>HasRenderer: ").append(Text.literal((getRenderer(spell) != null) + "").formatted(getRenderer(spell) != null ? Formatting.GREEN : Formatting.RED))
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -42,7 +42,7 @@ public class SpellRenderer<T extends Spell> {
|
||||||
matrices.push();
|
matrices.push();
|
||||||
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(animationProgress));
|
matrices.multiply(RotationAxis.POSITIVE_Y.rotationDegrees(animationProgress));
|
||||||
|
|
||||||
client.getItemRenderer().renderItem(spell.getType().withTraits(spell.getTraits()).getDefaultStack(), ModelTransformationMode.FIXED, light, 0, matrices, vertices, caster.asWorld(), 0);
|
client.getItemRenderer().renderItem(spell.getTypeAndTraits().getDefaultStack(), ModelTransformationMode.FIXED, light, 0, matrices, vertices, caster.asWorld(), 0);
|
||||||
matrices.pop();
|
matrices.pop();
|
||||||
|
|
||||||
if (spell instanceof TimedSpell timed) {
|
if (spell instanceof TimedSpell timed) {
|
||||||
|
|
|
@ -66,7 +66,7 @@ public class PlayerCharmTracker implements NbtSerialisable {
|
||||||
public void toNBT(NbtCompound compound) {
|
public void toNBT(NbtCompound compound) {
|
||||||
NbtList equippedSpells = new NbtList();
|
NbtList equippedSpells = new NbtList();
|
||||||
for (CustomisedSpellType<?> spell : handSpells) {
|
for (CustomisedSpellType<?> spell : handSpells) {
|
||||||
equippedSpells.add(spell.toNBT());
|
equippedSpells.add(spell.toNbt(new NbtCompound()));
|
||||||
}
|
}
|
||||||
compound.put("handSpells", equippedSpells);
|
compound.put("handSpells", equippedSpells);
|
||||||
}
|
}
|
||||||
|
|
|
@ -955,7 +955,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
||||||
if (spell.getAffinity() == Affinity.BAD && entity.getWorld().random.nextInt(20) == 0) {
|
if (spell.getAffinity() == Affinity.BAD && entity.getWorld().random.nextInt(20) == 0) {
|
||||||
getCorruption().add(entity.getRandom().nextBetween(1, 10));
|
getCorruption().add(entity.getRandom().nextBetween(1, 10));
|
||||||
}
|
}
|
||||||
getCorruption().add((int)spell.getTraits().getCorruption() * 10);
|
getCorruption().add((int)spell.getTypeAndTraits().traits().getCorruption() * 10);
|
||||||
setDirty();
|
setDirty();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
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.effect.SpellType;
|
||||||
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
import com.minelittlepony.unicopia.client.render.PlayerPoser.Animation;
|
||||||
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
|
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
|
||||||
|
@ -46,7 +47,10 @@ public class EnchantedStaffItem extends StaffItem implements EnchantableItem, Ch
|
||||||
|
|
||||||
public static SpellType<?> getSpellType(Entity entity, boolean remove) {
|
public static SpellType<?> getSpellType(Entity entity, boolean remove) {
|
||||||
if (entity instanceof CastSpellEntity cast) {
|
if (entity instanceof CastSpellEntity cast) {
|
||||||
return cast.getSpellSlot().get(c -> !SpellPredicate.IS_PLACED.test(c), true).map(Spell::getType).orElse(SpellType.empty());
|
return cast.getSpellSlot().get(c -> !SpellPredicate.IS_PLACED.test(c), true)
|
||||||
|
.map(Spell::getTypeAndTraits)
|
||||||
|
.map(CustomisedSpellType::type)
|
||||||
|
.orElse(SpellType.empty());
|
||||||
}
|
}
|
||||||
if (entity instanceof PlayerEntity player) {
|
if (entity instanceof PlayerEntity player) {
|
||||||
if (remove) {
|
if (remove) {
|
||||||
|
|
|
@ -25,7 +25,7 @@ public class Ether extends PersistentState {
|
||||||
return WorldOverlay.getPersistableStorage(world, ID, Ether::new, Ether::new);
|
return WorldOverlay.getPersistableStorage(world, ID, Ether::new, Ether::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
private final Map<Identifier, Map<UUID, Map<UUID, Entry<?>>>> endpoints;
|
private final Map<SpellType<?>, Map<UUID, Map<UUID, Entry<?>>>> endpoints;
|
||||||
|
|
||||||
private final Object locker = new Object();
|
private final Object locker = new Object();
|
||||||
|
|
||||||
|
@ -33,7 +33,7 @@ public class Ether extends PersistentState {
|
||||||
|
|
||||||
Ether(World world, NbtCompound compound) {
|
Ether(World world, NbtCompound compound) {
|
||||||
this.world = world;
|
this.world = world;
|
||||||
this.endpoints = NbtSerialisable.readMap(compound.getCompound("endpoints"), Identifier::tryParse, typeNbt -> {
|
this.endpoints = NbtSerialisable.readMap(compound.getCompound("endpoints"), id -> SpellType.getKey(Identifier.tryParse(id)), typeNbt -> {
|
||||||
return NbtSerialisable.readMap((NbtCompound)typeNbt, UUID::fromString, entityNbt -> {
|
return NbtSerialisable.readMap((NbtCompound)typeNbt, UUID::fromString, entityNbt -> {
|
||||||
return NbtSerialisable.readMap((NbtCompound)entityNbt, UUID::fromString, Entry::new);
|
return NbtSerialisable.readMap((NbtCompound)entityNbt, UUID::fromString, Entry::new);
|
||||||
});
|
});
|
||||||
|
@ -49,7 +49,7 @@ public class Ether extends PersistentState {
|
||||||
public NbtCompound writeNbt(NbtCompound compound) {
|
public NbtCompound writeNbt(NbtCompound compound) {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
pruneNodes();
|
pruneNodes();
|
||||||
compound.put("endpoints", NbtSerialisable.writeMap(endpoints, Identifier::toString, entities -> {
|
compound.put("endpoints", NbtSerialisable.writeMap(endpoints, type -> type.getId().toString(), entities -> {
|
||||||
return NbtSerialisable.writeMap(entities, UUID::toString, spells -> {
|
return NbtSerialisable.writeMap(entities, UUID::toString, spells -> {
|
||||||
return NbtSerialisable.writeMap(spells, UUID::toString, Entry::toNBT);
|
return NbtSerialisable.writeMap(spells, UUID::toString, Entry::toNBT);
|
||||||
});
|
});
|
||||||
|
@ -62,7 +62,7 @@ public class Ether extends PersistentState {
|
||||||
public <T extends Spell> Entry<T> getOrCreate(T spell, Caster<?> caster) {
|
public <T extends Spell> Entry<T> getOrCreate(T spell, Caster<?> caster) {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
Entry<T> entry = (Entry<T>)endpoints
|
Entry<T> entry = (Entry<T>)endpoints
|
||||||
.computeIfAbsent(spell.getType().getId(), typeId -> new HashMap<>())
|
.computeIfAbsent(spell.getTypeAndTraits().type(), typeId -> new HashMap<>())
|
||||||
.computeIfAbsent(caster.asEntity().getUuid(), entityId -> new HashMap<>())
|
.computeIfAbsent(caster.asEntity().getUuid(), entityId -> new HashMap<>())
|
||||||
.computeIfAbsent(spell.getUuid(), spellid -> {
|
.computeIfAbsent(spell.getUuid(), spellid -> {
|
||||||
markDirty();
|
markDirty();
|
||||||
|
@ -82,7 +82,7 @@ public class Ether extends PersistentState {
|
||||||
|
|
||||||
public <T extends Spell> void remove(SpellType<T> spellType, UUID entityId) {
|
public <T extends Spell> void remove(SpellType<T> spellType, UUID entityId) {
|
||||||
synchronized (locker) {
|
synchronized (locker) {
|
||||||
endpoints.computeIfPresent(spellType.getId(), (typeId, entries) -> {
|
endpoints.computeIfPresent(spellType, (typeId, entries) -> {
|
||||||
if (entries.remove(entityId) != null) {
|
if (entries.remove(entityId) != null) {
|
||||||
markDirty();
|
markDirty();
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ public class Ether extends PersistentState {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <T extends Spell> Entry<T> get(T spell, Caster<?> caster) {
|
public <T extends Spell> Entry<T> get(T spell, Caster<?> caster) {
|
||||||
return get((SpellType<T>)spell.getType(), caster.asEntity().getUuid(), spell.getUuid());
|
return get((SpellType<T>)spell.getTypeAndTraits().type(), caster.asEntity().getUuid(), spell.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Spell> Entry<T> get(SpellType<T> spell, EntityReference.EntityValues<?> entityId, @Nullable UUID spellId) {
|
public <T extends Spell> Entry<T> get(SpellType<T> spell, EntityReference.EntityValues<?> entityId, @Nullable UUID spellId) {
|
||||||
|
|
|
@ -726,6 +726,10 @@
|
||||||
"ability.unicopia.change_form": "Change Form",
|
"ability.unicopia.change_form": "Change Form",
|
||||||
"ability.unicopia.sonar_pulse": "Sonar Pulse",
|
"ability.unicopia.sonar_pulse": "Sonar Pulse",
|
||||||
|
|
||||||
|
"affinity.unicopia.good": "Good",
|
||||||
|
"affinity.unicopia.bad": "Bad",
|
||||||
|
"affinity.unicopia.neutral": "Neutral",
|
||||||
|
|
||||||
"gui.unicopia.trait.label": "Element of %s",
|
"gui.unicopia.trait.label": "Element of %s",
|
||||||
"gui.unicopia.trait.group": "\n %s",
|
"gui.unicopia.trait.group": "\n %s",
|
||||||
"gui.unicopia.trait.corruption": "\n %s corruption",
|
"gui.unicopia.trait.corruption": "\n %s corruption",
|
||||||
|
|
Loading…
Reference in a new issue