mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-27 15:17:59 +01:00
A little more cleanup to the magic system
This commit is contained in:
parent
d27de0f690
commit
6d3d8051fe
16 changed files with 73 additions and 55 deletions
|
@ -111,14 +111,10 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
TypedActionResult<SpellType<?>> newSpell = getNewSpell(player);
|
||||
|
||||
if (newSpell.getResult() != ActionResult.FAIL) {
|
||||
@Nullable
|
||||
SpellType<?> spell = newSpell.getValue();
|
||||
if (!player.getSpellSlot().isPresent() && spell == null) {
|
||||
spell = SpellType.SHIELD;
|
||||
}
|
||||
|
||||
player.subtractEnergyCost(spell == null ? 2 : 4);
|
||||
player.setSpell(spell == null ? null : spell.create());
|
||||
player.subtractEnergyCost(spell.isEmpty() ? 2 : 4);
|
||||
spell.apply(player);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -139,12 +135,12 @@ public class UnicornCastingAbility implements Ability<Hit> {
|
|||
}
|
||||
|
||||
private TypedActionResult<SpellType<?>> getNewSpell(Pony player) {
|
||||
final SpellType<?> current = player.getSpellSlot().get(true).map(Spell::getType).orElse(null);
|
||||
final SpellType<?> current = player.getSpellSlot().get(true).map(Spell::getType).orElse(SpellType.empty());
|
||||
return Streams.stream(player.getMaster().getItemsHand())
|
||||
.filter(GemstoneItem::isEnchanted)
|
||||
.map(stack -> GemstoneItem.consumeSpell(stack, player.getMaster(), current, SpellType::mayAttach))
|
||||
.findFirst()
|
||||
.orElse(TypedActionResult.<SpellType<?>>pass(null));
|
||||
.orElse(TypedActionResult.<SpellType<?>>pass(current == SpellType.EMPTY_KEY ? SpellType.SHIELD : SpellType.EMPTY_KEY));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -5,8 +5,6 @@ import java.util.UUID;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
|
||||
/**
|
||||
* Interface for a magic spells
|
||||
*/
|
||||
|
@ -38,25 +36,17 @@ public interface Spell extends NbtSerialisable, Affine {
|
|||
boolean isDirty();
|
||||
|
||||
/**
|
||||
* Marks this effect as dirty.
|
||||
* Applies this spell to the supplied caster.
|
||||
*/
|
||||
void setDirty(boolean dirty);
|
||||
boolean apply(Caster<?> caster);
|
||||
|
||||
/**
|
||||
* Called when first attached to a gem.
|
||||
* Marks this effect as dirty.
|
||||
*/
|
||||
default void onPlaced(Caster<?> caster) {
|
||||
|
||||
}
|
||||
void setDirty();
|
||||
|
||||
/**
|
||||
* Called when a gem is destroyed.
|
||||
*/
|
||||
default void onDestroyed(Caster<?> caster) {
|
||||
setDead();
|
||||
}
|
||||
|
||||
default boolean handleProjectileImpact(ProjectileEntity projectile) {
|
||||
return false;
|
||||
}
|
||||
void onDestroyed(Caster<?> caster);
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac
|
|||
|
||||
if (dimension == null) {
|
||||
dimension = source.getWorld().getRegistryKey().getValue();
|
||||
setDirty(true);
|
||||
setDirty();
|
||||
} else if (!source.getWorld().getRegistryKey().getValue().equals(dimension)) {
|
||||
return false;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ public abstract class AbstractPlacedSpell extends AbstractSpell implements Attac
|
|||
entity.world.spawnEntity(entity);
|
||||
|
||||
castEntity.set(entity);
|
||||
setDirty(true);
|
||||
setDirty();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package com.minelittlepony.unicopia.ability.magic.spell;
|
|||
import java.util.UUID;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -34,6 +35,7 @@ public abstract class AbstractSpell implements Spell {
|
|||
@Override
|
||||
public void setDead() {
|
||||
isDead = true;
|
||||
setDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -47,8 +49,8 @@ public abstract class AbstractSpell implements Spell {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void setDirty(boolean dirty) {
|
||||
isDirty = dirty;
|
||||
public void setDirty() {
|
||||
isDirty = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -56,6 +58,17 @@ public abstract class AbstractSpell implements Spell {
|
|||
return getType().getAffinity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean apply(Caster<?> caster) {
|
||||
caster.setSpell(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyed(Caster<?> caster) {
|
||||
setDead();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(CompoundTag compound) {
|
||||
compound.putBoolean("dead", isDead);
|
||||
|
@ -64,7 +77,7 @@ public abstract class AbstractSpell implements Spell {
|
|||
|
||||
@Override
|
||||
public void fromNBT(CompoundTag compound) {
|
||||
setDirty(false);
|
||||
isDirty = false;
|
||||
if (compound.contains("uuid")) {
|
||||
uuid = compound.getUuid("uuid");
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ import com.minelittlepony.unicopia.entity.player.Pony;
|
|||
import com.minelittlepony.unicopia.entity.player.PlayerDimensions;
|
||||
import com.minelittlepony.unicopia.particle.MagicParticleEffect;
|
||||
import com.minelittlepony.unicopia.particle.UParticles;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityDimensions;
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
|
@ -25,7 +27,7 @@ import net.minecraft.entity.player.PlayerEntity;
|
|||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
||||
public class DisguiseSpell extends AbstractSpell implements Attached, Suppressable, FlightType.Provider, PlayerDimensions.Provider {
|
||||
public class DisguiseSpell extends AbstractSpell implements Attached, Suppressable, FlightType.Provider, PlayerDimensions.Provider, ProjectileImpactListener {
|
||||
|
||||
private final Disguise disguise = new Disguise();
|
||||
|
||||
|
@ -49,7 +51,7 @@ public class DisguiseSpell extends AbstractSpell implements Attached, Suppressab
|
|||
@Override
|
||||
public void onSuppressed(Caster<?> otherSource) {
|
||||
suppressionCounter = 100;
|
||||
setDirty(true);
|
||||
setDirty();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -67,12 +69,12 @@ public class DisguiseSpell extends AbstractSpell implements Attached, Suppressab
|
|||
}
|
||||
|
||||
disguise.setAppearance(entity);
|
||||
setDirty(true);
|
||||
setDirty();
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleProjectileImpact(ProjectileEntity projectile) {
|
||||
public boolean onProjectileImpact(ProjectileEntity projectile) {
|
||||
return disguise.getAppearance() == projectile;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,11 +22,6 @@ public class RevealingSpell extends AbstractSpell implements Attached, Thrown {
|
|||
super(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPlaced(Caster<?> source) {
|
||||
source.getLevel().set(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onThrownTick(MagicProjectileEntity projectile) {
|
||||
return onBodyTick(projectile);
|
||||
|
|
|
@ -90,7 +90,7 @@ public class ShieldSpell extends AbstractSpell implements Attached, Thrown {
|
|||
cost /= 2.725D;
|
||||
|
||||
if (!source.subtractEnergyCost(cost)) {
|
||||
onDestroyed(source);
|
||||
setDead();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -86,14 +86,14 @@ public class SiphoningSpell extends AbstractPlacedSpell {
|
|||
|
||||
if (ticksUpset > 0 || maxHealthGain <= 0) {
|
||||
if (source.getWorld().random.nextInt(3000) == 0) {
|
||||
onDestroyed(source);
|
||||
setDead();
|
||||
} else {
|
||||
e.damage(damage, e.getHealth() / 4);
|
||||
}
|
||||
if (maxHealthGain <= 0) {
|
||||
ticksUpset = 100;
|
||||
}
|
||||
setDirty(true);
|
||||
setDirty();
|
||||
} else {
|
||||
e.heal((float)Math.min(0.5F * (1 + source.getLevel().get()), maxHealthGain * 0.6));
|
||||
ParticleUtils.spawnParticle(new FollowingParticleEffect(UParticles.HEALTH_DRAIN, e, 0.2F), e.world, e.getPos(), Vec3d.ZERO);
|
||||
|
|
|
@ -10,6 +10,7 @@ import javax.annotation.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.ability.magic.Affine;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
|
||||
import net.minecraft.nbt.CompoundTag;
|
||||
|
@ -117,11 +118,24 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
return null;
|
||||
}
|
||||
|
||||
public boolean apply(Caster<?> caster) {
|
||||
if (isEmpty()) {
|
||||
caster.setSpell(null);
|
||||
return false;
|
||||
}
|
||||
|
||||
return create().apply(caster);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean test(@Nullable Spell spell) {
|
||||
return spell != null && spell.getType() == this;
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
return this == EMPTY_KEY;
|
||||
}
|
||||
|
||||
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);
|
||||
byAffinity(affinity).add(type);
|
||||
|
@ -133,6 +147,11 @@ public final class SpellType<T extends Spell> implements Affine, SpellPredicate<
|
|||
return register(new Identifier("unicopia", name), affinity, color, obtainable, factory);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Spell> SpellType<T> empty() {
|
||||
return (SpellType<T>)EMPTY_KEY;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Spell> SpellType<T> getKey(Identifier id) {
|
||||
return (SpellType<T>)(EMPTY_ID.equals(id) ? EMPTY_KEY : REGISTRY.getOrDefault(id, EMPTY_KEY));
|
||||
|
|
|
@ -2,6 +2,7 @@ package com.minelittlepony.unicopia.command;
|
|||
|
||||
import java.util.function.Function;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
@ -79,9 +80,7 @@ public class DisguiseCommand {
|
|||
|
||||
static int reveal(ServerCommandSource source, PlayerEntity player) {
|
||||
Pony iplayer = Pony.of(player);
|
||||
iplayer.getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(disguise -> {
|
||||
disguise.onDestroyed(iplayer);
|
||||
});
|
||||
iplayer.getSpellSlot().get(SpellType.DISGUISE, true).ifPresent(Spell::setDead);
|
||||
|
||||
if (player.getEntityWorld().getGameRules().getBoolean(GameRules.SEND_COMMAND_FEEDBACK)) {
|
||||
player.sendMessage(new TranslatableText("commands.disguise.removed"), false);
|
||||
|
|
|
@ -5,6 +5,7 @@ import java.util.Optional;
|
|||
import javax.annotation.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.Race;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
|
@ -12,7 +13,7 @@ import net.minecraft.entity.damage.DamageSource;
|
|||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
import net.minecraft.util.Tickable;
|
||||
|
||||
public interface Equine<T extends Entity> extends NbtSerialisable, Tickable {
|
||||
public interface Equine<T extends Entity> extends NbtSerialisable, Tickable, ProjectileImpactListener {
|
||||
Race getSpecies();
|
||||
|
||||
Physics getPhysics();
|
||||
|
@ -44,6 +45,7 @@ public interface Equine<T extends Entity> extends NbtSerialisable, Tickable {
|
|||
/**
|
||||
* Event triggered when this entity is hit by a projectile.
|
||||
*/
|
||||
@Override
|
||||
default boolean onProjectileImpact(ProjectileEntity projectile) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.SpellPredicate;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.SpellType;
|
||||
import com.minelittlepony.unicopia.item.UItems;
|
||||
import com.minelittlepony.unicopia.network.EffectSync;
|
||||
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
|
||||
|
||||
import net.minecraft.entity.LivingEntity;
|
||||
import net.minecraft.entity.damage.DamageSource;
|
||||
|
@ -139,7 +140,9 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
|||
@Override
|
||||
public boolean onProjectileImpact(ProjectileEntity projectile) {
|
||||
return getSpellSlot().get(true)
|
||||
.filter(effect -> !effect.isDead() && effect.handleProjectileImpact(projectile))
|
||||
.filter(effect -> !effect.isDead()
|
||||
&& effect instanceof ProjectileImpactListener
|
||||
&& ((ProjectileImpactListener)effect).onProjectileImpact(projectile))
|
||||
.isPresent();
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,7 @@ public class SheepBehaviour extends EntityBehaviour<SheepEntity> {
|
|||
}
|
||||
} while (dropAmount-- > 0);
|
||||
}
|
||||
spell.setDirty(true);
|
||||
spell.setDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -89,6 +89,7 @@ public class EffectSync implements SpellContainer {
|
|||
private void updateReference(@Nullable Spell effect) {
|
||||
if (spell.isPresent() && spell.get() != effect) {
|
||||
spell.get().setDead();
|
||||
spell.get().onDestroyed(owner);
|
||||
}
|
||||
spell = Optional.ofNullable(effect);
|
||||
}
|
||||
|
|
|
@ -121,15 +121,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
|
|||
return effectDelegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpell(Spell effect) {
|
||||
Caster.super.setSpell(effect);
|
||||
|
||||
if (effect != null) {
|
||||
effect.onPlaced(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void setThrowDamage(float damage) {
|
||||
getDataTracker().set(DAMAGE, Math.max(0, damage));
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.minelittlepony.unicopia.projectile;
|
||||
|
||||
import net.minecraft.entity.projectile.ProjectileEntity;
|
||||
|
||||
public interface ProjectileImpactListener {
|
||||
boolean onProjectileImpact(ProjectileEntity projectile);
|
||||
}
|
Loading…
Reference in a new issue