diff --git a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java index 0cae9891..bfb00b07 100644 --- a/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java +++ b/src/main/java/com/minelittlepony/unicopia/ability/magic/SpellContainer.java @@ -32,7 +32,9 @@ public interface SpellContainer { /** * Gets the active effect for this caster updating it if needed. */ - Optional get(@Nullable SpellPredicate type); + default Optional get(@Nullable SpellPredicate type) { + return stream(type).findFirst(); + } /** * Sets the active effect. @@ -73,10 +75,12 @@ public interface SpellContainer { /** * Gets all active effects for this caster updating it if needed. */ - Stream stream(); + default Stream stream() { + return stream(null); + } /** - * Gets all active effects for this caster that match the given type updating it if needed. + * Gets all active effects for this caster that match the given type. */ Stream stream(@Nullable SpellPredicate type); diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java index 51ad4fa5..810297d9 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Creature.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Creature.java @@ -31,8 +31,6 @@ import net.minecraft.entity.SpawnGroup; import net.minecraft.entity.ai.goal.*; import net.minecraft.entity.attribute.DefaultAttributeContainer; import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.entity.mob.*; import net.minecraft.entity.passive.*; import net.minecraft.entity.player.PlayerEntity; @@ -41,7 +39,6 @@ import net.minecraft.nbt.NbtElement; import net.minecraft.util.math.MathHelper; public class Creature extends Living implements WeaklyOwned.Mutable { - static final TrackedData EFFECT = net.minecraft.entity.data.DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); public static void boostrap() {} private final EntityPhysics physics; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Equine.java b/src/main/java/com/minelittlepony/unicopia/entity/Equine.java index 691bbfcf..a9cf3707 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Equine.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Equine.java @@ -19,8 +19,6 @@ public interface Equine extends NbtSerialisable, Tickable, Pro void setSpecies(Race race); - void initDataTracker(); - /** * Called at the beginning of an update cycle. */ diff --git a/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java index 78b2c2e4..ae51c08c 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/ItemImpl.java @@ -47,10 +47,6 @@ public class ItemImpl implements Equine { race = tracker.startTracking(TrackableDataType.of(Race.PACKET_CODEC), Race.HUMAN); } - @Override - public void initDataTracker() { - } - @Override public boolean onProjectileImpact(ProjectileEntity projectile) { return false; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/Living.java b/src/main/java/com/minelittlepony/unicopia/entity/Living.java index 58dc2e00..d6f14bdb 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/Living.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/Living.java @@ -76,8 +76,6 @@ import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.Vec3d; public abstract class Living implements Equine, Caster, Transmittable { - //private static final TrackedData> CARRIER_ID = DataTracker.registerData(LivingEntity.class, TrackedDataHandlerRegistry.OPTIONAL_UUID); - protected final T entity; private final EffectSync effectDelegate; @@ -113,7 +111,7 @@ public abstract class Living implements Equine, Caste this.entity = entity; this.trackers = Trackable.of(entity).getDataTrackers(); this.tracker = trackers.getPrimaryTracker(); - this.effectDelegate = new EffectSync(this, Creature.EFFECT); + this.effectDelegate = new EffectSync(this, tracker); this.sneakingHeuristic = addTicker(new Interactable(entity::isSneaking)); this.landedHeuristic = addTicker(new Interactable(entity::isOnGround)); this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping)); @@ -121,11 +119,6 @@ public abstract class Living implements Equine, Caste carrierId = tracker.startTracking(TrackableDataType.of(PacketCodec.UUID), Util.NIL_UUID); } - @Override - public void initDataTracker() { - entity.getDataTracker().startTracking(Creature.EFFECT, new NbtCompound()); - } - public Q addTicker(Q tickable) { tickers.add(Objects.requireNonNull(tickable, "tickable cannot be null")); return tickable; diff --git a/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java b/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java index 0643087f..ea3896c8 100644 --- a/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/entity/mob/CastSpellEntity.java @@ -19,19 +19,15 @@ import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityType; import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.data.DataTracker; -import net.minecraft.entity.data.TrackedData; -import net.minecraft.entity.data.TrackedDataHandlerRegistry; import net.minecraft.nbt.NbtCompound; import net.minecraft.text.Text; import net.minecraft.world.World; public class CastSpellEntity extends LightEmittingEntity implements Caster, WeaklyOwned.Mutable, MagicImmune { - private static final TrackedData EFFECT = DataTracker.registerData(CastSpellEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); private final EntityPhysics physics = new EntityPhysics<>(this, Trackable.of(this).getDataTrackers().getPrimaryTracker()); - private final EffectSync effectDelegate = new EffectSync(this, EFFECT); + private final EffectSync effectDelegate = new EffectSync(this, Trackable.of(this).getDataTrackers().getPrimaryTracker()); private final EntityReference owner = new EntityReference<>(); @@ -45,7 +41,6 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster type, World world, CallbackInfo info) { - if (this instanceof Equine.Container c) { - c.get().initDataTracker(); - } - } - @Inject(method = "isFireImmune", at = @At("HEAD"), cancellable = true) private void onIsFireImmune(CallbackInfoReturnable info) { if (isLavaAffine() || (this instanceof Equine.Container c) && c.get().getCompositeRace().includes(Race.KIRIN)) { diff --git a/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java b/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java index 36fa7a65..b2d8fb97 100644 --- a/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java +++ b/src/main/java/com/minelittlepony/unicopia/network/datasync/EffectSync.java @@ -1,7 +1,7 @@ package com.minelittlepony.unicopia.network.datasync; -import java.util.Optional; import java.util.UUID; +import java.util.function.BiFunction; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Stream; @@ -14,9 +14,11 @@ import com.minelittlepony.unicopia.ability.magic.SpellContainer; import com.minelittlepony.unicopia.ability.magic.SpellPredicate; import com.minelittlepony.unicopia.ability.magic.spell.Situation; import com.minelittlepony.unicopia.ability.magic.spell.Spell; +import com.minelittlepony.unicopia.network.track.DataTracker; +import com.minelittlepony.unicopia.network.track.TrackableDataType; import com.minelittlepony.unicopia.util.NbtSerialisable; +import com.minelittlepony.unicopia.util.serialization.PacketCodec; -import net.minecraft.entity.data.TrackedData; import net.minecraft.nbt.NbtCompound; /** @@ -32,19 +34,21 @@ public class EffectSync implements SpellContainer, NbtSerialisable { private final Caster owner; - private final TrackedData param; + private final DataTracker tracker; + private final DataTracker.Entry param; - @Nullable - private NbtCompound lastValue; - - public EffectSync(Caster owner, TrackedData param) { - spells = new NetworkedReferenceSet<>(Spell::getUuid, () -> new SpellNetworkedReference<>(owner)); + public EffectSync(Caster owner, DataTracker tracker) { this.owner = owner; - this.param = param; - } + this.tracker = tracker; + this.param = tracker.startTracking(TrackableDataType.of(PacketCodec.NBT), new NbtCompound()); + spells = new NetworkedReferenceSet<>(Spell::getUuid, () -> new SpellNetworkedReference<>(owner)); - public void initDataTracker() { - owner.asEntity().getDataTracker().startTracking(param, new NbtCompound()); + tracker.onBeforeSend(param, () -> { + if (spells.isDirty()) { + tracker.set(param, spells.toNbt()); + } + }); + tracker.onReceive(param, nbt -> spells.fromNbt(nbt)); } public boolean tick(Situation situation) { @@ -78,20 +82,9 @@ public class EffectSync implements SpellContainer, NbtSerialisable { return spells.containsReference(id) || spells.getReferences().anyMatch(s -> s.equalsOrContains(id)); } - @Override - public boolean contains(@Nullable SpellPredicate type) { - return read(type).findFirst().isPresent(); - } - - @Override - public Optional get(@Nullable SpellPredicate type) { - return read(type).findFirst(); - } - @Override public void put(@Nullable Spell effect) { spells.addReference(effect); - write(); if (owner instanceof UpdateCallback callback) { callback.onSpellSet(effect); } @@ -99,12 +92,7 @@ public class EffectSync implements SpellContainer, NbtSerialisable { @Override public void remove(UUID id) { - Spell spell = spells.getReference(id); - spell.setDead(); - spell.tickDying(owner); - if (spell.isDead()) { - spells.removeReference(id); - } + discard(spells.getReference(id)); } @Override @@ -113,13 +101,19 @@ public class EffectSync implements SpellContainer, NbtSerialisable { if (!test.test(spell)) { return initial; } + discard(spell); + return true; + }); + } + + private void discard(Spell spell) { + if (spell != null) { spell.setDead(); spell.tickDying(owner); if (spell.isDead()) { spells.removeReference(spell); } - return true; - }); + } } @Override @@ -135,55 +129,28 @@ public class EffectSync implements SpellContainer, NbtSerialisable { }); } - @Override - public Stream stream() { - return stream(null); - } - + @SuppressWarnings("unchecked") @Override public Stream stream(@Nullable SpellPredicate type) { - return read(type); - } - - @Override - public boolean clear() { - if (spells.clear()) { - write(); - if (owner instanceof UpdateCallback) { - ((UpdateCallback)owner).onSpellSet(null); - } - return true; - } - return false; - } - - @SuppressWarnings("unchecked") - private Stream read(@Nullable SpellPredicate type) { - if (owner.isClient()) { - spells.fromNbt(owner.asEntity().getDataTracker().get(param)); - } - write(); - if (type == null) { return (Stream)spells.getReferences(); } return (Stream)spells.getReferences().flatMap(s -> s.findMatches(type)); } - private boolean reduce(Alteration alteration) { - boolean initial = false; - for (Spell i : read(null).toList()) { - initial = alteration.apply(initial, i); + @Override + public boolean clear() { + if (spells.clear()) { + if (owner instanceof UpdateCallback c) { + c.onSpellSet(null); + } + return true; } - - write(); - return initial; + return false; } - private void write() { - if (spells.isDirty() && !owner.isClient()) { - owner.asEntity().getDataTracker().set(param, spells.toNbt()); - } + private boolean reduce(BiFunction alteration) { + return stream().toList().stream().reduce(false, alteration, (a, b) -> b); } @Override @@ -194,14 +161,10 @@ public class EffectSync implements SpellContainer, NbtSerialisable { @Override public void fromNBT(NbtCompound compound) { spells.fromNbt(compound.getCompound("spells")); - owner.asEntity().getDataTracker().set(param, spells.toNbt()); + tracker.set(param, spells.toNbt()); } public interface UpdateCallback { void onSpellSet(@Nullable Spell spell); } - - private interface Alteration { - boolean apply(boolean initial, Spell spell); - } } diff --git a/src/main/java/com/minelittlepony/unicopia/projectile/MagicBeamEntity.java b/src/main/java/com/minelittlepony/unicopia/projectile/MagicBeamEntity.java index 7d92a756..28d0da3e 100644 --- a/src/main/java/com/minelittlepony/unicopia/projectile/MagicBeamEntity.java +++ b/src/main/java/com/minelittlepony/unicopia/projectile/MagicBeamEntity.java @@ -32,10 +32,9 @@ import net.minecraft.util.math.Vec3d; import net.minecraft.world.World; public class MagicBeamEntity extends MagicProjectileEntity implements Caster, MagicImmune { - private static final TrackedData EFFECT = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.NBT_COMPOUND); private static final TrackedData HYDROPHOBIC = DataTracker.registerData(MagicBeamEntity.class, TrackedDataHandlerRegistry.BOOLEAN); - private final EffectSync effectDelegate = new EffectSync(this, EFFECT); + private final EffectSync effectDelegate = new EffectSync(this, Trackable.of(this).getDataTrackers().getPrimaryTracker()); private final EntityPhysics physics = new EntityPhysics<>(this, Trackable.of(this).getDataTrackers().getPrimaryTracker()); public MagicBeamEntity(EntityType type, World world) { @@ -55,7 +54,6 @@ public class MagicBeamEntity extends MagicProjectileEntity implements Caster