Slight refactor for levelling

This commit is contained in:
Sollace 2020-10-02 09:39:00 +02:00
parent 9342369b69
commit 86524c10aa
20 changed files with 121 additions and 100 deletions

View file

@ -1,7 +1,6 @@
package com.minelittlepony.unicopia.ability.magic;
import java.util.Optional;
import java.util.UUID;
import java.util.stream.Stream;
import javax.annotation.Nullable;
@ -16,11 +15,10 @@ import net.minecraft.entity.LivingEntity;
import net.minecraft.entity.damage.DamageSource;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Box;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
/**
* Interface for any magically capable entities that can cast and persist spells.
* Interface for any magically capable entities that can cast or persist spells.
*/
public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affine, Magical, ParticleSource {
@ -76,13 +74,6 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
return getOwner();
}
/**
* Gets the unique id associated with this caste.
*/
default UUID getUniqueId() {
return getEntity().getUuid();
}
/**
* gets the minecraft world
*/
@ -112,14 +103,6 @@ public interface Caster<E extends LivingEntity> extends Owned<E>, Levelled, Affi
return getEntity().getBlockPos();
}
/**
* Gets the center position where this caster is located.
*/
@Override
default Vec3d getOriginVector() {
return getEntity().getPos();
}
default boolean subtractEnergyCost(double amount) {
getOwner().damage(DamageSource.MAGIC, (int)amount/2);
return getOwner().getHealth() > 0;

View file

@ -4,26 +4,41 @@ package com.minelittlepony.unicopia.ability.magic;
* Object with levelling capabilities.
*/
public interface Levelled {
static LevelStore fixed(int level) {
return new LevelStore() {
@Override
public int get() {
return level;
}
/**
* Maximum level this spell can reach or -1 for unlimited.
* <br>
* If a gem goes past this level it is more likely to explode.
*/
default int getMaxLevel() {
return 0;
@Override
public void set(int level) {
}
@Override
public int getMax() {
return get();
}
};
}
default boolean canLevelUp() {
int max = getMaxLevel();
return max < 0 || getCurrentLevel() < max;
}
LevelStore getLevel();
int getCurrentLevel();
interface LevelStore {
int getMax();
void setCurrentLevel(int level);
int get();
default void addLevels(int levels) {
setCurrentLevel(getCurrentLevel() + levels);
void set(int level);
default boolean canLevelUp() {
int max = getMax();
return max < 0 || get() < max;
}
default void add(int levels) {
set(get() + levels);
}
}
}

View file

@ -18,7 +18,7 @@ public abstract class AbstractRangedAreaSpell extends AbstractSpell implements A
@Override
public float getExhaustion(Caster<?> caster) {
float max = getMaxLevelCutOff(caster);
float current = caster.getCurrentLevel();
float current = caster.getLevel().get();
if (current > max) {
float maxEc = getMaxExhaustion(caster);

View file

@ -44,7 +44,7 @@ public class AttractiveSpell extends ShieldSpell {
@Override
public void render(Caster<?> source) {
int range = 4 + (source.getCurrentLevel() * 2);
int range = 4 + (source.getLevel().get() * 2);
Vec3d pos = source.getOriginVector();
source.spawnParticles(new Sphere(false, range), range * 9, p -> {
@ -54,7 +54,7 @@ public class AttractiveSpell extends ShieldSpell {
@Override
public double getDrawDropOffRange(Caster<?> caster) {
return 10 + (caster.getCurrentLevel() * 2);
return 10 + (caster.getLevel().get() * 2);
}
@Override

View file

@ -44,7 +44,7 @@ public class AwkwardSpell extends AbstractSpell implements ThrowableSpell {
@Override
public void render(Caster<?> source) {
source.spawnParticles(new Sphere(false, (1 + source.getCurrentLevel()) * 8), 10, pos -> {
source.spawnParticles(new Sphere(false, (1 + source.getLevel().get()) * 8), 10, pos -> {
List<Identifier> names = new ArrayList<>(Registry.PARTICLE_TYPE.getIds());

View file

@ -55,7 +55,7 @@ public class DisguiseSpell extends AbstractSpell implements AttachableSpell, Sup
@Override
public boolean isVulnerable(Caster<?> otherSource, Spell other) {
return suppressionCounter <= otherSource.getCurrentLevel();
return suppressionCounter <= otherSource.getLevel().get();
}
@Override

View file

@ -62,7 +62,7 @@ public class FireSpell extends AbstractRangedAreaSpell {
@Override
public void render(Caster<?> source) {
source.spawnParticles(VISUAL_EFFECT_RANGE, source.getCurrentLevel() * 6, pos -> {
source.spawnParticles(VISUAL_EFFECT_RANGE, source.getLevel().get() * 6, pos -> {
source.addParticle(ParticleTypes.LARGE_SMOKE, pos, Vec3d.ZERO);
});
}

View file

@ -36,7 +36,7 @@ public class InfernoSpell extends FireSpell {
World w = source.getWorld();
if (!w.isClient) {
int radius = 4 + (source.getCurrentLevel() * 4);
int radius = 4 + (source.getLevel().get() * 4);
Shape shape = new Sphere(false, radius);
Vec3d origin = source.getOriginVector();

View file

@ -52,7 +52,7 @@ public class NecromancySpell extends AbstractRangedAreaSpell {
float additional = source.getWorld().getLocalDifficulty(source.getOrigin()).getLocalDifficulty();
int radius = source.getCurrentLevel() + 1;
int radius = source.getLevel().get() + 1;
Shape affectRegion = new Sphere(false, radius * 4);
@ -98,7 +98,7 @@ public class NecromancySpell extends AbstractRangedAreaSpell {
@Override
public void render(Caster<?> source) {
Shape affectRegion = new Sphere(false, (1 + source.getCurrentLevel()) * 4);
Shape affectRegion = new Sphere(false, (1 + source.getLevel().get()) * 4);
source.spawnParticles(affectRegion, 5, pos -> {
if (!source.getWorld().isAir(new BlockPos(pos).down())) {

View file

@ -28,7 +28,7 @@ public class RevealingSpell extends AbstractSpell {
@Override
public void onPlaced(Caster<?> source) {
source.setCurrentLevel(1);
source.getLevel().set(1);
}
@Override

View file

@ -61,7 +61,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
int costMultiplier = applyEntities(source);
if (costMultiplier > 0) {
if (source.getOwner().age % 20 == 0) {
double cost = 4 + (source.getCurrentLevel() * 2);
double cost = 4 + (source.getLevel().get() * 2);
cost *= costMultiplier / 5F;
@ -76,7 +76,7 @@ public class ShieldSpell extends AbstractRangedAreaSpell implements AttachableSp
public double getDrawDropOffRange(Caster<?> source) {
float multiplier = (source.getOwner().isSneaking() ? 1 : 2);
return (4 + (source.getCurrentLevel() * 2)) / multiplier;
return (4 + (source.getLevel().get() * 2)) / multiplier;
}
@Override

View file

@ -35,7 +35,7 @@ public class SiphoningSpell extends AbstractRangedAreaSpell {
@Override
public boolean update(Caster<?> source) {
int radius = 4 + source.getCurrentLevel();
int radius = 4 + source.getLevel().get();
LivingEntity owner = source.getOwner();
@ -92,7 +92,7 @@ public class SiphoningSpell extends AbstractRangedAreaSpell {
e.damage(damage, e.getHealth() / 4);
}
} else {
e.heal((float)Math.min(0.5F * (1 + source.getCurrentLevel()), maxHealthGain * 0.6));
e.heal((float)Math.min(0.5F * (1 + source.getLevel().get()), maxHealthGain * 0.6));
}
});
}
@ -110,7 +110,7 @@ public class SiphoningSpell extends AbstractRangedAreaSpell {
@Override
public void render(Caster<?> source) {
int radius = 4 + source.getCurrentLevel();
int radius = 4 + source.getLevel().get();
Vec3d origin = source.getOriginVector();
int direction = source.getAffinity() == Affinity.GOOD ? 1 : -1;

View file

@ -5,6 +5,7 @@ import com.minelittlepony.unicopia.Race;
import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.ability.magic.AttachableSpell;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Levelled;
import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.spell.SpellRegistry;
import com.minelittlepony.unicopia.network.EffectSync;
@ -19,6 +20,8 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private static final LevelStore LEVELS = Levelled.fixed(0);
public static void boostrap() {}
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
@ -80,12 +83,8 @@ public class Creature implements Equine<LivingEntity>, Caster<LivingEntity> {
}
@Override
public int getCurrentLevel() {
return 0;
}
@Override
public void setCurrentLevel(int level) {
public LevelStore getLevel() {
return LEVELS;
}
@Override

View file

@ -29,7 +29,7 @@ public class GhastBehaviour extends MobBehaviour<GhastEntity> {
Vec3d rot = player.getEntity().getRotationVec(1);
FireballEntity proj = new FireballEntity(entity.world, entity, rot.getX(), rot.getY(), rot.getZ());
proj.explosionPower = entity.getFireballStrength() * (player.getCurrentLevel() + 1);
proj.explosionPower = entity.getFireballStrength() * (player.getLevel().get() + 1);
proj.setOwner(player.getOwner());
proj.updatePosition(
entity.getX() + rot.x * 4,

View file

@ -48,15 +48,15 @@ public class ManaContainer implements MagicReserves {
public void set(float value) {
float diff = value - get();
if (diff < 0) {
if (pony.canLevelUp()) {
xp.add(-diff / (100 * (1 + pony.getCurrentLevel())));
if (pony.getLevel().canLevelUp()) {
xp.add(-diff / (100 * (1 + pony.getLevel().get())));
if (xp.getPercentFill() >= 1) {
pony.addLevels(1);
pony.getLevel().add(1);
xp.set(0);
}
}
value = get() + diff / (1 + pony.getCurrentLevel());
value = get() + diff / (1 + pony.getLevel().get());
}
super.set(value);

View file

@ -0,0 +1,47 @@
package com.minelittlepony.unicopia.entity.player;
import com.minelittlepony.unicopia.ability.magic.Levelled;
import net.minecraft.entity.data.DataTracker;
import net.minecraft.entity.data.TrackedData;
import net.minecraft.entity.data.TrackedDataHandlerRegistry;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.util.math.MathHelper;
class PlayerLevelStore implements Levelled.LevelStore {
private static final TrackedData<Integer> LEVEL = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
private final Pony pony;
PlayerLevelStore(Pony pony) {
this.pony = pony;
pony.getEntity().getDataTracker().startTracking(LEVEL, 0);
}
@Override
public void add(int levels) {
if (levels > 0) {
pony.getMagicalReserves().getMana().set(pony.getMagicalReserves().getEnergy().getMax());
pony.getWorld().playSound(null, pony.getOrigin(), SoundEvents.ENTITY_PLAYER_LEVELUP, SoundCategory.PLAYERS, 1, 2);
}
Levelled.LevelStore.super.add(levels);
}
@Override
public int getMax() {
return 3;
}
@Override
public int get() {
return pony.getEntity().getDataTracker().get(LEVEL);
}
@Override
public void set(int level) {
pony.getEntity().getDataTracker().set(LEVEL, MathHelper.clamp(level, 0, getMax()));
}
}

View file

@ -106,7 +106,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
entity.fallDistance = 0;
int level = pony.getCurrentLevel() + 1;
int level = pony.getLevel().get() + 1;
if (ticksInAir > (level * 100)) {
Bar mana = pony.getMagicalReserves().getMana();
@ -158,7 +158,7 @@ public class PlayerPhysics extends EntityPhysics<Pony> implements Tickable, Moti
protected void moveFlying(Entity player, MutableVector velocity) {
float forward = 0.000015F * (1 + (pony.getCurrentLevel() / 10F)) * (float)Math.sqrt(getHorizontalMotion(player));
float forward = 0.000015F * (1 + (pony.getLevel().get() / 10F)) * (float)Math.sqrt(getHorizontalMotion(player));
boolean sneak = !player.isSneaking();
// vertical drop due to gravity

View file

@ -45,13 +45,10 @@ import net.minecraft.nbt.CompoundTag;
import net.minecraft.network.packet.s2c.play.EntityPassengersSetS2CPacket;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.server.world.ServerWorld;
import net.minecraft.sound.SoundCategory;
import net.minecraft.sound.SoundEvents;
import net.minecraft.text.Text;
import net.minecraft.text.TranslatableText;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Direction;
import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmittable, Copieable<Pony> {
@ -63,8 +60,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
static final TrackedData<Float> MANA = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
static final TrackedData<Float> XP = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.FLOAT);
static final TrackedData<Integer> LEVEL = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.INTEGER);
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private static final TrackedData<CompoundTag> HELD_EFFECT = DataTracker.registerData(PlayerEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
@ -73,6 +68,7 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
private final PlayerAttributes attributes = new PlayerAttributes();
private final PlayerCamera camera = new PlayerCamera(this);
private final MagicReserves mana;
private final PlayerLevelStore levels;
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
@ -94,11 +90,11 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
public Pony(PlayerEntity player) {
this.entity = player;
this.mana = new ManaContainer(this);
this.levels = new PlayerLevelStore(this);
player.getDataTracker().startTracking(RACE, Race.HUMAN.ordinal());
player.getDataTracker().startTracking(EFFECT, new CompoundTag());
player.getDataTracker().startTracking(HELD_EFFECT, new CompoundTag());
player.getDataTracker().startTracking(LEVEL, 0);
}
public static void registerAttributes(DefaultAttributeContainer.Builder builder) {
@ -138,6 +134,11 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
return mana;
}
@Override
public LevelStore getLevel() {
return levels;
}
@Override
public boolean isInvisible() {
return invisible && hasSpell();
@ -300,20 +301,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
prevLanded = entity.isOnGround();
}
@Override
public void addLevels(int levels) {
if (levels > 0) {
mana.getMana().set(mana.getEnergy().getMax());
entity.world.playSound(null, getOrigin(), SoundEvents.ENTITY_PLAYER_LEVELUP, SoundCategory.PLAYERS, 1, 2);
}
Caster.super.addLevels(levels);
}
@Override
public int getMaxLevel() {
return 3;
}
public Optional<Float> onImpact(float distance, float damageMultiplier) {
float g = gravity.getGravityModifier();
@ -445,16 +432,6 @@ public class Pony implements Caster<PlayerEntity>, Equine<PlayerEntity>, Transmi
return entity;
}
@Override
public int getCurrentLevel() {
return entity.getDataTracker().get(LEVEL);
}
@Override
public void setCurrentLevel(int level) {
entity.getDataTracker().set(LEVEL, MathHelper.clamp(level, 0, getMaxLevel()));
}
public boolean isClientPlayer() {
return InteractionManager.instance().isClientPlayer(getOwner());
}

View file

@ -16,12 +16,14 @@ public interface ParticleSource extends ParticleSpawner {
*/
World getWorld();
Entity getEntity();
/**
* Gets the center position where this caster is located.
*/
Vec3d getOriginVector();
Entity getEntity();
default Vec3d getOriginVector() {
return getEntity().getPos();
}
default void spawnParticles(ParticleEffect particleId, int count) {
ParticleUtils.spawnParticles(particleId, getEntity(), count);

View file

@ -4,6 +4,7 @@ import java.util.UUID;
import com.minelittlepony.unicopia.Affinity;
import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.ability.magic.Levelled;
import com.minelittlepony.unicopia.ability.magic.Magical;
import com.minelittlepony.unicopia.ability.magic.Spell;
import com.minelittlepony.unicopia.ability.magic.ThrowableSpell;
@ -46,6 +47,7 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
private static final TrackedData<Float> DAMAGE = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
private static final TrackedData<CompoundTag> EFFECT = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.TAG_COMPOUND);
private static final LevelStore LEVELS = Levelled.fixed(1);
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
@ -101,12 +103,8 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Magical,
}
@Override
public int getCurrentLevel() {
return 1;
}
@Override
public void setCurrentLevel(int level) {
public LevelStore getLevel() {
return LEVELS;
}
@Override