Cleanup and sync placed spell owners

This commit is contained in:
Sollace 2024-05-22 15:25:35 +01:00
parent e23cbcdd1c
commit 2910b8d29c
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
13 changed files with 119 additions and 91 deletions

View file

@ -10,8 +10,8 @@ import com.google.common.base.Strings;
import com.minelittlepony.unicopia.ability.Abilities; import com.minelittlepony.unicopia.ability.Abilities;
import com.minelittlepony.unicopia.ability.Ability; import com.minelittlepony.unicopia.ability.Ability;
import com.minelittlepony.unicopia.ability.magic.Affine; import com.minelittlepony.unicopia.ability.magic.Affine;
import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.util.RegistryUtils; import com.minelittlepony.unicopia.util.RegistryUtils;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import com.mojang.brigadier.context.CommandContext; import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException; import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType; import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
@ -45,7 +45,7 @@ public record Race (
public static final String DEFAULT_ID = "unicopia:unset"; public static final String DEFAULT_ID = "unicopia:unset";
public static final Registry<Race> REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race"), DEFAULT_ID); public static final Registry<Race> REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race"), DEFAULT_ID);
public static final Registry<Race> COMMAND_REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race/grantable"), DEFAULT_ID); public static final Registry<Race> COMMAND_REGISTRY = RegistryUtils.createDefaulted(Unicopia.id("race/grantable"), DEFAULT_ID);
public static final PacketCodec<Race> PACKET_CODEC = PacketCodec.ofRegistry(REGISTRY); public static final TrackableDataType<Race> TRACKABLE_TYPE = TrackableDataType.RACE;
public static final RegistryKey<? extends Registry<Race>> REGISTRY_KEY = REGISTRY.getKey(); public static final RegistryKey<? extends Registry<Race>> REGISTRY_KEY = REGISTRY.getKey();
private static final DynamicCommandExceptionType UNKNOWN_RACE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("commands.race.fail", id)); private static final DynamicCommandExceptionType UNKNOWN_RACE_EXCEPTION = new DynamicCommandExceptionType(id -> Text.translatable("commands.race.fail", id));
private static final Function<Race, Composite> COMPOSITES = Util.memoize(race -> new Composite(race, null, null)); private static final Function<Race, Composite> COMPOSITES = Util.memoize(race -> new Composite(race, null, null));

View file

