mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
Finish porting spell attributes to the new system
This commit is contained in:
parent
b30e9c5f1f
commit
9ee81c961c
23 changed files with 172 additions and 198 deletions
|
@ -3,12 +3,13 @@ package com.minelittlepony.unicopia.ability.magic.spell;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
||||
public abstract class AbstractAreaEffectSpell extends AbstractSpell {
|
||||
protected static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributes.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 4 + power));
|
||||
protected static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributeType.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 4 + power));
|
||||
public static final TooltipFactory TOOLTIP = RANGE;
|
||||
|
||||
protected AbstractAreaEffectSpell(CustomisedSpellType<?> type) {
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import com.minelittlepony.unicopia.entity.effect.EffectUtils;
|
||||
|
||||
import net.minecraft.item.ItemStack;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.StringHelper;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public interface SpellAttributes {
|
||||
Text CAST_ON_LOCATION = of(Unicopia.id("cast_on_location"));
|
||||
Text CAST_ON_PERSON = of(Unicopia.id("cast_on_person"));
|
||||
Identifier FOLLOWS_TARGET = Unicopia.id("follows_target");
|
||||
|
||||
Identifier PERMIT_ITEMS = Unicopia.id("permit_items");
|
||||
Identifier PERMIT_PASSIVE = Unicopia.id("permit_passive");
|
||||
Identifier PERMIT_HOSTILE = Unicopia.id("permit_hostile");
|
||||
Identifier PERMIT_PLAYER = Unicopia.id("permit_player");
|
||||
|
||||
Identifier FOCUSED_ENTITY = Unicopia.id("focused_entity");
|
||||
Identifier RANGE = Unicopia.id("range");
|
||||
Identifier DURATION = Unicopia.id("duration");
|
||||
Identifier STRENGTH = Unicopia.id("strength");
|
||||
Identifier VELOCITY = Unicopia.id("velocity");
|
||||
Identifier VERTICAL_VELOCITY = Unicopia.id("vertical_velocity");
|
||||
Identifier HANG_TIME = Unicopia.id("hang_time");
|
||||
Identifier PUSHING_POWER = Unicopia.id("pushing_power");
|
||||
Identifier CAUSES_LEVITATION = Unicopia.id("causes_levitation");
|
||||
Identifier AFFECTS = Unicopia.id("affects");
|
||||
Identifier DAMAGE_TO_TARGET = Unicopia.id("damage_to_target");
|
||||
Identifier SIMULTANIOUS_TARGETS = Unicopia.id("simultanious_targets");
|
||||
Identifier COST_PER_INDIVIDUAL = Unicopia.id("cost_per_individual");
|
||||
Identifier EXPLOSION_STRENGTH = Unicopia.id("explosion_strength");
|
||||
Identifier PROJECTILE_COUNT = Unicopia.id("projectile_count");
|
||||
Identifier ORB_COUNT = Unicopia.id("orb_count");
|
||||
Identifier WAVE_SIZE = Unicopia.id("wave_size");
|
||||
Identifier FOLLOW_RANGE = Unicopia.id("follow_range");
|
||||
Identifier LIGHT_TARGET = Unicopia.id("light_target");
|
||||
Identifier STICK_TO_TARGET = Unicopia.id("stick_to_target");
|
||||
Identifier SOAPINESS = Unicopia.id("soapiness");
|
||||
Identifier CAST_ON = Unicopia.id("cast_on");
|
||||
|
||||
Identifier TARGET_PREFERENCE = Unicopia.id("target_preference");
|
||||
Identifier CASTER_PREFERENCE = Unicopia.id("caster_preference");
|
||||
|
||||
@Deprecated
|
||||
static Text of(Identifier id) {
|
||||
return Text.literal(" ").append(Text.translatable(Util.createTranslationKey("spell_attribute", id))).formatted(Formatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
static Text of(Identifier id, float value) {
|
||||
return Text.literal(" ").append(
|
||||
Text.translatable("attribute.modifier.equals.0",
|
||||
ItemStack.MODIFIER_FORMAT.format(value),
|
||||
Text.translatable(Util.createTranslationKey("spell_attribute", id)))
|
||||
).formatted(Formatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
static Text ofRelative(Identifier id, float value) {
|
||||
return EffectUtils.formatModifierChange(Util.createTranslationKey("spell_attribute", id), value, false);
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
static Text ofTime(Identifier id, long time) {
|
||||
return Text.literal(" ").append(Text.translatable("attribute.modifier.equals.0",
|
||||
StringHelper.formatTicks((int)Math.abs(time)),
|
||||
Text.translatable(Util.createTranslationKey("spell_attribute", id))
|
||||
).formatted(Formatting.LIGHT_PURPLE));
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public enum ValueType {
|
||||
REGULAR,
|
||||
TIME,
|
||||
PERCENTAGE,
|
||||
CONDITIONAL
|
||||
}
|
||||
}
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.ability.magic.spell;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
import com.minelittlepony.unicopia.util.Tickable;
|
||||
|
@ -14,7 +15,7 @@ import net.minecraft.util.math.MathHelper;
|
|||
*/
|
||||
public interface TimedSpell extends Spell {
|
||||
int BASE_DURATION = 120 * 20;
|
||||
SpellAttribute<Integer> TIME = SpellAttribute.create(SpellAttributes.SOAPINESS, AttributeFormat.TIME, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> BASE_DURATION + (int)(MathHelper.clamp(focus, 0, 160) * 19) * 20);
|
||||
SpellAttribute<Integer> TIME = SpellAttribute.create(SpellAttributeType.SOAPINESS, AttributeFormat.TIME, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> BASE_DURATION + (int)(MathHelper.clamp(focus, 0, 160) * 19) * 20);
|
||||
|
||||
Timer getTimer();
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ public enum AttributeFormat {
|
|||
return Text.translatable("spell_attribute.unicopia.added_trait." + ((value > 0) ? "plus" : "take"), name, count).formatted(Formatting.DARK_AQUA);
|
||||
}
|
||||
|
||||
static MutableText formatAttributeLine(Text attributeName) {
|
||||
public static MutableText formatAttributeLine(Text attributeName) {
|
||||
return Text.literal(" ").append(attributeName).formatted(Formatting.LIGHT_PURPLE);
|
||||
}
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
|||
import it.unimi.dsi.fastutil.floats.Float2ObjectFunction;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Formatting;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public record SpellAttribute<T> (
|
||||
|
@ -31,34 +30,33 @@ public record SpellAttribute<T> (
|
|||
return valueGetter.apply(traits, traits.get(trait));
|
||||
}
|
||||
|
||||
public static <T extends Number> SpellAttribute<T> create(Identifier id, AttributeFormat format, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter) {
|
||||
public static <T extends Number> SpellAttribute<T> create(SpellAttributeType id, AttributeFormat format, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter) {
|
||||
return create(id, format, format, trait, valueGetter, false);
|
||||
}
|
||||
|
||||
public static <T extends Number> SpellAttribute<T> create(Identifier id, AttributeFormat format, Trait trait, Float2ObjectFunction<@NotNull T> valueGetter) {
|
||||
public static <T extends Number> SpellAttribute<T> create(SpellAttributeType id, AttributeFormat format, Trait trait, Float2ObjectFunction<@NotNull T> valueGetter) {
|
||||
return create(id, format, format, trait, valueGetter, false);
|
||||
}
|
||||
|
||||
public static <T extends Number> SpellAttribute<T> create(Identifier id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, Float2ObjectFunction<@NotNull T> valueGetter) {
|
||||
public static <T extends Number> SpellAttribute<T> create(SpellAttributeType id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, Float2ObjectFunction<@NotNull T> valueGetter) {
|
||||
return create(id, baseFormat, relativeFormat, trait, valueGetter, false);
|
||||
}
|
||||
|
||||
public static <T extends Number> SpellAttribute<T> create(Identifier id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter) {
|
||||
public static <T extends Number> SpellAttribute<T> create(SpellAttributeType id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter) {
|
||||
return create(id, baseFormat, relativeFormat, trait, valueGetter, false);
|
||||
}
|
||||
|
||||
public static <T extends @NotNull Number> SpellAttribute<T> create(Identifier id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, Float2ObjectFunction<@NotNull T> valueGetter, boolean detrimental) {
|
||||
public static <T extends @NotNull Number> SpellAttribute<T> create(SpellAttributeType id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, Float2ObjectFunction<@NotNull T> valueGetter, boolean detrimental) {
|
||||
return create(id, baseFormat, relativeFormat, trait, (traits, value) -> valueGetter.get(value.floatValue()), detrimental);
|
||||
}
|
||||
|
||||
public static <T extends @NotNull Number> SpellAttribute<T> create(Identifier id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter, boolean detrimental) {
|
||||
Text name = Text.translatable(Util.createTranslationKey("spell_attribute", id));
|
||||
public static <T extends @NotNull Number> SpellAttribute<T> create(SpellAttributeType id, AttributeFormat baseFormat, AttributeFormat relativeFormat, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter, boolean detrimental) {
|
||||
return new SpellAttribute<>(trait, valueGetter, (CustomisedSpellType<?> type, List<Text> tooltip) -> {
|
||||
float traitAmount = type.traits().get(trait);
|
||||
float traitDifference = type.relativeTraits().get(trait);
|
||||
float value = valueGetter.apply(type.traits(), traitAmount).floatValue();
|
||||
|
||||
var b = baseFormat.getBase(name, value, "equals", Formatting.LIGHT_PURPLE);
|
||||
var b = baseFormat.getBase(id.name(), value, "equals", Formatting.LIGHT_PURPLE);
|
||||
if (traitDifference != 0) {
|
||||
tooltip.add(b.append(relativeFormat.getRelative(Text.empty(), valueGetter.apply(type.traits(), traitAmount - traitDifference).floatValue(), value, detrimental)));
|
||||
tooltip.add(AttributeFormat.formatTraitDifference(trait, traitDifference));
|
||||
|
@ -68,15 +66,14 @@ public record SpellAttribute<T> (
|
|||
});
|
||||
}
|
||||
|
||||
public static SpellAttribute<Boolean> createConditional(Identifier id, Trait trait, Float2ObjectFunction<Boolean> valueGetter) {
|
||||
public static SpellAttribute<Boolean> createConditional(SpellAttributeType id, Trait trait, Float2ObjectFunction<Boolean> valueGetter) {
|
||||
return createConditional(id, trait, (traits, value) -> valueGetter.get(value.floatValue()));
|
||||
}
|
||||
|
||||
public static SpellAttribute<Boolean> createConditional(Identifier id, Trait trait, BiFunction<SpellTraits, Float, @NotNull Boolean> valueGetter) {
|
||||
public static SpellAttribute<Boolean> createConditional(SpellAttributeType id, Trait trait, BiFunction<SpellTraits, Float, @NotNull Boolean> valueGetter) {
|
||||
return new SpellAttribute<>(trait, valueGetter, (CustomisedSpellType<?> type, List<Text> tooltip) -> {
|
||||
Text name = Text.translatable(Util.createTranslationKey("spell_attribute", id));
|
||||
float difference = type.relativeTraits().get(trait);
|
||||
Text value = AttributeFormat.formatAttributeLine(name);
|
||||
Text value = AttributeFormat.formatAttributeLine(id.name());
|
||||
if (!valueGetter.apply(type.traits(), type.traits().get(trait))) {
|
||||
value = value.copy().formatted(Formatting.STRIKETHROUGH, Formatting.DARK_GRAY);
|
||||
}
|
||||
|
@ -87,12 +84,12 @@ public record SpellAttribute<T> (
|
|||
});
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> SpellAttribute<T> createEnumerated(Identifier id, Trait trait, Float2ObjectFunction<T> valueGetter) {
|
||||
public static <T extends Enum<T>> SpellAttribute<T> createEnumerated(SpellAttributeType id, Trait trait, Float2ObjectFunction<T> valueGetter) {
|
||||
return createEnumerated(id, trait, (traits, value) -> valueGetter.get(value.floatValue()));
|
||||
}
|
||||
|
||||
public static <T extends Enum<T>> SpellAttribute<T> createEnumerated(Identifier id, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter) {
|
||||
Function<T, Text> cache = Util.memoize(t -> Text.translatable(Util.createTranslationKey("spell_attribute", id.withPath(id.getPath() + "." + t.name().toLowerCase(Locale.ROOT)))));
|
||||
public static <T extends Enum<T>> SpellAttribute<T> createEnumerated(SpellAttributeType id, Trait trait, BiFunction<SpellTraits, Float, @NotNull T> valueGetter) {
|
||||
Function<T, Text> cache = Util.memoize(t -> Text.translatable(Util.createTranslationKey("spell_attribute", id.id().withPath(p -> p + "." + t.name().toLowerCase(Locale.ROOT)))));
|
||||
return new SpellAttribute<>(trait, valueGetter, (CustomisedSpellType<?> type, List<Text> tooltip) -> {
|
||||
T t = valueGetter.apply(type.traits(), type.traits().get(trait));
|
||||
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.attribute;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.minelittlepony.unicopia.Unicopia;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.Identifier;
|
||||
import net.minecraft.util.Util;
|
||||
|
||||
public record SpellAttributeType(Identifier id, Text name) {
|
||||
public static final List<SpellAttributeType> REGISTRY = new ArrayList<>();
|
||||
|
||||
@Deprecated
|
||||
public static final SpellAttributeType CAST_ON_LOCATION = register("cast_on.location");
|
||||
public static final SpellAttributeType FOLLOWS_TARGET = register("follows_target");
|
||||
|
||||
public static final SpellAttributeType PERMIT_ITEMS = register("permit_items");
|
||||
public static final SpellAttributeType PERMIT_PASSIVE = register("permit_passive");
|
||||
public static final SpellAttributeType PERMIT_HOSTILE = register("permit_hostile");
|
||||
public static final SpellAttributeType PERMIT_PLAYER = register("permit_player");
|
||||
|
||||
public static final SpellAttributeType FOCUSED_ENTITY = register("focused_entity");
|
||||
public static final SpellAttributeType RANGE = register("range");
|
||||
public static final SpellAttributeType DURATION = register("duration");
|
||||
public static final SpellAttributeType STRENGTH = register("strength");
|
||||
public static final SpellAttributeType VELOCITY = register("velocity");
|
||||
public static final SpellAttributeType VERTICAL_VELOCITY = register("vertical_velocity");
|
||||
public static final SpellAttributeType HANG_TIME = register("hang_time");
|
||||
public static final SpellAttributeType PUSHING_POWER = register("pushing_power");
|
||||
public static final SpellAttributeType CAUSES_LEVITATION = register("causes_levitation");
|
||||
public static final SpellAttributeType AFFECTS = register("affects");
|
||||
public static final SpellAttributeType DAMAGE_TO_TARGET = register("damage_to_target");
|
||||
public static final SpellAttributeType SIMULTANIOUS_TARGETS = register("simultanious_targets");
|
||||
public static final SpellAttributeType COST_PER_INDIVIDUAL = register("cost_per_individual");
|
||||
public static final SpellAttributeType EXPLOSION_STRENGTH = register("explosion_strength");
|
||||
public static final SpellAttributeType PROJECTILE_COUNT = register("projectile_count");
|
||||
public static final SpellAttributeType ORB_COUNT = register("orb_count");
|
||||
public static final SpellAttributeType WAVE_SIZE = register("wave_size");
|
||||
public static final SpellAttributeType FOLLOW_RANGE = register("follow_range");
|
||||
public static final SpellAttributeType LIGHT_TARGET = register("light_target");
|
||||
public static final SpellAttributeType STICK_TO_TARGET = register("stick_to_target");
|
||||
public static final SpellAttributeType SOAPINESS = register("soapiness");
|
||||
public static final SpellAttributeType CAST_ON = register("cast_on");
|
||||
|
||||
public static final SpellAttributeType TARGET_PREFERENCE = register("target_preference");
|
||||
public static final SpellAttributeType CASTER_PREFERENCE = register("caster_preference");
|
||||
public static final SpellAttributeType NEGATES_FALL_DAMAGE = register("negates_fall_damage");
|
||||
|
||||
public SpellAttributeType(Identifier id) {
|
||||
this(id, Text.translatable(Util.createTranslationKey("spell_attribute", id)));
|
||||
}
|
||||
|
||||
public static SpellAttributeType register(String name) {
|
||||
SpellAttributeType type = new SpellAttributeType(Unicopia.id(name));
|
||||
REGISTRY.add(type);
|
||||
return type;
|
||||
}
|
||||
}
|
|
@ -9,6 +9,8 @@ import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
|||
import net.minecraft.text.Text;
|
||||
|
||||
public interface TooltipFactory {
|
||||
TooltipFactory EMPTY = (type, tooltip) -> {};
|
||||
|
||||
void appendTooltip(CustomisedSpellType<?> type, List<Text> tooltip);
|
||||
|
||||
static TooltipFactory of(TooltipFactory...lines) {
|
||||
|
|
|
@ -2,8 +2,12 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.CastOn;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -24,16 +28,18 @@ public class AreaProtectionSpell extends AbstractAreaEffectSpell {
|
|||
.with(Trait.STRENGTH, 30)
|
||||
.build();
|
||||
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(TooltipFactory.of(SpellAttributes.CAST_ON_LOCATION), RANGE);
|
||||
private static final SpellAttribute<CastOn> CAST_ON = SpellAttribute.createEnumerated(SpellAttributeType.CAST_ON, Trait.FOCUS, focus -> focus > 0 ? CastOn.SELF : CastOn.LOCATION);
|
||||
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(CAST_ON, RANGE);
|
||||
|
||||
protected AreaProtectionSpell(CustomisedSpellType<?> type) {
|
||||
super(type);
|
||||
}
|
||||
|
||||
/*@Override
|
||||
@Override
|
||||
public Spell prepareForCast(Caster<?> caster, CastingMethod method) {
|
||||
return method == CastingMethod.STAFF || getTraits().get(Trait.GENEROSITY) > 0 ? toPlaceable() : this;
|
||||
}*/
|
||||
return method == CastingMethod.STAFF || CAST_ON.get(getTraits()) == CastOn.LOCATION ? toPlaceable() : this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean tick(Caster<?> source, Situation situation) {
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
|
@ -22,8 +23,8 @@ import net.minecraft.util.math.MathHelper;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
public class AttractiveSpell extends ShieldSpell implements HomingSpell, TimedSpell, ProjectileDelegate.EntityHitListener {
|
||||
static final SpellAttribute<Boolean> TARGET_FOCUSED_ENTITY = SpellAttribute.createConditional(SpellAttributes.FOCUSED_ENTITY, Trait.ORDER, order -> order >= 20);
|
||||
static final SpellAttribute<Boolean> STICK_TO_TARGET = SpellAttribute.createConditional(SpellAttributes.STICK_TO_TARGET, Trait.CHAOS, chaos -> chaos > 0);
|
||||
static final SpellAttribute<Boolean> TARGET_FOCUSED_ENTITY = SpellAttribute.createConditional(SpellAttributeType.FOCUSED_ENTITY, Trait.ORDER, order -> order >= 20);
|
||||
static final SpellAttribute<Boolean> STICK_TO_TARGET = SpellAttribute.createConditional(SpellAttributeType.STICK_TO_TARGET, Trait.CHAOS, chaos -> chaos > 0);
|
||||
static final TooltipFactory TARGET = (type, tooltip) -> (TARGET_FOCUSED_ENTITY.get(type.traits()) ? TARGET_FOCUSED_ENTITY : ShieldSpell.TARGET).appendTooltip(type, tooltip);
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(TIME, RANGE, TARGET, STICK_TO_TARGET, CAST_ON);
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -51,7 +52,7 @@ public class BubbleSpell extends AbstractSpell implements TimedSpell,
|
|||
.with(Trait.POWER, 1)
|
||||
.build();
|
||||
|
||||
private static final SpellAttribute<Integer> SOAPINESS = SpellAttribute.create(SpellAttributes.SOAPINESS, AttributeFormat.REGULAR, Trait.POWER, power -> (int)(power * 2));
|
||||
private static final SpellAttribute<Integer> SOAPINESS = SpellAttribute.create(SpellAttributeType.SOAPINESS, AttributeFormat.REGULAR, Trait.POWER, power -> (int)(power * 2));
|
||||
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(TimedSpell.TIME, SOAPINESS);
|
||||
|
||||
|
|
|
@ -8,10 +8,10 @@ import org.jetbrains.annotations.Nullable;
|
|||
import com.minelittlepony.unicopia.UTags;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.Affects;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -49,11 +49,11 @@ public class CatapultSpell extends AbstractSpell implements ProjectileDelegate.B
|
|||
private static final float HORIZONTAL_VARIANCE = 0.25F;
|
||||
private static final float MAX_STRENGTH = 120;
|
||||
|
||||
private static final SpellAttribute<Float> LAUNCH_SPEED = SpellAttribute.create(SpellAttributes.VERTICAL_VELOCITY, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> 0.1F + (MathHelper.clamp(strength, -MAX_STRENGTH, MAX_STRENGTH) - 40) / 16F);
|
||||
private static final SpellAttribute<Float> HANG_TIME = SpellAttribute.create(SpellAttributes.HANG_TIME, AttributeFormat.TIME, AttributeFormat.PERCENTAGE, Trait.AIR, air -> 50 + (int)MathHelper.clamp(air, 0, 10) * 20F);
|
||||
private static final SpellAttribute<Float> PUSHING_POWER = SpellAttribute.create(SpellAttributes.PUSHING_POWER, AttributeFormat.REGULAR, Trait.POWER, power -> 1 + MathHelper.clamp(power, 0, 10) / 10F);
|
||||
private static final SpellAttribute<Boolean> CAUSES_LEVITATION = SpellAttribute.createConditional(SpellAttributes.CAUSES_LEVITATION, Trait.FOCUS, focus -> focus > 50);
|
||||
private static final SpellAttribute<Affects> AFFECTS = SpellAttribute.createEnumerated(SpellAttributes.AFFECTS, Trait.ORDER, order -> {
|
||||
private static final SpellAttribute<Float> LAUNCH_SPEED = SpellAttribute.create(SpellAttributeType.VERTICAL_VELOCITY, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> 0.1F + (MathHelper.clamp(strength, -MAX_STRENGTH, MAX_STRENGTH) - 40) / 16F);
|
||||
private static final SpellAttribute<Float> HANG_TIME = SpellAttribute.create(SpellAttributeType.HANG_TIME, AttributeFormat.TIME, AttributeFormat.PERCENTAGE, Trait.AIR, air -> 50 + (int)MathHelper.clamp(air, 0, 10) * 20F);
|
||||
private static final SpellAttribute<Float> PUSHING_POWER = SpellAttribute.create(SpellAttributeType.PUSHING_POWER, AttributeFormat.REGULAR, Trait.POWER, power -> 1 + MathHelper.clamp(power, 0, 10) / 10F);
|
||||
private static final SpellAttribute<Boolean> CAUSES_LEVITATION = SpellAttribute.createConditional(SpellAttributeType.CAUSES_LEVITATION, Trait.FOCUS, focus -> focus > 50);
|
||||
private static final SpellAttribute<Affects> AFFECTS = SpellAttribute.createEnumerated(SpellAttributeType.AFFECTS, Trait.ORDER, order -> {
|
||||
if (order <= 0) {
|
||||
return Affects.BOTH;
|
||||
} else if (order <= 10) {
|
||||
|
|
|
@ -94,7 +94,7 @@ public record CustomisedSpellType<T extends Spell> (
|
|||
lines.addAll(TextHelper.wrap(lore, 180).toList());
|
||||
float corruption = ((int)traits().getCorruption() * 10) + type().getAffinity().getCorruption();
|
||||
List<Text> modifiers = new ArrayList<>();
|
||||
type.getTooltip().accept(this, modifiers);
|
||||
type.getTooltip().appendTooltip(this, modifiers);
|
||||
if (corruption != 0) {
|
||||
modifiers.add(EffectUtils.formatModifierChange("affinity.unicopia.corruption", corruption, true));
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -21,7 +22,7 @@ public class DispellEvilSpell extends AbstractSpell implements ProjectileDelegat
|
|||
.with(Trait.POWER, 1)
|
||||
.build();
|
||||
|
||||
private static final SpellAttribute<Double> RANGE = SpellAttribute.create(SpellAttributes.RANGE, AttributeFormat.TIME, AttributeFormat.PERCENTAGE, Trait.POWER, power -> (1 + power) * 10D);
|
||||
private static final SpellAttribute<Double> RANGE = SpellAttribute.create(SpellAttributeType.RANGE, AttributeFormat.TIME, AttributeFormat.PERCENTAGE, Trait.POWER, power -> (1 + power) * 10D);
|
||||
|
||||
static final TooltipFactory TOOLTIP = RANGE;
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
|
@ -19,8 +19,8 @@ import net.minecraft.util.math.Vec3d;
|
|||
* An area-effect spell that disperses illusions.
|
||||
*/
|
||||
public class DisperseIllusionSpell extends AbstractAreaEffectSpell {
|
||||
private static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributes.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 15 + power));
|
||||
private static final SpellAttribute<Long> DURATION = SpellAttribute.create(SpellAttributes.DURATION, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> (1 + (long)strength) * 100);
|
||||
private static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributeType.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 15 + power));
|
||||
private static final SpellAttribute<Long> DURATION = SpellAttribute.create(SpellAttributeType.DURATION, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> (1 + (long)strength) * 100);
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(RANGE, DURATION);
|
||||
|
||||
protected DisperseIllusionSpell(CustomisedSpellType<?> type) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.entity.EntityReference;
|
||||
|
@ -19,7 +20,7 @@ import net.minecraft.util.math.Vec3d;
|
|||
|
||||
public class DisplacementSpell extends AbstractSpell implements HomingSpell, ProjectileDelegate.EntityHitListener {
|
||||
|
||||
private static final SpellAttribute<Float> DAMAGE_TO_TARGET = SpellAttribute.create(SpellAttributes.DAMAGE_TO_TARGET, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.BLOOD, blood -> blood);
|
||||
private static final SpellAttribute<Float> DAMAGE_TO_TARGET = SpellAttribute.create(SpellAttributeType.DAMAGE_TO_TARGET, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.BLOOD, blood -> blood);
|
||||
|
||||
static final TooltipFactory TOOLTIP = DAMAGE_TO_TARGET;
|
||||
|
||||
|
|
|
@ -5,8 +5,11 @@ import java.util.stream.Stream;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.item.FriendshipBraceletItem;
|
||||
|
@ -16,7 +19,6 @@ import com.minelittlepony.unicopia.particle.ParticleUtils;
|
|||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.math.MathHelper;
|
||||
import net.minecraft.util.math.Vec3d;
|
||||
|
||||
|
@ -30,6 +32,25 @@ public class FeatherFallSpell extends AbstractSpell implements TimedSpell {
|
|||
private static final float POWERS_RANGE_WEIGHT = 0.3F;
|
||||
private static final float MAX_GENEROSITY_FACTOR = 19F;
|
||||
|
||||
private static final SpellAttribute<Integer> DURATION = SpellAttribute.create(SpellAttributeType.DURATION, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> 10 + (int)(MathHelper.clamp(focus, 0, 160)));
|
||||
private static final SpellAttribute<Float> STRENGTH = SpellAttribute.create(SpellAttributeType.STRENGTH, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> MathHelper.clamp(strength, 2, 9));
|
||||
private static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributeType.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> MathHelper.clamp((power - 10) * POWERS_RANGE_WEIGHT, MIN_RANGE, MAX_RANGE));
|
||||
private static final SpellAttribute<Long> SIMULTANIOUS_TARGETS = SpellAttribute.create(SpellAttributeType.SIMULTANIOUS_TARGETS, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.GENEROSITY, (traits, generosity) -> {
|
||||
return (long)(generosity + traits.get(Trait.FOCUS, MIN_TARGETS, MAX_TARGETS) * 2);
|
||||
});
|
||||
private static final SpellAttribute<Float> COST_PER_INDIVIDUAL = SpellAttribute.create(SpellAttributeType.COST_PER_INDIVIDUAL, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, (traits, power) -> {
|
||||
return MathHelper.clamp(((Math.max(power, 10) - 10) * POWERS_RANGE_WEIGHT) - ((Math.max(traits.get(Trait.FOCUS), 80) - 80) * FOCUS_RANGE_WEIGHT), 1, 7);
|
||||
});
|
||||
private static final SpellAttribute<Float> TARGET_PREFERENCE = SpellAttribute.create(SpellAttributeType.TARGET_PREFERENCE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.GENEROSITY, generosity -> {
|
||||
return MathHelper.clamp(generosity, 1, MAX_GENEROSITY_FACTOR) / MAX_GENEROSITY_FACTOR;
|
||||
});
|
||||
private static final SpellAttribute<Float> CASTER_PREFERENCE = SpellAttribute.create(SpellAttributeType.CASTER_PREFERENCE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.GENEROSITY, (traits, generosity) -> {
|
||||
return 1 - TARGET_PREFERENCE.get(traits);
|
||||
});
|
||||
private static final SpellAttribute<Boolean> NEGATES_FALL_DAMAGE = SpellAttribute.createConditional(SpellAttributeType.NEGATES_FALL_DAMAGE, Trait.GENEROSITY, (generosity) -> generosity > 0.5F);
|
||||
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(DURATION, STRENGTH, RANGE, SIMULTANIOUS_TARGETS, COST_PER_INDIVIDUAL, TARGET_PREFERENCE, CASTER_PREFERENCE, NEGATES_FALL_DAMAGE);
|
||||
|
||||
public static final SpellTraits DEFAULT_TRAITS = new SpellTraits.Builder()
|
||||
.with(Trait.FOCUS, 80)
|
||||
.with(Trait.POWER, 10)
|
||||
|
@ -38,22 +59,11 @@ public class FeatherFallSpell extends AbstractSpell implements TimedSpell {
|
|||
.with(Trait.ORDER, 15)
|
||||
.build();
|
||||
|
||||
public static void appendTooltip(CustomisedSpellType<FeatherFallSpell> type, List<Text> tooltip) {
|
||||
tooltip.add(SpellAttributes.ofTime(SpellAttributes.DURATION, 10 + (int)(type.traits().get(Trait.FOCUS, 0, 160))));
|
||||
tooltip.add(SpellAttributes.of(SpellAttributes.STRENGTH, type.traits().get(Trait.STRENGTH, 2, 9)));
|
||||
tooltip.add(SpellAttributes.of(SpellAttributes.RANGE, (float)getEffectRange(type.traits())));
|
||||
tooltip.add(SpellAttributes.of(SpellAttributes.SIMULTANIOUS_TARGETS, getMaxTargets(type.traits())));
|
||||
tooltip.add(SpellAttributes.of(SpellAttributes.COST_PER_INDIVIDUAL, (float)getCostPerEntity(type.traits())));
|
||||
float generosity = type.traits().get(Trait.GENEROSITY, 1, MAX_GENEROSITY_FACTOR) / MAX_GENEROSITY_FACTOR;
|
||||
tooltip.add(SpellAttributes.of(SpellAttributes.TARGET_PREFERENCE, (int)(generosity * 100)));
|
||||
tooltip.add(SpellAttributes.of(SpellAttributes.CASTER_PREFERENCE, (int)((1 - generosity) * 100)));
|
||||
}
|
||||
|
||||
private final Timer timer;
|
||||
|
||||
protected FeatherFallSpell(CustomisedSpellType<?> type) {
|
||||
super(type);
|
||||
timer = new Timer(10 + (int)(getTraits().get(Trait.FOCUS, 0, 160)));
|
||||
timer = new Timer(DURATION.get(getTraits()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -75,18 +85,16 @@ public class FeatherFallSpell extends AbstractSpell implements TimedSpell {
|
|||
return true;
|
||||
}
|
||||
|
||||
final float strength = 1F / (getTraits().get(Trait.STRENGTH, 2, 9) / targets.size());
|
||||
final float generosity = getTraits().get(Trait.GENEROSITY, 1, MAX_GENEROSITY_FACTOR) / MAX_GENEROSITY_FACTOR;
|
||||
final float strength = 1F / (STRENGTH.get(getTraits()) / targets.size());
|
||||
final float targetPreference = TARGET_PREFERENCE.get(getTraits());
|
||||
final float casterPreference = 1 - targetPreference;
|
||||
final boolean negateFallDamage = NEGATES_FALL_DAMAGE.get(getTraits());
|
||||
|
||||
Entity entity = caster.asEntity();
|
||||
Vec3d masterVelocity = entity.getVelocity().multiply(0.1);
|
||||
targets.forEach(target -> {
|
||||
if (target.getVelocity().y < 0) {
|
||||
|
||||
boolean isSelf = caster.isOwnedBy(target) || target == entity;
|
||||
float delta = strength * (isSelf ? (1F - generosity) : generosity);
|
||||
|
||||
if (!isSelf || generosity < 0.5F) {
|
||||
if (negateFallDamage) {
|
||||
target.verticalCollision = true;
|
||||
target.setOnGround(true);
|
||||
target.fallDistance = 0;
|
||||
|
@ -94,6 +102,8 @@ public class FeatherFallSpell extends AbstractSpell implements TimedSpell {
|
|||
if (target instanceof PlayerEntity) {
|
||||
((PlayerEntity)target).getAbilities().flying = false;
|
||||
}
|
||||
|
||||
float delta = strength * ((caster.isOwnedBy(target) || target == entity) ? casterPreference : targetPreference);
|
||||
target.setVelocity(target.getVelocity().multiply(1, delta, 1));
|
||||
if (situation == Situation.PROJECTILE && target != entity) {
|
||||
target.addVelocity(masterVelocity.x, 0, masterVelocity.z);
|
||||
|
@ -102,33 +112,16 @@ public class FeatherFallSpell extends AbstractSpell implements TimedSpell {
|
|||
ParticleUtils.spawnParticles(new MagicParticleEffect(getType().getColor()), target, 7);
|
||||
});
|
||||
|
||||
return caster.subtractEnergyCost(timer.getTicksRemaining() % 50 == 0 ? getCostPerEntity(getTraits()) * targets.size() : 0);
|
||||
}
|
||||
|
||||
protected static double getCostPerEntity(SpellTraits traits) {
|
||||
float focus = Math.max(traits.get(Trait.FOCUS), 80) - 80;
|
||||
float power = Math.max(traits.get(Trait.POWER), 10) - 10;
|
||||
|
||||
return MathHelper.clamp((power * POWERS_RANGE_WEIGHT) - (focus * FOCUS_RANGE_WEIGHT), 1, 7);
|
||||
}
|
||||
|
||||
protected static double getEffectRange(SpellTraits traits) {
|
||||
return MathHelper.clamp((traits.get(Trait.POWER) - 10) * POWERS_RANGE_WEIGHT, MIN_RANGE, MAX_RANGE);
|
||||
}
|
||||
|
||||
protected static long getMaxTargets(SpellTraits traits) {
|
||||
long generosity = (long)traits.get(Trait.GENEROSITY) * 2L;
|
||||
long focus = (long)traits.get(Trait.FOCUS, MIN_TARGETS, MAX_TARGETS) * 2L;
|
||||
return generosity + focus;
|
||||
return caster.subtractEnergyCost(timer.getTicksRemaining() % 50 == 0 ? COST_PER_INDIVIDUAL.get(getTraits()) * targets.size() : 0);
|
||||
}
|
||||
|
||||
protected Stream<Entity> getTargets(Caster<?> caster) {
|
||||
return Stream.concat(Stream.of(caster.asEntity()), caster.findAllEntitiesInRange(getEffectRange(getTraits())).sorted((a, b) -> {
|
||||
return Stream.concat(Stream.of(caster.asEntity()), caster.findAllEntitiesInRange(RANGE.get(getTraits())).sorted((a, b) -> {
|
||||
return Integer.compare(
|
||||
FriendshipBraceletItem.isComrade(caster, a) ? 1 : 0,
|
||||
FriendshipBraceletItem.isComrade(caster, b) ? 1 : 0
|
||||
);
|
||||
}).distinct()).limit(getMaxTargets(getTraits()));
|
||||
}).distinct()).limit(SIMULTANIOUS_TARGETS.get(getTraits()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -4,9 +4,9 @@ import com.minelittlepony.unicopia.USounds;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -36,12 +36,12 @@ public class FireBoltSpell extends AbstractSpell implements HomingSpell,
|
|||
.with(Trait.FIRE, 60)
|
||||
.build();
|
||||
|
||||
private static final SpellAttribute<Float> VELOCITY = SpellAttribute.create(SpellAttributes.VELOCITY, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> 1.3F + (strength / 11F));
|
||||
private static final SpellAttribute<Integer> PROJECTILE_COUNT = SpellAttribute.create(SpellAttributes.PROJECTILE_COUNT, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.EARTH, earth -> 11 + (int)earth * 3);
|
||||
private static final SpellAttribute<Boolean> FOLLOWS_TARGET = SpellAttribute.createConditional(SpellAttributes.FOLLOWS_TARGET, Trait.FOCUS, focus -> focus >= 50);
|
||||
private static final SpellAttribute<Float> FOLLOW_RANGE = SpellAttribute.create(SpellAttributes.FOLLOW_RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> Math.max(0F, focus - 49));
|
||||
private static final SpellAttribute<Float> MAX_EXPLOSION_STRENGTH = SpellAttribute.create(SpellAttributes.EXPLOSION_STRENGTH, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> focus >= 50 ? 10F : 1F);
|
||||
private static final SpellAttribute<Float> EXPLOSION_STRENGTH = SpellAttribute.create(SpellAttributes.EXPLOSION_STRENGTH, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, (traits, focus) -> MathHelper.clamp(focus / 50, 0, MAX_EXPLOSION_STRENGTH.get(traits)));
|
||||
private static final SpellAttribute<Float> VELOCITY = SpellAttribute.create(SpellAttributeType.VELOCITY, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.STRENGTH, strength -> 1.3F + (strength / 11F));
|
||||
private static final SpellAttribute<Integer> PROJECTILE_COUNT = SpellAttribute.create(SpellAttributeType.PROJECTILE_COUNT, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.EARTH, earth -> 11 + (int)earth * 3);
|
||||
private static final SpellAttribute<Boolean> FOLLOWS_TARGET = SpellAttribute.createConditional(SpellAttributeType.FOLLOWS_TARGET, Trait.FOCUS, focus -> focus >= 50);
|
||||
private static final SpellAttribute<Float> FOLLOW_RANGE = SpellAttribute.create(SpellAttributeType.FOLLOW_RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> Math.max(0F, focus - 49));
|
||||
private static final SpellAttribute<Float> MAX_EXPLOSION_STRENGTH = SpellAttribute.create(SpellAttributeType.EXPLOSION_STRENGTH, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.FOCUS, focus -> focus >= 50 ? 10F : 1F);
|
||||
private static final SpellAttribute<Float> EXPLOSION_STRENGTH = SpellAttribute.create(SpellAttributeType.EXPLOSION_STRENGTH, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, (traits, focus) -> MathHelper.clamp(focus / 50, 0, MAX_EXPLOSION_STRENGTH.get(traits)));
|
||||
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(MAX_EXPLOSION_STRENGTH, EXPLOSION_STRENGTH, VELOCITY, PROJECTILE_COUNT, FOLLOWS_TARGET, FOLLOW_RANGE.conditionally(FOLLOWS_TARGET::get));
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ import java.util.List;
|
|||
import com.minelittlepony.unicopia.Owned;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -36,7 +36,7 @@ public class IceSpell extends AbstractSpell {
|
|||
.with(Trait.ICE, 15)
|
||||
.build();
|
||||
|
||||
private static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributes.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 3 + power));
|
||||
private static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributeType.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 3 + power));
|
||||
|
||||
static final TooltipFactory TOOLTIP = RANGE;
|
||||
|
||||
|
|
|
@ -6,10 +6,10 @@ import java.util.List;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.TimedSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -34,7 +34,7 @@ public class LightSpell extends AbstractSpell implements TimedSpell, ProjectileD
|
|||
.with(Trait.ORDER, 25)
|
||||
.build();
|
||||
|
||||
private static final SpellAttribute<Integer> ORB_COUNT = SpellAttribute.create(SpellAttributes.ORB_COUNT, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.LIFE, life -> 2 + (int)(MathHelper.clamp(life, 10, 20) / 10F));
|
||||
private static final SpellAttribute<Integer> ORB_COUNT = SpellAttribute.create(SpellAttributeType.ORB_COUNT, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.LIFE, life -> 2 + (int)(MathHelper.clamp(life, 10, 20) / 10F));
|
||||
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(TIME, ORB_COUNT);
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ import com.minelittlepony.unicopia.USounds;
|
|||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.AbstractAreaEffectSpell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
import com.minelittlepony.unicopia.entity.Creature;
|
||||
|
@ -83,7 +83,7 @@ public class NecromancySpell extends AbstractAreaEffectSpell implements Projecti
|
|||
return e -> e.getType() == type;
|
||||
}
|
||||
|
||||
static final SpellAttribute<Integer> WAVE_SIZE = SpellAttribute.create(SpellAttributes.WAVE_SIZE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.CHAOS, chaos -> 10 + (int)MathHelper.clamp(chaos, 0, 10));
|
||||
static final SpellAttribute<Integer> WAVE_SIZE = SpellAttribute.create(SpellAttributeType.WAVE_SIZE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.CHAOS, chaos -> 10 + (int)MathHelper.clamp(chaos, 0, 10));
|
||||
static final TooltipFactory TOOLTIP = TooltipFactory.of(RANGE, WAVE_SIZE);
|
||||
|
||||
private final List<EntityReference<LivingEntity>> summonedEntities = new ArrayList<>();
|
||||
|
|
|
@ -9,10 +9,10 @@ import com.minelittlepony.unicopia.ability.magic.Caster;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.CastingMethod;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellAttributes;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.AttributeFormat;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.CastOn;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttribute;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.SpellAttributeType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.attribute.TooltipFactory;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.SpellTraits;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.trait.Trait;
|
||||
|
@ -51,13 +51,13 @@ public class ShieldSpell extends AbstractSpell {
|
|||
.with(Trait.AIR, 9)
|
||||
.build();
|
||||
|
||||
static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributes.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 4 + power));
|
||||
protected static final SpellAttribute<CastOn> CAST_ON = SpellAttribute.createEnumerated(SpellAttributes.CAST_ON, Trait.GENEROSITY, generosity -> generosity > 0 ? CastOn.LOCATION : CastOn.SELF);
|
||||
static final SpellAttribute<Float> RANGE = SpellAttribute.create(SpellAttributeType.RANGE, AttributeFormat.REGULAR, AttributeFormat.PERCENTAGE, Trait.POWER, power -> Math.max(0, 4 + power));
|
||||
protected static final SpellAttribute<CastOn> CAST_ON = SpellAttribute.createEnumerated(SpellAttributeType.CAST_ON, Trait.GENEROSITY, generosity -> generosity > 0 ? CastOn.LOCATION : CastOn.SELF);
|
||||
|
||||
static final SpellAttribute<Boolean> TARGET_ITEMS = SpellAttribute.createConditional(SpellAttributes.PERMIT_ITEMS, Trait.KNOWLEDGE, knowledge -> knowledge > 10);
|
||||
static final SpellAttribute<Boolean> PERMIT_PASSIVE = SpellAttribute.createConditional(SpellAttributes.PERMIT_PASSIVE, Trait.LIFE, l -> l > 0);
|
||||
static final SpellAttribute<Boolean> PERMIT_HOSTILE = SpellAttribute.createConditional(SpellAttributes.PERMIT_HOSTILE, Trait.BLOOD, l -> l > 0);
|
||||
static final SpellAttribute<Boolean> PERMIT_PLAYER = SpellAttribute.createConditional(SpellAttributes.PERMIT_PLAYER, Trait.ICE, l -> l > 0);
|
||||
static final SpellAttribute<Boolean> TARGET_ITEMS = SpellAttribute.createConditional(SpellAttributeType.PERMIT_ITEMS, Trait.KNOWLEDGE, knowledge -> knowledge > 10);
|
||||
static final SpellAttribute<Boolean> PERMIT_PASSIVE = SpellAttribute.createConditional(SpellAttributeType.PERMIT_PASSIVE, Trait.LIFE, l -> l > 0);
|
||||
static final SpellAttribute<Boolean> PERMIT_HOSTILE = SpellAttribute.createConditional(SpellAttributeType.PERMIT_HOSTILE, Trait.BLOOD, l -> l > 0);
|
||||
static final SpellAttribute<Boolean> PERMIT_PLAYER = SpellAttribute.createConditional(SpellAttributeType.PERMIT_PLAYER, Trait.ICE, l -> l > 0);
|
||||
|
||||
static final TooltipFactory PERMIT_ENTITY = TooltipFactory.of(PERMIT_PASSIVE, PERMIT_HOSTILE, PERMIT_PLAYER);
|
||||
static final TooltipFactory TARGET = (type, tooltip) -> (TARGET_ITEMS.get(type.traits()) ? TARGET_ITEMS : PERMIT_ENTITY).appendTooltip(type, tooltip);
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.google.common.base.Suppliers;
|
||||
|
@ -69,7 +67,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
public static final SpellType<DisperseIllusionSpell> REVEALING = register("reveal", builder(DisperseIllusionSpell::new).color(0xFFFFAF).shape(GemstoneItem.Shape.CROSS).tooltip(DisperseIllusionSpell.TOOLTIP));
|
||||
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", builder(TransformationSpell::new).color(0x19E48E).shape(GemstoneItem.Shape.BRUSH));
|
||||
public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", builder(FeatherFallSpell::new).color(0x00EEFF).shape(GemstoneItem.Shape.LAMBDA).traits(FeatherFallSpell.DEFAULT_TRAITS).tooltip(FeatherFallSpell::appendTooltip));
|
||||
public static final SpellType<FeatherFallSpell> FEATHER_FALL = register("feather_fall", builder(FeatherFallSpell::new).color(0x00EEFF).shape(GemstoneItem.Shape.LAMBDA).traits(FeatherFallSpell.DEFAULT_TRAITS).tooltip(FeatherFallSpell.TOOLTIP));
|
||||
public static final SpellType<CatapultSpell> CATAPULT = register("catapult", builder(CatapultSpell::new).color(0x22FF00).shape(GemstoneItem.Shape.ROCKET).traits(CatapultSpell.DEFAULT_TRAITS).tooltip(CatapultSpell.TOOLTIP));
|
||||
public static final SpellType<FireBoltSpell> FIRE_BOLT = register("fire_bolt", builder(FireBoltSpell::new).color(0xFF8811).shape(GemstoneItem.Shape.FLAME).traits(FireBoltSpell.DEFAULT_TRAITS).tooltip(FireBoltSpell.TOOLTIP));
|
||||
public static final SpellType<LightSpell> LIGHT = register("light", builder(LightSpell::new).color(0xEEFFAA).shape(GemstoneItem.Shape.STAR).traits(LightSpell.DEFAULT_TRAITS).tooltip(LightSpell.TOOLTIP));
|
||||
|
@ -100,9 +98,9 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
|
||||
private final ItemStack defaultStack;
|
||||
|
||||
private final BiConsumer<CustomisedSpellType<T>, List<Text>> tooltipFunction;
|
||||
private final TooltipFactory tooltipFunction;
|
||||
|
||||
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, boolean stackable, GemstoneItem.Shape shape, SpellTraits traits, BiConsumer<CustomisedSpellType<T>, List<Text>> tooltipFunction, Factory<T> factory) {
|
||||
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, boolean stackable, GemstoneItem.Shape shape, SpellTraits traits, TooltipFactory tooltipFunction, Factory<T> factory) {
|
||||
this.id = id;
|
||||
this.affinity = affinity;
|
||||
this.color = color;
|
||||
|
@ -175,7 +173,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
return factory;
|
||||
}
|
||||
|
||||
public BiConsumer<CustomisedSpellType<T>, List<Text>> getTooltip() {
|
||||
public TooltipFactory getTooltip() {
|
||||
return tooltipFunction;
|
||||
}
|
||||
|
||||
|
@ -240,7 +238,7 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
private boolean stackable = false;
|
||||
private GemstoneItem.Shape shape = GemstoneItem.Shape.ROUND;
|
||||
private SpellTraits traits = SpellTraits.EMPTY;
|
||||
private BiConsumer<CustomisedSpellType<T>, List<Text>> tooltipFunction = (t, l) -> {};
|
||||
private TooltipFactory tooltipFunction = TooltipFactory.EMPTY;
|
||||
|
||||
Builder(Factory<T> factory) {
|
||||
this.factory = factory;
|
||||
|
@ -277,12 +275,6 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
}
|
||||
|
||||
public Builder<T> tooltip(TooltipFactory tooltipFunction) {
|
||||
this.tooltipFunction = tooltipFunction::appendTooltip;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public Builder<T> tooltip(BiConsumer<CustomisedSpellType<T>, List<Text>> tooltipFunction) {
|
||||
this.tooltipFunction = tooltipFunction;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -587,8 +587,8 @@
|
|||
"spell_attribute.unicopia.added_trait.plus": " + %s x%s",
|
||||
"spell_attribute.unicopia.added_trait.take": " - %s x%s",
|
||||
"spell_attribute.unicopia.added_trait.unknown": "Undiscovered Trait",
|
||||
"spell_attribute.unicopia.cast_on_location": "Applies to location",
|
||||
"spell_attribute.unicopia.cast_on_person": "Applies to self",
|
||||
"spell_attribute.unicopia.cast_on.location": "Applies to location",
|
||||
"spell_attribute.unicopia.cast_on.self": "Applies to self",
|
||||
"spell_attribute.unicopia.focused_entity": "Applies to focused entity",
|
||||
"spell_attribute.unicopia.affects.both": "Affects blocks and entities",
|
||||
"spell_attribute.unicopia.affects.entities": "Affects only entities",
|
||||
|
@ -615,10 +615,12 @@
|
|||
"spell_attribute.unicopia.explosion_strength": "Blast Strength",
|
||||
"spell_attribute.unicopia.projectile_count": "Projectile Count",
|
||||
"spell_attribute.unicopia.follow_range": "Following Range",
|
||||
"spell_attribute.unicopia.stick_to_target": "Attaches to Target",
|
||||
"spell_attribute.unicopia.orb_count": "Orb Count",
|
||||
"spell_attribute.unicopia.wave_size": "Wave Size",
|
||||
"spell_attribute.unicopia.target_preference": "Target Preference",
|
||||
"spell_attribute.unicopia.caster_preference": "Caster Preference",
|
||||
"spell_attribute.unicopia.negates_fall_damage": "Negates Fall Damage",
|
||||
|
||||
"trait.unicopia.strength.name": "Strength",
|
||||
"trait.unicopia.strength.description": "Imparts physical strength or enhances endurance.\nSpells with more of the strength trait hit harder and last longer.",
|
||||
|
|
Loading…
Reference in a new issue