mirror of
https://github.com/Sollace/Unicopia.git
synced 2025-02-01 03:26:44 +01:00
Store the level with the spellcast entity so it can still be used when the owner is offline
This commit is contained in:
parent
5d9ef41672
commit
cbd80270e3
7 changed files with 85 additions and 20 deletions
|
@ -25,8 +25,9 @@ public interface WeaklyOwned<E extends Entity> extends Owned<E> {
|
|||
*
|
||||
* @param sibling
|
||||
*/
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
default void setMaster(WeaklyOwned<? extends E> sibling) {
|
||||
default void setMaster(Owned<? extends E> sibling) {
|
||||
if (sibling instanceof WeaklyOwned) {
|
||||
getMasterReference().copyFrom(((WeaklyOwned<E>)sibling).getMasterReference());
|
||||
} else {
|
||||
|
|
|
@ -1,10 +1,46 @@
|
|||
package com.minelittlepony.unicopia.ability.magic;
|
||||
|
||||
import java.util.function.IntSupplier;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
||||
/**
|
||||
* Object with levelling capabilities.
|
||||
*/
|
||||
public interface Levelled {
|
||||
LevelStore EMPTY = fixed(0);
|
||||
|
||||
static LevelStore fixed(int level) {
|
||||
return of(() -> level);
|
||||
}
|
||||
|
||||
static LevelStore of(IntSupplier supplier) {
|
||||
return new LevelStore() {
|
||||
@Override
|
||||
public int get() {
|
||||
return supplier.getAsInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void set(int level) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getMax() {
|
||||
return get();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static LevelStore copyOf(LevelStore store) {
|
||||
return of(store.get(), store.getMax());
|
||||
}
|
||||
|
||||
static LevelStore fromNbt(NbtCompound compound) {
|
||||
return of(compound.getInt("value"), compound.getInt("max"));
|
||||
}
|
||||
|
||||
static LevelStore of(int level, int max) {
|
||||
return new LevelStore() {
|
||||
@Override
|
||||
public int get() {
|
||||
|
@ -17,9 +53,8 @@ public interface Levelled {
|
|||
|
||||
@Override
|
||||
public int getMax() {
|
||||
return get();
|
||||
return max;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -46,5 +81,12 @@ public interface Levelled {
|
|||
default void add(int levels) {
|
||||
set(get() + levels);
|
||||
}
|
||||
|
||||
default NbtCompound toNbt() {
|
||||
NbtCompound compound = new NbtCompound();
|
||||
compound.putInt("value", get());
|
||||
compound.putInt("max", getMax());
|
||||
return compound;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@ public class PlaceableSpell extends AbstractDelegatingSpell {
|
|||
delegate.onPlaced(source, copy, entity);
|
||||
}
|
||||
entity.getSpellSlot().put(copy);
|
||||
entity.setMaster(source);
|
||||
entity.setCaster(source);
|
||||
entity.world.spawnEntity(entity);
|
||||
Ether.get(entity.world).put(getType(), entity);
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package com.minelittlepony.unicopia.entity;
|
||||
|
||||
import com.minelittlepony.unicopia.Affinity;
|
||||
import com.minelittlepony.unicopia.WeaklyOwned;
|
||||
import com.minelittlepony.unicopia.*;
|
||||
import com.minelittlepony.unicopia.ability.magic.Caster;
|
||||
import com.minelittlepony.unicopia.ability.magic.Levelled;
|
||||
import com.minelittlepony.unicopia.ability.magic.SpellContainer;
|
||||
|
@ -27,14 +26,15 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<Livin
|
|||
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
||||
|
||||
private static final LevelStore LEVELS = Levelled.fixed(0);
|
||||
|
||||
private final EntityPhysics<CastSpellEntity> physics = new EntityPhysics<>(this, GRAVITY);
|
||||
|
||||
private final EffectSync effectDelegate = new EffectSync(this, EFFECT);
|
||||
|
||||
private final EntityReference<LivingEntity> owner = new EntityReference<>();
|
||||
|
||||
private LevelStore level = Levelled.EMPTY;
|
||||
private LevelStore corruption = Levelled.EMPTY;
|
||||
|
||||
public CastSpellEntity(EntityType<?> type, World world) {
|
||||
super(type, world);
|
||||
}
|
||||
|
@ -81,14 +81,20 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<Livin
|
|||
return this;
|
||||
}
|
||||
|
||||
public void setCaster(Caster<?> caster) {
|
||||
this.level = Levelled.copyOf(caster.getLevel());
|
||||
this.corruption = Levelled.copyOf(caster.getCorruption());
|
||||
setMaster(caster);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getLevel() {
|
||||
return Caster.of(getMaster()).map(Caster::getLevel).orElse(LEVELS);
|
||||
return level;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getCorruption() {
|
||||
return Caster.of(getMaster()).map(Caster::getCorruption).orElse(LEVELS);
|
||||
return corruption;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -120,6 +126,8 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<Livin
|
|||
@Override
|
||||
protected void writeCustomDataToNbt(NbtCompound tag) {
|
||||
tag.put("owner", owner.toNBT());
|
||||
tag.put("level", level.toNbt());
|
||||
tag.put("corruption", corruption.toNbt());
|
||||
getSpellSlot().get(true).ifPresent(effect -> {
|
||||
tag.put("effect", Spell.writeNbt(effect));
|
||||
});
|
||||
|
@ -133,6 +141,8 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<Livin
|
|||
if (tag.contains("effect")) {
|
||||
getSpellSlot().put(Spell.readNbt(tag.getCompound("effect")));
|
||||
}
|
||||
level = Levelled.fromNbt(tag.getCompound("level"));
|
||||
corruption = Levelled.fromNbt(tag.getCompound("corruption"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -44,8 +44,6 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned<Living
|
|||
public static final TrackedData<Float> GRAVITY = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<Integer> EATING = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.INTEGER);
|
||||
|
||||
private static final LevelStore LEVELS = Levelled.fixed(0);
|
||||
|
||||
public static void boostrap() {}
|
||||
|
||||
private final EntityPhysics<LivingEntity> physics;
|
||||
|
@ -205,12 +203,12 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned<Living
|
|||
|
||||
@Override
|
||||
public LevelStore getLevel() {
|
||||
return LEVELS;
|
||||
return Levelled.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getCorruption() {
|
||||
return LEVELS;
|
||||
return Levelled.EMPTY;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -16,11 +16,26 @@ import net.minecraft.server.world.ServerWorld;
|
|||
import net.minecraft.util.math.Vec3d;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
/**
|
||||
* An indirect reference to an entity by its unique id.
|
||||
* Used to store the 'owner' reference for certain objects that allows them to\
|
||||
* remember who they belong to even when the entity has been unloaded.
|
||||
*
|
||||
* @param <T> The type of the entity this reference points to.
|
||||
*/
|
||||
public class EntityReference<T extends Entity> implements NbtSerialisable {
|
||||
|
||||
/**
|
||||
* Server UUID of the entity used to look up the entity instance on the server.
|
||||
*/
|
||||
private Optional<UUID> uuid = Optional.empty();
|
||||
/**
|
||||
* Corresponding client id used to look up the entity instance on the client.
|
||||
*/
|
||||
private int clientId;
|
||||
|
||||
/**
|
||||
* The last-known position of the entity.
|
||||
*/
|
||||
private Optional<Vec3d> pos = Optional.empty();
|
||||
|
||||
public EntityReference() {}
|
||||
|
@ -88,8 +103,8 @@ public class EntityReference<T extends Entity> implements NbtSerialisable {
|
|||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Optional<T> getOrEmpty(World world) {
|
||||
if (uuid.isPresent() && world instanceof ServerWorld) {
|
||||
return uuid.map(((ServerWorld)world)::getEntity).map(e -> (T)e).filter(this::checkReference);
|
||||
if (uuid.isPresent() && world instanceof ServerWorld serverWorld) {
|
||||
return uuid.map(serverWorld::getEntity).map(e -> (T)e).filter(this::checkReference);
|
||||
}
|
||||
|
||||
if (clientId != 0) {
|
||||
|
|
|
@ -55,7 +55,6 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Li
|
|||
private static final TrackedData<Float> GRAVITY = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.FLOAT);
|
||||
private static final TrackedData<Boolean> HYDROPHOBIC = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.BOOLEAN);
|
||||
private static final TrackedData<NbtCompound> EFFECT = DataTracker.registerData(MagicProjectileEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND);
|
||||
private static final LevelStore LEVELS = Levelled.fixed(1);
|
||||
|
||||
public static final byte PROJECTILE_COLLISSION = 3;
|
||||
|
||||
|
@ -117,12 +116,12 @@ public class MagicProjectileEntity extends ThrownItemEntity implements Caster<Li
|
|||
|
||||
@Override
|
||||
public LevelStore getLevel() {
|
||||
return Caster.of(getMaster()).map(Caster::getLevel).orElse(LEVELS);
|
||||
return Caster.of(getMaster()).map(Caster::getLevel).orElse(Levelled.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LevelStore getCorruption() {
|
||||
return Caster.of(getMaster()).map(Caster::getCorruption).orElse(LEVELS);
|
||||
return Caster.of(getMaster()).map(Caster::getCorruption).orElse(Levelled.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
Loading…
Reference in a new issue