@ -23,7 +23,6 @@ import com.minelittlepony.unicopia.entity.ai.WantItTakeItGoal;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import com.minelittlepony.unicopia.network.track.DataTracker; import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.TrackableDataType; import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import net.minecraft.entity.EntityType; import net.minecraft.entity.EntityType;
import net.minecraft.entity.LivingEntity; import net.minecraft.entity.LivingEntity;
@ -62,7 +61,6 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
.isEmpty(); .isEmpty();
}); });
protected final DataTracker.Entry<NbtCompound> master;
protected final DataTracker.Entry<Integer> eating; protected final DataTracker.Entry<Integer> eating;
protected final DataTracker.Entry<Boolean> discorded; protected final DataTracker.Entry<Boolean> discorded;
protected final DataTracker.Entry<Boolean> smitten; protected final DataTracker.Entry<Boolean> smitten;
@ -73,16 +71,15 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
addTicker(physics); addTicker(physics);
addTicker(this::updateConsumption); addTicker(this::updateConsumption);
master = tracker.startTracking(TrackableDataType.of(PacketCodec.NBT), owner.toNBT()); tracker.startTracking(owner);
eating = tracker.startTracking(TrackableDataType.of(PacketCodec.INT), 0); eating = tracker.startTracking(TrackableDataType.INT, 0);
discorded = tracker.startTracking(TrackableDataType.of(PacketCodec.BOOLEAN), false); discorded = tracker.startTracking(TrackableDataType.BOOLEAN, false);
smitten = tracker.startTracking(TrackableDataType.of(PacketCodec.BOOLEAN), false); smitten = tracker.startTracking(TrackableDataType.BOOLEAN, false);
} }
@Override @Override
public void setMaster(LivingEntity owner) { public void setMaster(LivingEntity owner) {
this.owner.set(owner); this.owner.set(owner);
tracker.set(master, this.owner.toNBT());
if (owner != null) { if (owner != null) {
targets.ifPresent(this::initMinionAi); targets.ifPresent(this::initMinionAi);
} }
@ -93,20 +90,20 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
} }
public boolean isDiscorded() { public boolean isDiscorded() {
return tracker.get(this.discorded); return discorded.get();
} }
public boolean isSmitten() { public boolean isSmitten() {
return tracker.get(this.smitten); return smitten.get();
} }
public void setSmitten(boolean smitten) { public void setSmitten(boolean smitten) {
smittenTicks = smitten ? 20 : 0; smittenTicks = smitten ? 20 : 0;
tracker.set(this.smitten, smitten); this.smitten.set(smitten);
} }
public void setDiscorded(boolean discorded) { public void setDiscorded(boolean discorded) {
tracker.set(this.discorded, discorded); this.discorded.set(discorded);
discordedChanged = true; discordedChanged = true;
} }
@ -118,9 +115,6 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
@Override @Override
public EntityReference<LivingEntity> getMasterReference() { public EntityReference<LivingEntity> getMasterReference() {
if (master != null) {
owner.fromNBT(tracker.get(master));
}
return owner; return owner;
} }
@ -232,10 +226,10 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
private void updateConsumption() { private void updateConsumption() {
if (isClient()) { if (isClient()) {
eatTimer = tracker.get(eating); eatTimer = eating.get();
} else if (eatMuffinGoal != null) { } else if (eatMuffinGoal != null) {
eatTimer = eatMuffinGoal.getTimer(); eatTimer = eatMuffinGoal.getTimer();
tracker.set(eating, eatTimer); eating.set(eatTimer);
} }
} }
@ -324,9 +318,6 @@ public class Creature extends Living<LivingEntity> implements WeaklyOwned.Mutabl
} }
if (compound.contains("master", NbtElement.COMPOUND_TYPE)) { if (compound.contains("master", NbtElement.COMPOUND_TYPE)) {
owner.fromNBT(compound.getCompound("master")); owner.fromNBT(compound.getCompound("master"));
if (master != null) {
tracker.set(master, owner.toNBT());
}
if (owner.isSet()) { if (owner.isSet()) {
targets.ifPresent(this::initMinionAi); targets.ifPresent(this::initMinionAi);
} }

View file

@ -6,7 +6,6 @@ import com.minelittlepony.unicopia.network.track.Trackable;
import com.minelittlepony.unicopia.network.track.TrackableDataType; import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.util.Copyable; import com.minelittlepony.unicopia.util.Copyable;
import com.minelittlepony.unicopia.util.Tickable; import com.minelittlepony.unicopia.util.Tickable;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.FenceGateBlock; import net.minecraft.block.FenceGateBlock;
@ -31,7 +30,7 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
public EntityPhysics(T entity) { public EntityPhysics(T entity) {
this.entity = entity; this.entity = entity;
this.tracker = Trackable.of(entity).getDataTrackers().getPrimaryTracker(); this.tracker = Trackable.of(entity).getDataTrackers().getPrimaryTracker();
gravity = tracker.startTracking(TrackableDataType.of(PacketCodec.FLOAT), 1F); gravity = tracker.startTracking(TrackableDataType.FLOAT, 1F);
} }
@Override @Override
@ -96,12 +95,12 @@ public class EntityPhysics<T extends Entity> implements Physics, Copyable<Entity
@Override @Override
public void setBaseGravityModifier(float constant) { public void setBaseGravityModifier(float constant) {
tracker.set(gravity, constant); gravity.set(constant);
} }
@Override @Override
public float getBaseGravityModifier() { public float getBaseGravityModifier() {
return tracker.get(gravity); return gravity.get();
} }
@Override @Override

View file

@ -10,6 +10,7 @@ import org.jetbrains.annotations.Nullable;
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.network.track.TrackableObject;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.player.PlayerEntity; import net.minecraft.entity.player.PlayerEntity;
@ -29,7 +30,7 @@ import net.minecraft.world.World;
* *
* @param <T> The type of the entity this reference points to. * @param <T> The type of the entity this reference points to.
*/ */
public class EntityReference<T extends Entity> implements NbtSerialisable { public class EntityReference<T extends Entity> implements NbtSerialisable, TrackableObject {
private static final Serializer<?> SERIALIZER = Serializer.of(EntityReference::new); private static final Serializer<?> SERIALIZER = Serializer.of(EntityReference::new);
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@ -42,6 +43,8 @@ public class EntityReference<T extends Entity> implements NbtSerialisable {
private WeakReference<T> directReference = new WeakReference<>(null); private WeakReference<T> directReference = new WeakReference<>(null);
private boolean dirty = true;
public EntityReference() {} public EntityReference() {}
public EntityReference(T entity) { public EntityReference(T entity) {
@ -61,13 +64,14 @@ public class EntityReference<T extends Entity> implements NbtSerialisable {
public boolean set(@Nullable T entity) { public boolean set(@Nullable T entity) {
this.directReference = new WeakReference<>(entity); this.directReference = new WeakReference<>(entity);
this.reference = entity == null ? null : new EntityValues<>(entity); this.reference = entity == null ? null : new EntityValues<>(entity);
this.dirty = true;
return entity != null; return entity != null;
} }
public Optional<EntityValues<T>> getTarget() { public Optional<EntityValues<T>> getTarget() {
T value = directReference.get(); T value = directReference.get();
if (value != null) { if (value != null) {
set(value); this.reference = new EntityValues<>(value);
} }
return Optional.ofNullable(reference); return Optional.ofNullable(reference);
} }
@ -113,11 +117,41 @@ public class EntityReference<T extends Entity> implements NbtSerialisable {
@Override @Override
public void fromNBT(NbtCompound tag) { public void fromNBT(NbtCompound tag) {
this.reference = tag.contains("uuid") ? new EntityValues<>(tag) : null; this.reference = tag.contains("uuid") ? new EntityValues<>(tag) : null;
this.dirty = true;
} }
@Override @Override
public int hashCode() { public int hashCode() {
return getTarget().map(EntityValues::uuid).orElse(Util.NIL_UUID).hashCode(); return getUuid().hashCode();
}
@Override
public UUID getUuid() {
return getTarget().map(EntityValues::uuid).orElse(Util.NIL_UUID);
}
@Override
public Status getStatus() {
if (dirty) {
dirty = false;
return Status.UPDATED;
}
return Status.DEFAULT;
}
@Override
public NbtCompound toTrackedNbt() {
return toNBT();
}
@Override
public void readTrackedNbt(NbtCompound compound) {
fromNBT(compound);
}
@Override
public void discard(boolean immediate) {
set(null);
} }
public record EntityValues<T extends Entity>( public record EntityValues<T extends Entity>(

View file

@ -8,7 +8,6 @@ import com.minelittlepony.unicopia.item.enchantment.WantItNeedItEnchantment;
import com.minelittlepony.unicopia.network.track.DataTracker; import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.DataTrackerManager; import com.minelittlepony.unicopia.network.track.DataTrackerManager;
import com.minelittlepony.unicopia.network.track.Trackable; import com.minelittlepony.unicopia.network.track.Trackable;
import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.particle.FollowingParticleEffect; import com.minelittlepony.unicopia.particle.FollowingParticleEffect;
import com.minelittlepony.unicopia.particle.ParticleUtils; import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.particle.UParticles; import com.minelittlepony.unicopia.particle.UParticles;
@ -44,7 +43,7 @@ public class ItemImpl implements Equine<ItemEntity> {
this.tracker = trackers.getPrimaryTracker(); this.tracker = trackers.getPrimaryTracker();
this.physics = new ItemPhysics(owner); this.physics = new ItemPhysics(owner);
race = tracker.startTracking(TrackableDataType.of(Race.PACKET_CODEC), Race.HUMAN); race = tracker.startTracking(Race.TRACKABLE_TYPE, Race.HUMAN);
} }
@Override @Override
@ -141,12 +140,12 @@ public class ItemImpl implements Equine<ItemEntity> {
@Override @Override
public Race getSpecies() { public Race getSpecies() {
return tracker.get(race); return race.get();
} }
@Override @Override
public void setSpecies(Race race) { public void setSpecies(Race race) {
tracker.set(this.race, race); this.race.set(race);
} }
@Override @Override

View file

@ -40,7 +40,6 @@ import com.minelittlepony.unicopia.particle.ParticleUtils;
import com.minelittlepony.unicopia.projectile.ProjectileImpactListener; import com.minelittlepony.unicopia.projectile.ProjectileImpactListener;
import com.minelittlepony.unicopia.server.world.DragonBreathStore; import com.minelittlepony.unicopia.server.world.DragonBreathStore;
import com.minelittlepony.unicopia.util.*; import com.minelittlepony.unicopia.util.*;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import it.unimi.dsi.fastutil.floats.Float2ObjectFunction; import it.unimi.dsi.fastutil.floats.Float2ObjectFunction;
import net.fabricmc.fabric.api.util.TriState; import net.fabricmc.fabric.api.util.TriState;
@ -116,7 +115,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
this.landedHeuristic = addTicker(new Interactable(entity::isOnGround)); this.landedHeuristic = addTicker(new Interactable(entity::isOnGround));
this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping)); this.jumpingHeuristic = addTicker(new Interactable(((LivingEntityDuck)entity)::isJumping));
carrierId = tracker.startTracking(TrackableDataType.of(PacketCodec.UUID), Util.NIL_UUID); carrierId = tracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID);
} }
public <Q extends Tickable> Q addTicker(Q tickable) { public <Q extends Tickable> Q addTicker(Q tickable) {
@ -171,12 +170,12 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
} }
public Optional<UUID> getCarrierId() { public Optional<UUID> getCarrierId() {
UUID carrierId = tracker.get(this.carrierId); UUID carrierId = this.carrierId.get();
return carrierId == Util.NIL_UUID ? Optional.empty() : Optional.of(carrierId); return carrierId == Util.NIL_UUID ? Optional.empty() : Optional.of(carrierId);
} }
public void setCarrier(UUID carrier) { public void setCarrier(UUID carrier) {
tracker.set(this.carrierId, carrier == null ? Util.NIL_UUID : carrier); carrierId.set(carrier == null ? Util.NIL_UUID : carrier);
} }
public void setCarrier(Entity carrier) { public void setCarrier(Entity carrier) {

View file

@ -12,6 +12,8 @@ import com.minelittlepony.unicopia.entity.EntityPhysics;
import com.minelittlepony.unicopia.entity.EntityReference; import com.minelittlepony.unicopia.entity.EntityReference;
import com.minelittlepony.unicopia.entity.MagicImmune; import com.minelittlepony.unicopia.entity.MagicImmune;
import com.minelittlepony.unicopia.entity.Physics; import com.minelittlepony.unicopia.entity.Physics;
import com.minelittlepony.unicopia.network.track.Trackable;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityDimensions; import net.minecraft.entity.EntityDimensions;
import net.minecraft.entity.EntityPose; import net.minecraft.entity.EntityPose;
@ -50,6 +52,7 @@ public class CastSpellEntity extends LightEmittingEntity implements Caster<CastS
public CastSpellEntity(EntityType<?> type, World world) { public CastSpellEntity(EntityType<?> type, World world) {
super(type, world); super(type, world);
ignoreCameraFrustum = true; ignoreCameraFrustum = true;
Trackable.of(this).getDataTrackers().getPrimaryTracker().startTracking(owner);
} }
@Override @Override

View file

@ -12,8 +12,6 @@ import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.TrackableDataType; import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.minelittlepony.unicopia.util.Tickable; import com.minelittlepony.unicopia.util.Tickable;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.block.Blocks; import net.minecraft.block.Blocks;
import net.minecraft.block.SideShapeType; import net.minecraft.block.SideShapeType;
@ -36,14 +34,12 @@ public class Acrobatics implements Tickable, NbtSerialisable {
private final Pony pony; private final Pony pony;
private final PlayerEntity entity; private final PlayerEntity entity;
private final DataTracker tracker;
private final DataTracker.Entry<Optional<BlockPos>> hangingPos; private final DataTracker.Entry<Optional<BlockPos>> hangingPos;
public Acrobatics(Pony pony, DataTracker tracker) { public Acrobatics(Pony pony, DataTracker tracker) {
this.pony = pony; this.pony = pony;
this.tracker = tracker;
this.entity = pony.asEntity(); this.entity = pony.asEntity();
this.hangingPos = tracker.startTracking(TrackableDataType.of(PacketCodec.OPTIONAL_POS), Optional.empty()); this.hangingPos = tracker.startTracking(TrackableDataType.OPTIONAL_POS, Optional.empty());
pony.addTicker(this::checkDislodge); pony.addTicker(this::checkDislodge);
} }
@ -146,7 +142,7 @@ public class Acrobatics implements Tickable, NbtSerialisable {
} }
public Optional<BlockPos> getHangingPosition() { public Optional<BlockPos> getHangingPosition() {
return tracker.get(hangingPos); return hangingPos.get();
} }
public boolean isHanging() { public boolean isHanging() {
@ -154,13 +150,13 @@ public class Acrobatics implements Tickable, NbtSerialisable {
} }
public void stopHanging() { public void stopHanging() {
tracker.set(hangingPos, Optional.empty()); hangingPos.set(Optional.empty());
entity.calculateDimensions(); entity.calculateDimensions();
ticksHanging = 0; ticksHanging = 0;
} }
public void startHanging(BlockPos pos) { public void startHanging(BlockPos pos) {
tracker.set(hangingPos, Optional.of(pos)); hangingPos.set(Optional.of(pos));
entity.teleport(pos.getX() + 0.5, pos.getY() - 1, pos.getZ() + 0.5); entity.teleport(pos.getX() + 0.5, pos.getY() - 1, pos.getZ() + 0.5);
entity.setVelocity(Vec3d.ZERO); entity.setVelocity(Vec3d.ZERO);
entity.setSneaking(false); entity.setSneaking(false);
@ -201,6 +197,6 @@ public class Acrobatics implements Tickable, NbtSerialisable {
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound) {
ticksHanging = compound.getInt("ticksHanging"); ticksHanging = compound.getInt("ticksHanging");
tracker.set(hangingPos, NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound)); hangingPos.set(NbtSerialisable.BLOCK_POS.readOptional("hangingPosition", compound));
} }
} }

View file

@ -8,8 +8,6 @@ import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.util.Copyable; import com.minelittlepony.unicopia.util.Copyable;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.minelittlepony.unicopia.util.Tickable; import com.minelittlepony.unicopia.util.Tickable;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -153,7 +151,6 @@ class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyabl
} }
class BarInst implements Bar, NbtSerialisable { class BarInst implements Bar, NbtSerialisable {
private final DataTracker tracker;
private final DataTracker.Entry<Float> marker; private final DataTracker.Entry<Float> marker;
private final float max; private final float max;
@ -162,17 +159,16 @@ class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyabl
private float prevValue; private float prevValue;
BarInst(DataTracker tracker, float max, float initial) { BarInst(DataTracker tracker, float max, float initial) {
this.tracker = tracker;
this.max = max; this.max = max;
this.trailingValue = initial; this.trailingValue = initial;
this.prevTrailingValue = initial; this.prevTrailingValue = initial;
this.prevValue = initial; this.prevValue = initial;
this.marker = tracker.startTracking(TrackableDataType.of(PacketCodec.FLOAT), max * trailingValue); this.marker = tracker.startTracking(TrackableDataType.FLOAT, max * trailingValue);
} }
@Override @Override
public float get() { public float get() {
return applyLimits(tracker.get(marker)); return applyLimits(marker.get());
} }
@Override @Override
@ -191,7 +187,7 @@ class ManaContainer implements MagicReserves, Tickable, NbtSerialisable, Copyabl
} }
private void load(float value) { private void load(float value) {
tracker.set(marker, value); marker.set(value);
} }
protected float getInitial(float initial) { protected float getInitial(float initial) {

View file

@ -3,8 +3,6 @@ package com.minelittlepony.unicopia.entity.player;
import com.minelittlepony.unicopia.ability.magic.Levelled; import com.minelittlepony.unicopia.ability.magic.Levelled;
import com.minelittlepony.unicopia.network.track.DataTracker; import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.TrackableDataType; import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import net.minecraft.sound.*; import net.minecraft.sound.*;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@ -12,7 +10,6 @@ class PlayerLevelStore implements Levelled.LevelStore {
private final Pony pony; private final Pony pony;
private final DataTracker tracker;
private final DataTracker.Entry<Integer> dataEntry; private final DataTracker.Entry<Integer> dataEntry;
private final boolean upgradeMana; private final boolean upgradeMana;
@ -21,8 +18,7 @@ class PlayerLevelStore implements Levelled.LevelStore {
PlayerLevelStore(Pony pony, DataTracker tracker, boolean upgradeMana, SoundEvent levelUpSound) { PlayerLevelStore(Pony pony, DataTracker tracker, boolean upgradeMana, SoundEvent levelUpSound) {
this.pony = pony; this.pony = pony;
this.tracker = tracker; this.dataEntry = tracker.startTracking(TrackableDataType.INT, 0);
this.dataEntry = tracker.startTracking(TrackableDataType.of(PacketCodec.INT), 0);
this.upgradeMana = upgradeMana; this.upgradeMana = upgradeMana;
this.levelUpSound = levelUpSound; this.levelUpSound = levelUpSound;
} }
@ -45,11 +41,11 @@ class PlayerLevelStore implements Levelled.LevelStore {
@Override @Override
public int get() { public int get() {
return tracker.get(dataEntry); return dataEntry.get();
} }
@Override @Override
public void set(int level) { public void set(int level) {
tracker.set(dataEntry, MathHelper.clamp(level, 0, getMax())); dataEntry.set(MathHelper.clamp(level, 0, getMax()));
} }
} }

View file

@ -35,7 +35,6 @@ import com.minelittlepony.unicopia.item.enchantment.UEnchantments;
import com.minelittlepony.unicopia.util.*; import com.minelittlepony.unicopia.util.*;
import com.minelittlepony.unicopia.network.*; import com.minelittlepony.unicopia.network.*;
import com.minelittlepony.unicopia.network.track.DataTracker; import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.server.world.UGameRules; import com.minelittlepony.unicopia.server.world.UGameRules;
import com.minelittlepony.common.util.animation.LinearInterpolator; import com.minelittlepony.common.util.animation.LinearInterpolator;
import com.google.common.collect.Streams; import com.google.common.collect.Streams;
@ -117,8 +116,8 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
sender.accept(Channel.SERVER_PLAYER_CAPABILITIES.toPacket(new MsgPlayerCapabilities(this))); sender.accept(Channel.SERVER_PLAYER_CAPABILITIES.toPacket(new MsgPlayerCapabilities(this)));
} }
}); });
race = this.tracker.startTracking(TrackableDataType.of(Race.PACKET_CODEC), Race.HUMAN); race = this.tracker.startTracking(Race.TRACKABLE_TYPE, Race.HUMAN);
suppressedRace = this.tracker.startTracking(TrackableDataType.of(Race.PACKET_CODEC), Race.HUMAN); suppressedRace = this.tracker.startTracking(Race.TRACKABLE_TYPE, Race.HUMAN);
this.levels = new PlayerLevelStore(this, tracker, true, USounds.Vanilla.ENTITY_PLAYER_LEVELUP); this.levels = new PlayerLevelStore(this, tracker, true, USounds.Vanilla.ENTITY_PLAYER_LEVELUP);
this.corruption = new PlayerLevelStore(this, tracker, false, USounds.ENTITY_PLAYER_CORRUPTION); this.corruption = new PlayerLevelStore(this, tracker, false, USounds.ENTITY_PLAYER_CORRUPTION);
this.mana = addTicker(new ManaContainer(this, tracker)); this.mana = addTicker(new ManaContainer(this, tracker));
@ -203,7 +202,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
*/ */
@Override @Override
public Race getSpecies() { public Race getSpecies() {
return tracker.get(race); return race.get();
} }
/** /**
@ -227,7 +226,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
public void setSpecies(Race race) { public void setSpecies(Race race) {
race = race.validate(entity); race = race.validate(entity);
Race current = getSpecies(); Race current = getSpecies();
tracker.set(this.race, race); this.race.set(race);
if (race != current) { if (race != current) {
clearSuppressedRace(); clearSuppressedRace();
} }
@ -240,7 +239,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
} }
public void setSuppressedRace(Race race) { public void setSuppressedRace(Race race) {
tracker.set(suppressedRace, race.validate(entity)); suppressedRace.set(race.validate(entity));
} }
public void clearSuppressedRace() { public void clearSuppressedRace() {
@ -248,7 +247,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
} }
public Race getSuppressedRace() { public Race getSuppressedRace() {
return tracker.get(suppressedRace); return suppressedRace.get();
} }
public TraitDiscovery getDiscoveries() { public TraitDiscovery getDiscoveries() {

View file

@ -5,8 +5,6 @@ import java.util.List;
import java.util.Objects; import java.util.Objects;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
@ -31,13 +29,13 @@ public class DataTracker {
} }
public <T extends TrackableObject> Entry<NbtCompound> startTracking(T value) { public <T extends TrackableObject> Entry<NbtCompound> startTracking(T value) {
Entry<NbtCompound> entry = startTracking(TrackableDataType.of(PacketCodec.NBT), value.toTrackedNbt()); Entry<NbtCompound> entry = startTracking(TrackableDataType.NBT, value.toTrackedNbt());
persistentObjects.put(entry.id(), value); persistentObjects.put(entry.id(), value);
return entry; return entry;
} }
public <T> Entry<T> startTracking(TrackableDataType<T> type, T initialValue) { public <T> Entry<T> startTracking(TrackableDataType<T> type, T initialValue) {
Entry<T> entry = new Entry<>(codecs.size()); Entry<T> entry = new Entry<>(this, codecs.size());
codecs.add(new Pair<>(entry.id(), type, initialValue)); codecs.add(new Pair<>(entry.id(), type, initialValue));
return entry; return entry;
} }
@ -47,11 +45,11 @@ public class DataTracker {
return (Pair<T>)codecs.get(entry.id()); return (Pair<T>)codecs.get(entry.id());
} }
public <T> T get(Entry<T> entry) { private <T> T get(Entry<T> entry) {
return getPair(entry).value; return getPair(entry).value;
} }
public <T> void set(Entry<T> entry, T value) { private <T> void set(Entry<T> entry, T value) {
if (manager.isClient) { if (manager.isClient) {
return; return;
} }
@ -128,7 +126,15 @@ public class DataTracker {
} }
} }
public record Entry<T>(int id) {} public record Entry<T>(DataTracker tracker, int id) {
public T get() {
return tracker.get(this);
}
public void set(T t) {
tracker.set(this, t);
}
}
static class Pair<T> { static class Pair<T> {
private final TrackableDataType<T> type; private final TrackableDataType<T> type;
public final int id; public final int id;
@ -142,7 +148,7 @@ public class DataTracker {
public Pair(PacketByteBuf buffer) { public Pair(PacketByteBuf buffer) {
this.id = buffer.readInt(); this.id = buffer.readInt();
this.type = TrackableDataType.of(buffer.readInt()); this.type = TrackableDataType.of(buffer);
this.value = type.read(buffer); this.value = type.read(buffer);
} }

View file

@ -1,30 +1,40 @@
package com.minelittlepony.unicopia.network.track; package com.minelittlepony.unicopia.network.track;
import java.util.ArrayList; import com.minelittlepony.unicopia.Race;
import java.util.List; import com.minelittlepony.unicopia.Unicopia;
import com.google.common.collect.Interner;
import com.google.common.collect.Interners;
import com.minelittlepony.unicopia.util.serialization.PacketCodec; import com.minelittlepony.unicopia.util.serialization.PacketCodec;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos;
public record TrackableDataType<T>(int id, PacketCodec<T> codec) { public record TrackableDataType<T>(int id, PacketCodec<T> codec) {
private static final List<TrackableDataType<?>> REGISTRY = new ArrayList<>(); private static final Int2ObjectMap<TrackableDataType<?>> REGISTRY = new Int2ObjectOpenHashMap<>();
private static final Interner<TrackableDataType<?>> INTERNER = Interners.newStrongInterner();
public static final TrackableDataType<Integer> INT = of(new Identifier("integer"), PacketCodec.INT);
public static final TrackableDataType<Float> FLOAT = of(new Identifier("float"), PacketCodec.FLOAT);
public static final TrackableDataType<Boolean> BOOLEAN = of(new Identifier("boolean"), PacketCodec.BOOLEAN);
public static final TrackableDataType<UUID> UUID = of(new Identifier("uuid"), PacketCodec.UUID);
public static final TrackableDataType<NbtCompound> NBT = of(new Identifier("nbt"), PacketCodec.NBT);
public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(new Identifier("optional_pos"), PacketCodec.OPTIONAL_POS);
public static final TrackableDataType<Race> RACE = TrackableDataType.of(Unicopia.id("race"), PacketCodec.ofRegistry(Race.REGISTRY));
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> TrackableDataType<T> of(int id) { public static <T> TrackableDataType<T> of(PacketByteBuf buffer) {
return (TrackableDataType<T>)REGISTRY.get(id); int id = buffer.readInt();
return Objects.requireNonNull((TrackableDataType<T>)REGISTRY.get(id), "Unknown trackable data type id: " + id);
} }
public static <T> TrackableDataType<T> of(PacketCodec<T> codec) { @SuppressWarnings("unchecked")
@SuppressWarnings("unchecked") public static <T> TrackableDataType<T> of(Identifier typeName, PacketCodec<T> codec) {
TrackableDataType<T> type = (TrackableDataType<T>) INTERNER.intern(new TrackableDataType<>(REGISTRY.size(), codec)); return (TrackableDataType<T>)REGISTRY.computeIfAbsent(typeName.hashCode(), t -> new TrackableDataType<>(t, codec));
if (type.id() == REGISTRY.size()) {
REGISTRY.add(type);
}
return type;
} }
public T read(PacketByteBuf buffer) { public T read(PacketByteBuf buffer) {
@ -32,7 +42,7 @@ public record TrackableDataType<T>(int id, PacketCodec<T> codec) {
} }
public void write(PacketByteBuf buffer, T value) { public void write(PacketByteBuf buffer, T value) {
buffer.writeInt(id()); buffer.writeInt(id);
codec().write(buffer, value); codec().write(buffer, value);
} }
} }