mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-30 16:28:00 +01:00
Further cleanup to the magic system
This commit is contained in:
parent
b3e196c404
commit
269db7bdc9
25 changed files with 160 additions and 224 deletions
|
@ -2,8 +2,10 @@ package com.minelittlepony.unicopia;
|
||||||
|
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.Equine;
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
|
||||||
|
@ -28,7 +30,7 @@ public interface EquinePredicates {
|
||||||
|
|
||||||
Predicate<LivingEntity> HAS_WANT_IT_NEED_IT = e -> EnchantmentHelper.getEquipmentLevel(UEnchantments.WANT_IT_NEED_IT, e) > 0;
|
Predicate<LivingEntity> HAS_WANT_IT_NEED_IT = e -> EnchantmentHelper.getEquipmentLevel(UEnchantments.WANT_IT_NEED_IT, e) > 0;
|
||||||
|
|
||||||
static Predicate<Entity> carryingSpell(Class<? extends Spell> type) {
|
static Predicate<Entity> carryingSpell(@Nullable SpellType<?> type) {
|
||||||
return IS_PLAYER.and(entity -> Pony.of((PlayerEntity)entity).getSpellOrEmpty(type, false).isPresent());
|
return IS_PLAYER.and(entity -> Pony.of((PlayerEntity)entity).getSpellSlot().get(type, false).isPresent());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import com.minelittlepony.unicopia.EquinePredicates;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.ShieldSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
import com.minelittlepony.unicopia.util.MagicalDamageSource;
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ import net.minecraft.util.math.Vec3d;
|
||||||
*/
|
*/
|
||||||
public class BatEeeeAbility implements Ability<Hit> {
|
public class BatEeeeAbility implements Ability<Hit> {
|
||||||
|
|
||||||
private static final Predicate<Entity> HAS_SHIELD = EquinePredicates.carryingSpell(ShieldSpell.class);
|
private static final Predicate<Entity> HAS_SHIELD = EquinePredicates.carryingSpell(SpellType.SHIELD);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getWarmupTime(Pony player) {
|
public int getWarmupTime(Pony player) {
|
||||||
|
|
|
@ -44,7 +44,8 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
|
||||||
|
|
||||||
Entity looked = trace.getEntity().map(e -> {
|
Entity looked = trace.getEntity().map(e -> {
|
||||||
return e instanceof PlayerEntity ? Pony.of((PlayerEntity)e)
|
return e instanceof PlayerEntity ? Pony.of((PlayerEntity)e)
|
||||||
.getSpellOrEmpty(DisguiseSpell.class)
|
.getSpellSlot()
|
||||||
|
.get(SpellType.DISGUISE, true)
|
||||||
.map(DisguiseSpell::getDisguise)
|
.map(DisguiseSpell::getDisguise)
|
||||||
.map(Disguise::getAppearance)
|
.map(Disguise::getAppearance)
|
||||||
.orElse(e) : e;
|
.orElse(e) : e;
|
||||||
|
@ -57,7 +58,7 @@ public class ChangelingDisguiseAbility extends ChangelingFeedAbility {
|
||||||
|
|
||||||
player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F);
|
player.getEntityWorld().playSound(null, player.getBlockPos(), SoundEvents.ENTITY_PARROT_IMITATE_RAVAGER, SoundCategory.PLAYERS, 1.4F, 0.4F);
|
||||||
|
|
||||||
iplayer.getSpellOrEmpty(DisguiseSpell.class).orElseGet(() -> {
|
iplayer.getSpellSlot().get(SpellType.DISGUISE, true).orElseGet(() -> {
|
||||||
DisguiseSpell disc = SpellType.DISGUISE.create();
|
DisguiseSpell disc = SpellType.DISGUISE.create();
|
||||||
|
|
||||||
iplayer.setSpell(disc);
|
iplayer.setSpell(disc);
|
||||||
|
|
|
@ -40,7 +40,7 @@ public class PegasusRainboomAbility implements Ability<Hit> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.getPhysics().isFlying() && !player.hasSpell()) {
|
if (player.getPhysics().isFlying() && !player.getSpellSlot().isPresent()) {
|
||||||
return Hit.INSTANCE;
|
return Hit.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ public class PegasusRainboomAbility implements Ability<Hit> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.getPhysics().isFlying() && !player.hasSpell()) {
|
if (player.getPhysics().isFlying() && !player.getSpellSlot().isPresent()) {
|
||||||
player.getMagicalReserves().getMana().multiply(0.1F);
|
player.getMagicalReserves().getMana().multiply(0.1F);
|
||||||
player.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, player.getPhysics().getMotionAngle()), player.getOriginVector(), Vec3d.ZERO);
|
player.addParticle(new OrientedBillboardParticleEffect(UParticles.RAINBOOM_RING, player.getPhysics().getMotionAngle()), player.getOriginVector(), Vec3d.ZERO);
|
||||||
player.setSpell(SpellType.JOUSTING.create());
|
player.setSpell(SpellType.JOUSTING.create());
|
||||||
|
|
|
@ -7,6 +7,7 @@ import javax.annotation.Nullable;
|
||||||
import com.google.common.collect.Streams;
|
import com.google.common.collect.Streams;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.ability.data.Hit;
|
import com.minelittlepony.unicopia.ability.data.Hit;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.item.AmuletItem;
|
import com.minelittlepony.unicopia.item.AmuletItem;
|
||||||
|
@ -60,7 +61,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
return Hit.of(spell != ActionResult.FAIL && manaLevel > 4F);
|
return Hit.of(spell != ActionResult.FAIL && manaLevel > 4F);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Hit.of(manaLevel > (player.hasSpell() ? 2F : 4F));
|
return Hit.of(manaLevel > (player.getSpellSlot().isPresent() ? 2F : 4F));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -82,7 +83,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
return 4F;
|
return 4F;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player.hasSpell()) {
|
if (player.getSpellSlot().isPresent()) {
|
||||||
return 2F;
|
return 2F;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +113,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
if (newSpell.getResult() != ActionResult.FAIL) {
|
if (newSpell.getResult() != ActionResult.FAIL) {
|
||||||
@Nullable
|
@Nullable
|
||||||
SpellType<?> spell = newSpell.getValue();
|
SpellType<?> spell = newSpell.getValue();
|
||||||
if (!player.hasSpell() && spell == null) {
|
if (!player.getSpellSlot().isPresent() && spell == null) {
|
||||||
spell = SpellType.SHIELD;
|
spell = SpellType.SHIELD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +139,7 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypedActionResult<SpellType<?>> getNewSpell(Pony player) {
|
private TypedActionResult<SpellType<?>> getNewSpell(Pony player) {
|
||||||
final SpellType<?> current = player.hasSpell() ? player.getSpell(true).getType() : null;
|
final SpellType<?> current = player.getSpellSlot().get(true).map(Spell::getType).orElse(null);
|
||||||
return Streams.stream(player.getMaster().getItemsHand())
|
return Streams.stream(player.getMaster().getItemsHand())
|
||||||
.filter(GemstoneItem::isEnchanted)
|
.filter(GemstoneItem::isEnchanted)
|
||||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, SpellType::mayAttach))
|
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, SpellType::mayAttach))
|
||||||
|
|
|
@ -27,48 +27,10 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
|
||||||
|
|
||||||
Physics getPhysics();
|
Physics getPhysics();
|
||||||
|
|
||||||
EffectSync getPrimarySpellSlot();
|
EffectSync getSpellSlot();
|
||||||
|
|
||||||
default void setSpell(@Nullable Spell spell) {
|
default void setSpell(@Nullable Spell spell) {
|
||||||
getPrimarySpellSlot().set(spell);
|
getSpellSlot().put(spell);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active effect for this caster.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default Spell getSpell(boolean update) {
|
|
||||||
return getSpell(null, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active effect for the matching given type.
|
|
||||||
* Returns null if no such effect exists for this caster.
|
|
||||||
*/
|
|
||||||
@Nullable
|
|
||||||
default <T extends Spell> T getSpell(@Nullable Class<T> type, boolean update) {
|
|
||||||
return getPrimarySpellSlot().get(type, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active effect for this caster updating it if needed.
|
|
||||||
*/
|
|
||||||
default <T extends Spell> Optional<T> getSpellOrEmpty(Class<T> type, boolean update) {
|
|
||||||
return getPrimarySpellSlot().getOrEmpty(type, update);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the active effect for this caster updating it if needed.
|
|
||||||
*/
|
|
||||||
default <T extends Spell> Optional<T> getSpellOrEmpty(Class<T> type) {
|
|
||||||
return getSpellOrEmpty(type, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if this caster has an active effect attached to it.
|
|
||||||
*/
|
|
||||||
default boolean hasSpell() {
|
|
||||||
return getPrimarySpellSlot().has();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,7 +42,7 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gets the minecraft world
|
* Gets the minecraft world
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
default World getWorld() {
|
default World getWorld() {
|
||||||
|
|
|
@ -52,11 +52,4 @@ public interface Spell extends NbtSerialisable, Affine {
|
||||||
default boolean handleProjectileImpact(ProjectileEntity projectile) {
|
default boolean handleProjectileImpact(ProjectileEntity projectile) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a new, deep-copied instance of this spell.
|
|
||||||
*/
|
|
||||||
default Spell copy() {
|
|
||||||
return SpellType.copy(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.ability.magic.spell;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||||
import com.minelittlepony.unicopia.util.shape.Shape;
|
import com.minelittlepony.unicopia.util.shape.Shape;
|
||||||
|
@ -45,12 +44,12 @@ public class RevealingSpell extends AbstractSpell implements Attached, Thrown {
|
||||||
}
|
}
|
||||||
|
|
||||||
source.findAllSpellsInRange(15).forEach(e -> {
|
source.findAllSpellsInRange(15).forEach(e -> {
|
||||||
Suppressable spell = e.getSpell(Suppressable.class, false);
|
e.getSpellSlot().get(SpellPredicate.IS_SUPPRESSABLE, false)
|
||||||
|
.filter(spell -> spell.isVulnerable(source, this))
|
||||||
if (spell != null && spell.isVulnerable(source, this)) {
|
.ifPresent(spell -> {
|
||||||
spell.onSuppressed(source);
|
spell.onSuppressed(source);
|
||||||
source.getWorld().playSound(null, e.getOrigin(), SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, SoundCategory.PLAYERS, 0.2F, 0.5F);
|
source.getWorld().playSound(null, e.getOrigin(), SoundEvents.ENTITY_ZOMBIE_VILLAGER_CURE, SoundCategory.PLAYERS, 0.2F, 0.5F);
|
||||||
}
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package com.minelittlepony.unicopia.ability.magic.spell;
|
||||||
|
|
||||||
|
import java.util.function.Predicate;
|
||||||
|
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Attached;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Suppressable;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
||||||
|
|
||||||
|
public interface SpellPredicate<T> extends Predicate<Spell> {
|
||||||
|
SpellPredicate<Thrown> IS_THROWN = s -> s instanceof Thrown;
|
||||||
|
SpellPredicate<Attached> IS_ATTACHED = s -> s instanceof Attached;
|
||||||
|
SpellPredicate<Suppressable> IS_SUPPRESSABLE = s -> s instanceof Suppressable;
|
||||||
|
}
|
|
@ -10,9 +10,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
|
||||||
|
|
||||||
import net.minecraft.nbt.CompoundTag;
|
import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.text.Text;
|
import net.minecraft.text.Text;
|
||||||
|
@ -20,7 +18,7 @@ import net.minecraft.text.TranslatableText;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Util;
|
import net.minecraft.util.Util;
|
||||||
|
|
||||||
public class SpellType<T extends Spell> implements Affine {
|
public final class SpellType<T extends Spell> implements Affine, SpellPredicate<T> {
|
||||||
|
|
||||||
public static final Identifier EMPTY_ID = new Identifier("unicopia", "null");
|
public static final Identifier EMPTY_ID = new Identifier("unicopia", "null");
|
||||||
public static final SpellType<?> EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, t -> null);
|
public static final SpellType<?> EMPTY_KEY = new SpellType<>(EMPTY_ID, Affinity.NEUTRAL, 0xFFFFFF, false, t -> null);
|
||||||
|
@ -57,7 +55,7 @@ public class SpellType<T extends Spell> implements Affine {
|
||||||
@Nullable
|
@Nullable
|
||||||
private String translationKey;
|
private String translationKey;
|
||||||
|
|
||||||
SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
|
private SpellType(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.affinity = affinity;
|
this.affinity = affinity;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
@ -65,8 +63,8 @@ public class SpellType<T extends Spell> implements Affine {
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
|
|
||||||
Spell inst = create();
|
Spell inst = create();
|
||||||
thrown = inst instanceof Thrown;
|
thrown = SpellPredicate.IS_THROWN.test(inst);
|
||||||
attached = inst instanceof Attached;
|
attached = SpellPredicate.IS_ATTACHED.test(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isObtainable() {
|
public boolean isObtainable() {
|
||||||
|
@ -119,6 +117,11 @@ public class SpellType<T extends Spell> implements Affine {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean test(@Nullable Spell spell) {
|
||||||
|
return spell != null && spell.getType() == this;
|
||||||
|
}
|
||||||
|
|
||||||
public static <T extends Spell> SpellType<T> register(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
|
public static <T extends Spell> SpellType<T> register(Identifier id, Affinity affinity, int color, boolean obtainable, Factory<T> factory) {
|
||||||
SpellType<T> type = new SpellType<>(id, affinity, color, obtainable, factory);
|
SpellType<T> type = new SpellType<>(id, affinity, color, obtainable, factory);
|
||||||
byAffinity(affinity).add(type);
|
byAffinity(affinity).add(type);
|
||||||
|
@ -132,18 +135,13 @@ public class SpellType<T extends Spell> implements Affine {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static <T extends Spell> SpellType<T> getKey(Identifier id) {
|
public static <T extends Spell> SpellType<T> getKey(Identifier id) {
|
||||||
return (SpellType<T>)REGISTRY.getOrDefault(id, EMPTY_KEY);
|
return (SpellType<T>)(EMPTY_ID.equals(id) ? EMPTY_KEY : REGISTRY.getOrDefault(id, EMPTY_KEY));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Set<SpellType<?>> byAffinity(Affinity affinity) {
|
public static Set<SpellType<?>> byAffinity(Affinity affinity) {
|
||||||
return BY_AFFINITY.computeIfAbsent(affinity, a -> new HashSet<>());
|
return BY_AFFINITY.computeIfAbsent(affinity, a -> new HashSet<>());
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
|
||||||
public static <T extends Spell> T copy(T effect) {
|
|
||||||
return (T)fromNBT(toNBT(effect));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static Spell fromNBT(CompoundTag compound) {
|
public static Spell fromNBT(CompoundTag compound) {
|
||||||
if (compound.contains("effect_id")) {
|
if (compound.contains("effect_id")) {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||||
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
import com.minelittlepony.unicopia.ability.AbilitySlot;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.client.KeyBindingsHandler;
|
import com.minelittlepony.unicopia.client.KeyBindingsHandler;
|
||||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
@ -88,7 +89,7 @@ public class UHud extends DrawableHelper {
|
||||||
matrices.pop();
|
matrices.pop();
|
||||||
|
|
||||||
if (pony.getSpecies() == Race.CHANGELING && !client.player.isSneaking()) {
|
if (pony.getSpecies() == Race.CHANGELING && !client.player.isSneaking()) {
|
||||||
pony.getSpellOrEmpty(DisguiseSpell.class, false).map(DisguiseSpell::getDisguise)
|
pony.getSpellSlot().get(SpellType.DISGUISE, false).map(DisguiseSpell::getDisguise)
|
||||||
.map(Disguise::getAppearance)
|
.map(Disguise::getAppearance)
|
||||||
.ifPresent(appearance -> {
|
.ifPresent(appearance -> {
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ package com.minelittlepony.unicopia.client.render;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.Equine;
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
import com.minelittlepony.unicopia.entity.ItemImpl;
|
import com.minelittlepony.unicopia.entity.ItemImpl;
|
||||||
import com.minelittlepony.unicopia.entity.Living;
|
import com.minelittlepony.unicopia.entity.Living;
|
||||||
|
@ -83,7 +83,7 @@ public class WorldRenderDelegate {
|
||||||
|
|
||||||
int fireTicks = pony.getMaster().doesRenderOnFire() ? 1 : 0;
|
int fireTicks = pony.getMaster().doesRenderOnFire() ? 1 : 0;
|
||||||
|
|
||||||
return ((Caster<?>)pony).getSpellOrEmpty(DisguiseSpell.class, true).map(effect -> {
|
return ((Caster<?>)pony).getSpellSlot().get(SpellType.DISGUISE, true).map(effect -> {
|
||||||
effect.update(pony, false);
|
effect.update(pony, false);
|
||||||
|
|
||||||
Disguise ve = effect.getDisguise();
|
Disguise ve = effect.getDisguise();
|
||||||
|
|
|
@ -2,7 +2,6 @@ package com.minelittlepony.unicopia.command;
|
||||||
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
@ -61,13 +60,10 @@ public class DisguiseCommand {
|
||||||
throw FAILED_EXCEPTION.create();
|
throw FAILED_EXCEPTION.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
DisguiseSpell effect = iplayer.getSpell(DisguiseSpell.class, true);
|
iplayer.getSpellSlot()
|
||||||
|
.get(SpellType.DISGUISE, true)
|
||||||
if (effect == null) {
|
.orElseGet(SpellType.DISGUISE::create)
|
||||||
iplayer.setSpell(SpellType.DISGUISE.create().setDisguise(entity));
|
.setDisguise(entity);
|
||||||
} else {
|
|
||||||
effect.setDisguise(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isSelf) {
|
if (!isSelf) {
|
||||||
source.sendFeedback(new TranslatableText("commands.disguise.success.other", player.getName(), entity.getName()), true);
|
source.sendFeedback(new TranslatableText("commands.disguise.success.other", player.getName(), entity.getName()), true);
|
||||||
|
@ -83,7 +79,7 @@ public class DisguiseCommand {
|
||||||
|
|
||||||
static int reveal(ServerCommandSource source, PlayerEntity player) {
|
static int reveal(ServerCommandSource source, PlayerEntity player) {
|
||||||
Pony iplayer = Pony.of(player);
|
Pony iplayer = Pony.of(player);
|
||||||
iplayer.getSpellOrEmpty(DisguiseSpell.class).ifPresent(disguise -> {
|
iplayer.getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(disguise -> {
|
||||||
disguise.onDestroyed(iplayer);
|
disguise.onDestroyed(iplayer);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.ai.BreakHeartGoal;
|
import com.minelittlepony.unicopia.entity.ai.BreakHeartGoal;
|
||||||
import com.minelittlepony.unicopia.entity.ai.DynamicTargetGoal;
|
import com.minelittlepony.unicopia.entity.ai.DynamicTargetGoal;
|
||||||
|
@ -89,11 +88,9 @@ public class Creature extends Living<LivingEntity> {
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(CompoundTag compound) {
|
public void toNBT(CompoundTag compound) {
|
||||||
super.toNBT(compound);
|
super.toNBT(compound);
|
||||||
Spell effect = getSpell(true);
|
getSpellSlot().get(true).ifPresent(effect -> {
|
||||||
|
|
||||||
if (effect != null) {
|
|
||||||
compound.put("effect", SpellType.toNBT(effect));
|
compound.put("effect", SpellType.toNBT(effect));
|
||||||
}
|
});
|
||||||
physics.toNBT(compound);
|
physics.toNBT(compound);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,9 @@ import java.util.stream.Stream;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Attached;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.item.UItems;
|
import com.minelittlepony.unicopia.item.UItems;
|
||||||
import com.minelittlepony.unicopia.network.EffectSync;
|
import com.minelittlepony.unicopia.network.EffectSync;
|
||||||
|
|
||||||
|
@ -60,7 +59,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EffectSync getPrimarySpellSlot() {
|
public EffectSync getSpellSlot() {
|
||||||
return effectDelegate;
|
return effectDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,15 +78,11 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tick() {
|
public void tick() {
|
||||||
if (hasSpell()) {
|
getSpellSlot().get(SpellPredicate.IS_ATTACHED, true).ifPresent(effect -> {
|
||||||
Attached effect = getSpell(Attached.class, true);
|
|
||||||
|
|
||||||
if (effect != null) {
|
|
||||||
if (!effect.onBodyTick(this)) {
|
if (!effect.onBodyTick(this)) {
|
||||||
setSpell(null);
|
setSpell(null);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
|
||||||
|
|
||||||
if (invinsibilityTicks > 0) {
|
if (invinsibilityTicks > 0) {
|
||||||
invinsibilityTicks--;
|
invinsibilityTicks--;
|
||||||
|
@ -142,18 +137,13 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean onProjectileImpact(ProjectileEntity projectile) {
|
public boolean onProjectileImpact(ProjectileEntity projectile) {
|
||||||
if (hasSpell()) {
|
return getSpellSlot().get(true)
|
||||||
Spell effect = getSpell(true);
|
.filter(effect -> !effect.isDead() && effect.handleProjectileImpact(projectile))
|
||||||
if (!effect.isDead() && effect.handleProjectileImpact(projectile)) {
|
.isPresent();
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void handleFall(float distance, float damageMultiplier) {
|
protected void handleFall(float distance, float damageMultiplier) {
|
||||||
getSpellOrEmpty(DisguiseSpell.class, false).ifPresent(spell -> {
|
getSpellSlot().get(SpellType.DISGUISE, false).ifPresent(spell -> {
|
||||||
spell.getDisguise().onImpact(this, distance, damageMultiplier);
|
spell.getDisguise().onImpact(this, distance, damageMultiplier);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import com.minelittlepony.unicopia.FlightType;
|
||||||
import com.minelittlepony.unicopia.InteractionManager;
|
import com.minelittlepony.unicopia.InteractionManager;
|
||||||
import com.minelittlepony.unicopia.Owned;
|
import com.minelittlepony.unicopia.Owned;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.player.PlayerAttributes;
|
import com.minelittlepony.unicopia.entity.player.PlayerAttributes;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
import com.minelittlepony.unicopia.projectile.ProjectileUtil;
|
||||||
|
@ -345,7 +345,7 @@ public class Disguise implements NbtSerialisable {
|
||||||
VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D));
|
VoxelShape entityShape = VoxelShapes.cuboid(box.expand(1.0E-6D));
|
||||||
|
|
||||||
world.getOtherEntities(entity, box.expand(0.5), predicate.and(e -> {
|
world.getOtherEntities(entity, box.expand(0.5), predicate.and(e -> {
|
||||||
Caster.of(e).flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false)).ifPresent(p -> {
|
Caster.of(e).flatMap(c -> c.getSpellSlot().get(SpellType.DISGUISE, false)).ifPresent(p -> {
|
||||||
p.getDisguise().getCollissionShapes(ctx, shape -> {
|
p.getDisguise().getCollissionShapes(ctx, shape -> {
|
||||||
if (!shape.isEmpty() && VoxelShapes.matchesAnywhere(shape, entityShape, BooleanBiFunction.AND)) {
|
if (!shape.isEmpty() && VoxelShapes.matchesAnywhere(shape, entityShape, BooleanBiFunction.AND)) {
|
||||||
shapes.add(shape);
|
shapes.add(shape);
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Optional;
|
||||||
|
|
||||||
import com.minelittlepony.common.util.animation.MotionCompositor;
|
import com.minelittlepony.common.util.animation.MotionCompositor;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
|
||||||
|
@ -46,7 +47,8 @@ public class PlayerCamera extends MotionCompositor {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Double> calculateDistance(double distance) {
|
public Optional<Double> calculateDistance(double distance) {
|
||||||
return player.getSpellOrEmpty(DisguiseSpell.class, false)
|
return player.getSpellSlot()
|
||||||
|
.get(SpellType.DISGUISE, false)
|
||||||
.map(DisguiseSpell::getDisguise)
|
.map(DisguiseSpell::getDisguise)
|
||||||
.flatMap(d -> d.getDistance(player))
|
.flatMap(d -> d.getDistance(player))
|
||||||
.map(d -> distance * d);
|
.map(d -> distance * d);
|
||||||
|
|
|
@ -5,7 +5,6 @@ import java.util.Optional;
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Unicopia;
|
import com.minelittlepony.unicopia.Unicopia;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
|
||||||
|
|
||||||
import net.minecraft.entity.EntityDimensions;
|
import net.minecraft.entity.EntityDimensions;
|
||||||
|
|
||||||
|
@ -72,13 +71,9 @@ public final class PlayerDimensions {
|
||||||
}
|
}
|
||||||
|
|
||||||
Optional<Provider> getPredicate() {
|
Optional<Provider> getPredicate() {
|
||||||
if (pony.hasSpell()) {
|
return pony.getSpellSlot().get(true)
|
||||||
Spell effect = pony.getSpell(true);
|
.filter(effect -> !effect.isDead() && effect instanceof Provider)
|
||||||
if (!effect.isDead() && effect instanceof Provider) {
|
.map(effect -> (Provider)effect);
|
||||||
return Optional.of(((Provider)effect));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Optional.empty();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface Provider {
|
public interface Provider {
|
||||||
|
|
|
@ -3,8 +3,7 @@ package com.minelittlepony.unicopia.entity.player;
|
||||||
import com.minelittlepony.unicopia.FlightType;
|
import com.minelittlepony.unicopia.FlightType;
|
||||||
import com.minelittlepony.unicopia.Race;
|
import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.USounds;
|
import com.minelittlepony.unicopia.USounds;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.JoustingSpell;
|
|
||||||
import com.minelittlepony.unicopia.entity.Creature;
|
import com.minelittlepony.unicopia.entity.Creature;
|
||||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||||
import com.minelittlepony.unicopia.entity.Jumper;
|
import com.minelittlepony.unicopia.entity.Jumper;
|
||||||
|
@ -78,7 +77,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isRainbooming() {
|
public boolean isRainbooming() {
|
||||||
return pony.getSpellOrEmpty(JoustingSpell.class).isPresent();
|
return pony.getSpellSlot().get(SpellType.JOUSTING, true).isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -448,14 +447,10 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
|
||||||
return FlightType.ARTIFICIAL;
|
return FlightType.ARTIFICIAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pony.hasSpell()) {
|
return pony.getSpellSlot().get(true)
|
||||||
Spell effect = pony.getSpell(true);
|
.filter(effect -> !effect.isDead() && effect instanceof FlightType.Provider)
|
||||||
if (!effect.isDead() && effect instanceof FlightType.Provider) {
|
.map(effect -> ((FlightType.Provider)effect).getFlightType(pony))
|
||||||
return ((FlightType.Provider)effect).getFlightType(pony);
|
.orElse(pony.getSpecies().getFlightType());
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pony.getSpecies().getFlightType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateFlightStat(boolean flying) {
|
public void updateFlightStat(boolean flying) {
|
||||||
|
|
|
@ -14,7 +14,6 @@ import com.minelittlepony.unicopia.Race;
|
||||||
import com.minelittlepony.unicopia.WorldTribeManager;
|
import com.minelittlepony.unicopia.WorldTribeManager;
|
||||||
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
import com.minelittlepony.unicopia.ability.AbilityDispatcher;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.ShieldSpell;
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.Physics;
|
import com.minelittlepony.unicopia.entity.Physics;
|
||||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||||
|
@ -134,7 +133,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isInvisible() {
|
public boolean isInvisible() {
|
||||||
return invisible && hasSpell();
|
return invisible && getSpellSlot().isPresent();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isSpeciesPersisted() {
|
public boolean isSpeciesPersisted() {
|
||||||
|
@ -289,7 +288,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
||||||
|
|
||||||
float g = gravity.getGravityModifier();
|
float g = gravity.getGravityModifier();
|
||||||
|
|
||||||
boolean extraProtection = getSpell(ShieldSpell.class, false) != null;
|
boolean extraProtection = getSpellSlot().get(SpellType.SHIELD, false).isPresent();
|
||||||
|
|
||||||
if (g != 1 || extraProtection || getSpecies().canFly() && !entity.isCreative() && !entity.isSpectator()) {
|
if (g != 1 || extraProtection || getSpecies().canFly() && !entity.isCreative() && !entity.isSpectator()) {
|
||||||
|
|
||||||
|
@ -384,11 +383,9 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
||||||
compound.put("powers", powers.toNBT());
|
compound.put("powers", powers.toNBT());
|
||||||
compound.put("gravity", gravity.toNBT());
|
compound.put("gravity", gravity.toNBT());
|
||||||
|
|
||||||
Spell effect = getSpell(true);
|
getSpellSlot().get(true).ifPresent(effect ->{
|
||||||
|
|
||||||
if (effect != null) {
|
|
||||||
compound.put("effect", SpellType.toNBT(effect));
|
compound.put("effect", SpellType.toNBT(effect));
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -403,7 +400,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
||||||
magicExhaustion = compound.getFloat("magicExhaustion");
|
magicExhaustion = compound.getFloat("magicExhaustion");
|
||||||
|
|
||||||
if (compound.contains("effect")) {
|
if (compound.contains("effect")) {
|
||||||
getPrimarySpellSlot().set(SpellType.fromNBT(compound.getCompound("effect")));
|
getSpellSlot().put(SpellType.fromNBT(compound.getCompound("effect")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -411,7 +408,7 @@ public class Pony extends Living<PlayerEntity> implements Transmittable, Copieab
|
||||||
public void copyFrom(Pony oldPlayer) {
|
public void copyFrom(Pony oldPlayer) {
|
||||||
speciesPersisted = oldPlayer.speciesPersisted;
|
speciesPersisted = oldPlayer.speciesPersisted;
|
||||||
if (!oldPlayer.getEntity().removed) {
|
if (!oldPlayer.getEntity().removed) {
|
||||||
setSpell(oldPlayer.getSpell(true));
|
setSpell(oldPlayer.getSpellSlot().get(true).orElse(null));
|
||||||
}
|
}
|
||||||
setSpecies(oldPlayer.getSpecies());
|
setSpecies(oldPlayer.getSpecies());
|
||||||
setDirty();
|
setDirty();
|
||||||
|
|
|
@ -14,6 +14,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.Creature;
|
import com.minelittlepony.unicopia.entity.Creature;
|
||||||
import com.minelittlepony.unicopia.entity.PonyContainer;
|
import com.minelittlepony.unicopia.entity.PonyContainer;
|
||||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||||
|
@ -82,7 +83,7 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
||||||
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isClimbing()Z", at = @At("HEAD"), cancellable = true)
|
||||||
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
public void onIsClimbing(CallbackInfoReturnable<Boolean> info) {
|
||||||
if (get() instanceof Pony && horizontalCollision) {
|
if (get() instanceof Pony && horizontalCollision) {
|
||||||
((Pony)get()).getSpellOrEmpty(DisguiseSpell.class, false)
|
((Pony)get()).getSpellSlot().get(SpellType.DISGUISE, false)
|
||||||
.map(DisguiseSpell::getDisguise)
|
.map(DisguiseSpell::getDisguise)
|
||||||
.filter(Disguise::canClimbWalls)
|
.filter(Disguise::canClimbWalls)
|
||||||
.ifPresent(v -> {
|
.ifPresent(v -> {
|
||||||
|
@ -95,7 +96,7 @@ abstract class MixinLivingEntity extends Entity implements PonyContainer<Equine<
|
||||||
@Inject(method = "isPushable()Z", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "isPushable()Z", at = @At("HEAD"), cancellable = true)
|
||||||
private void onIsPushable(CallbackInfoReturnable<Boolean> info) {
|
private void onIsPushable(CallbackInfoReturnable<Boolean> info) {
|
||||||
Caster.of(this)
|
Caster.of(this)
|
||||||
.flatMap(c -> c.getSpellOrEmpty(DisguiseSpell.class, false))
|
.flatMap(c -> c.getSpellSlot().get(SpellType.DISGUISE, false))
|
||||||
.map(DisguiseSpell::getDisguise)
|
.map(DisguiseSpell::getDisguise)
|
||||||
.map(Disguise::getAppearance)
|
.map(Disguise::getAppearance)
|
||||||
.filter(Entity::isPushable)
|
.filter(Entity::isPushable)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.DisguiseSpell;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.Equine;
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@ abstract class MixinTargetPredicate {
|
||||||
public void onTest(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable<Boolean> info) {
|
public void onTest(@Nullable LivingEntity baseEntity, LivingEntity targetEntity, CallbackInfoReturnable<Boolean> info) {
|
||||||
Equine<?> eq = Equine.of(targetEntity);
|
Equine<?> eq = Equine.of(targetEntity);
|
||||||
if (eq instanceof Pony) {
|
if (eq instanceof Pony) {
|
||||||
((Pony)eq).getSpellOrEmpty(DisguiseSpell.class).ifPresent(spell -> {
|
((Pony)eq).getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(spell -> {
|
||||||
if (spell.getDisguise().getAppearance() == baseEntity) {
|
if (spell.getDisguise().getAppearance() == baseEntity) {
|
||||||
info.setReturnValue(false);
|
info.setReturnValue(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import javax.annotation.Nullable;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
|
|
||||||
import net.minecraft.entity.data.TrackedData;
|
import net.minecraft.entity.data.TrackedData;
|
||||||
|
@ -13,7 +14,7 @@ import net.minecraft.nbt.CompoundTag;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Synchronisation class for spell effects.
|
* Synchronisation class for spells.
|
||||||
* Since we can't have our own serializers, we have to intelligently
|
* Since we can't have our own serializers, we have to intelligently
|
||||||
* determine whether to update it from an nbt tag.
|
* determine whether to update it from an nbt tag.
|
||||||
*
|
*
|
||||||
|
@ -21,85 +22,83 @@ import net.minecraft.util.Identifier;
|
||||||
*/
|
*/
|
||||||
public class EffectSync {
|
public class EffectSync {
|
||||||
|
|
||||||
@Nullable
|
private Optional<Spell> spell = Optional.empty();
|
||||||
private Spell effect;
|
|
||||||
|
|
||||||
private final Caster<?> owned;
|
private final Caster<?> owner;
|
||||||
|
|
||||||
private final TrackedData<CompoundTag> param;
|
private final TrackedData<CompoundTag> param;
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private CompoundTag lastValue;
|
private CompoundTag lastValue;
|
||||||
|
|
||||||
public EffectSync(Caster<?> owned, TrackedData<CompoundTag> param) {
|
public EffectSync(Caster<?> owner, TrackedData<CompoundTag> param) {
|
||||||
this.owned = owned;
|
this.owner = owner;
|
||||||
this.param = param;
|
this.param = param;
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T extends Spell> Optional<T> getOrEmpty(Class<T> type, boolean update) {
|
/**
|
||||||
T effect = get(type, update);
|
* Gets the active effect for this caster updating it if needed.
|
||||||
|
*/
|
||||||
if (effect == null || effect.isDead()) {
|
public <T extends Spell> Optional<T> get(boolean update) {
|
||||||
return Optional.empty();
|
return get(null, update);
|
||||||
}
|
|
||||||
|
|
||||||
return Optional.of(effect);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the active effect for this caster updating it if needed.
|
||||||
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public <E extends Spell> E get(Class<E> type, boolean update) {
|
public <T extends Spell> Optional<T> get(@Nullable SpellPredicate<T> type, boolean update) {
|
||||||
if (update) {
|
if (update) {
|
||||||
sync(true);
|
sync(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effect == null || type == null || type.isAssignableFrom(effect.getClass())) {
|
if (checkReference() && (type == null || type.test(spell.get()))) {
|
||||||
return (E)effect;
|
return (Optional<T>)spell;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return Optional.empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean has() {
|
/**
|
||||||
|
* Returns true if this caster has an active effect attached to it.
|
||||||
|
*/
|
||||||
|
public boolean isPresent() {
|
||||||
sync(false);
|
sync(false);
|
||||||
return effect != null;
|
return checkReference();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean checkReference() {
|
||||||
|
return spell.isPresent() && !spell.get().isDead();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sync(boolean force) {
|
private void sync(boolean force) {
|
||||||
CompoundTag comp = owned.getEntity().getDataTracker().get(param);
|
CompoundTag comp = owner.getEntity().getDataTracker().get(param);
|
||||||
|
|
||||||
|
Spell effect = spell.orElse(null);
|
||||||
|
|
||||||
if (comp == null || !comp.contains("effect_id")) {
|
if (comp == null || !comp.contains("effect_id")) {
|
||||||
if (effect != null) {
|
updateReference(null);
|
||||||
effect.setDead();
|
} else if (!checkReference() || !effect.getType().getId().equals(new Identifier(comp.getString("effect_id")))) {
|
||||||
effect = null;
|
updateReference(SpellType.fromNBT(comp));
|
||||||
}
|
} else if (owner.getEntity().world.isClient()) {
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if (effect == null || !effect.getType().getId().equals(new Identifier(comp.getString("effect_id")))) {
|
|
||||||
if (effect != null) {
|
|
||||||
effect.setDead();
|
|
||||||
}
|
|
||||||
effect = SpellType.fromNBT(comp);
|
|
||||||
} else if (owned.getEntity().world.isClient()) {
|
|
||||||
if (lastValue != comp || !(comp == null || comp.equals(lastValue))) {
|
if (lastValue != comp || !(comp == null || comp.equals(lastValue))) {
|
||||||
lastValue = comp;
|
lastValue = comp;
|
||||||
effect.fromNBT(comp);
|
effect.fromNBT(comp);
|
||||||
}
|
}
|
||||||
} else if ((force || !owned.getEntity().world.isClient()) && effect.isDirty()) {
|
} else if ((force || !owner.isClient()) && effect.isDirty()) {
|
||||||
set(effect);
|
put(effect);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void set(@Nullable Spell effect) {
|
public void put(@Nullable Spell effect) {
|
||||||
if (this.effect != null && this.effect != effect) {
|
updateReference(effect);
|
||||||
this.effect.setDead();
|
owner.getEntity().getDataTracker().set(param, effect == null ? new CompoundTag() : SpellType.toNBT(effect));
|
||||||
}
|
}
|
||||||
this.effect = effect;
|
|
||||||
|
|
||||||
if (effect == null) {
|
private void updateReference(@Nullable Spell effect) {
|
||||||
owned.getEntity().getDataTracker().set(param, new CompoundTag());
|
if (spell.isPresent() && spell.get() != effect) {
|
||||||
} else {
|
spell.get().setDead();
|
||||||
owned.getEntity().getDataTracker().set(param, SpellType.toNBT(effect));
|
|
||||||
}
|
}
|
||||||
|
spell = Optional.ofNullable(effect);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||||
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.Equine;
|
import com.minelittlepony.unicopia.entity.Equine;
|
||||||
|
|
||||||
|
@ -66,7 +67,7 @@ public class ParticleHandle {
|
||||||
public void attach(Caster<?> caster) {
|
public void attach(Caster<?> caster) {
|
||||||
this.linked = true;
|
this.linked = true;
|
||||||
this.caster = Optional.of(caster);
|
this.caster = Optional.of(caster);
|
||||||
this.effect = caster.getSpell(false).getType();
|
this.effect = caster.getSpellSlot().get(false).map(Spell::getType).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void detach() {
|
public void detach() {
|
||||||
|
@ -81,10 +82,10 @@ public class ParticleHandle {
|
||||||
caster = caster.filter(c -> {
|
caster = caster.filter(c -> {
|
||||||
Entity e = c.getEntity();
|
Entity e = c.getEntity();
|
||||||
|
|
||||||
|
|
||||||
return Equine.of(e) == c
|
return Equine.of(e) == c
|
||||||
&& c.hasSpell()
|
&& c.getSpellSlot().get(false)
|
||||||
&& c.getSpell(false).getType().equals(effect)
|
.filter(s -> s.getType() == effect)
|
||||||
|
.isPresent()
|
||||||
&& e != null
|
&& e != null
|
||||||
&& c.getWorld().getEntityById(e.getEntityId()) != null;
|
&& c.getWorld().getEntityById(e.getEntityId()) != null;
|
||||||
});
|
});
|
||||||
|
|
|
@ -2,11 +2,12 @@ package com.minelittlepony.unicopia.projectile;
|
||||||
|
|
||||||
import com.minelittlepony.unicopia.Affinity;
|
import com.minelittlepony.unicopia.Affinity;
|
||||||
import com.minelittlepony.unicopia.UEntities;
|
import com.minelittlepony.unicopia.UEntities;
|
||||||
|
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.Levelled;
|
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Magical;
|
import com.minelittlepony.unicopia.ability.magic.Magical;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||||
import com.minelittlepony.unicopia.ability.magic.Thrown;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
||||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||||
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
import com.minelittlepony.unicopia.entity.EntityPhysics;
|
||||||
import com.minelittlepony.unicopia.entity.Physics;
|
import com.minelittlepony.unicopia.entity.Physics;
|
||||||
|
@ -77,7 +78,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Item getDefaultItem() {
|
protected Item getDefaultItem() {
|
||||||
switch (getSpellOrEmpty(Spell.class, false).map(Spell::getAffinity).orElse(Affinity.NEUTRAL)) {
|
switch (getSpellSlot().get(false).map(Spell::getAffinity).orElse(Affinity.NEUTRAL)) {
|
||||||
case GOOD: return Items.SNOWBALL;
|
case GOOD: return Items.SNOWBALL;
|
||||||
case BAD: return Items.MAGMA_CREAM;
|
case BAD: return Items.MAGMA_CREAM;
|
||||||
default: return Items.AIR;
|
default: return Items.AIR;
|
||||||
|
@ -111,11 +112,11 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Affinity getAffinity() {
|
public Affinity getAffinity() {
|
||||||
return hasSpell() ? getSpell(true).getAffinity() : Affinity.NEUTRAL;
|
return getSpellSlot().get(true).map(Affine::getAffinity).orElse(Affinity.NEUTRAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EffectSync getPrimarySpellSlot() {
|
public EffectSync getSpellSlot() {
|
||||||
return effectDelegate;
|
return effectDelegate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,17 +159,13 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
setNoGravity(false);
|
setNoGravity(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasSpell()) {
|
if (getSpellSlot().isPresent()) {
|
||||||
if (lastBlockPos == null || !lastBlockPos.equals(getBlockPos())) {
|
if (lastBlockPos == null || !lastBlockPos.equals(getBlockPos())) {
|
||||||
lastBlockPos = getBlockPos();
|
lastBlockPos = getBlockPos();
|
||||||
}
|
}
|
||||||
|
|
||||||
Thrown spell = getSpell(Thrown.class, true);
|
if (!getSpellSlot().get(SpellPredicate.IS_THROWN, true).filter(spell -> spell.onThrownTick(this)).isPresent()) {
|
||||||
|
|
||||||
if (spell.isDead()) {
|
|
||||||
remove();
|
remove();
|
||||||
} else {
|
|
||||||
spell.onThrownTick(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -228,10 +225,9 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
public void writeCustomDataToTag(CompoundTag compound) {
|
public void writeCustomDataToTag(CompoundTag compound) {
|
||||||
super.writeCustomDataToTag(compound);
|
super.writeCustomDataToTag(compound);
|
||||||
physics.toNBT(compound);
|
physics.toNBT(compound);
|
||||||
|
getSpellSlot().get(true).ifPresent(effect -> {
|
||||||
if (hasSpell()) {
|
compound.put("effect", SpellType.toNBT(effect));
|
||||||
compound.put("effect", SpellType.toNBT(getSpell(true)));
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -249,13 +245,9 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onBlockHit(BlockHitResult hit) {
|
protected void onBlockHit(BlockHitResult hit) {
|
||||||
if (hasSpell()) {
|
getSpellSlot().get(SpellPredicate.IS_THROWN, true).ifPresent(effect -> {
|
||||||
Spell effect = getSpell(true);
|
effect.onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()));
|
||||||
|
});
|
||||||
if (effect instanceof ProjectileDelegate) {
|
|
||||||
((ProjectileDelegate)effect).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getItem().getItem() instanceof ProjectileDelegate) {
|
if (getItem().getItem() instanceof ProjectileDelegate) {
|
||||||
((ProjectileDelegate)getItem().getItem()).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()));
|
((ProjectileDelegate)getItem().getItem()).onImpact(this, hit.getBlockPos(), world.getBlockState(hit.getBlockPos()));
|
||||||
|
|
Loading…
Reference in a new issue