Remove Spell#isDirty and Spell#setDirty

This commit is contained in:
Sollace 2024-09-21 21:40:20 +01:00
parent 92ad502fa7
commit 469aaeecd1
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
22 changed files with 114 additions and 118 deletions

View file

@ -131,7 +131,7 @@ class MultiSpellSlot implements SpellSlots, NbtSerialisable {
return hasValue ? Status.NEW : Status.REMOVED; return hasValue ? Status.NEW : Status.REMOVED;
} }
return spell.hasDirtySpell() ? Status.UPDATED : Status.DEFAULT; return Status.DEFAULT;
} }
@Override @Override

View file

@ -80,18 +80,6 @@ public abstract class AbstractDelegatingSpell implements Spell {
return getOrEmpty().isDying(); return getOrEmpty().isDying();
} }
@Deprecated
@Override
public boolean isDirty() {
return delegate.hasDirtySpell();
}
@Deprecated
@Override
public void setDirty() {
getOrEmpty().setDirty();
}
@Override @Override
public boolean isHidden() { public boolean isHidden() {
return getOrEmpty().isHidden(); return getOrEmpty().isHidden();

View file

@ -20,7 +20,7 @@ import net.minecraft.nbt.NbtCompound;
*/ */
public abstract class AbstractDisguiseSpell extends AbstractSpell implements Disguise, ProjectileImpactListener { public abstract class AbstractDisguiseSpell extends AbstractSpell implements Disguise, ProjectileImpactListener {
private final EntityAppearance disguise = new EntityAppearance(); private final EntityAppearance disguise = dataTracker.startTracking(new EntityAppearance());
public AbstractDisguiseSpell(CustomisedSpellType<?> type) { public AbstractDisguiseSpell(CustomisedSpellType<?> type) {
super(type); super(type);

View file

@ -44,11 +44,6 @@ public final class EmptySpell implements Spell {
return false; return false;
} }
@Override
public boolean isDirty() {
return false;
}
@Override @Override
public boolean tick(Caster<?> caster, Situation situation) { public boolean tick(Caster<?> caster, Situation situation) {
return false; return false;
@ -57,9 +52,6 @@ public final class EmptySpell implements Spell {
@Override @Override
public void tickDying(Caster<?> caster) { } public void tickDying(Caster<?> caster) { }
@Override
public void setDirty() { }
@Override @Override
public boolean isHidden() { public boolean isHidden() {
return true; return true;

View file

@ -9,6 +9,8 @@ import com.minelittlepony.unicopia.ability.magic.spell.effect.AbstractSpell;
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType; import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
import com.minelittlepony.unicopia.entity.mob.CastSpellEntity; import com.minelittlepony.unicopia.entity.mob.CastSpellEntity;
import com.minelittlepony.unicopia.network.track.DataTracker;
import com.minelittlepony.unicopia.network.track.TrackableDataType;
import com.minelittlepony.unicopia.server.world.Ether; import com.minelittlepony.unicopia.server.world.Ether;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
@ -21,12 +23,10 @@ import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World; import net.minecraft.world.World;
public class PlacementControlSpell extends AbstractSpell implements OrientedSpell { public class PlacementControlSpell extends AbstractSpell implements OrientedSpell {
@Nullable private final DataTracker.Entry<UUID> placedEntityId = dataTracker.startTracking(TrackableDataType.UUID, null);
private UUID placedEntityId; private final DataTracker.Entry<Optional<RegistryKey<World>>> dimension = dataTracker.startTracking(TrackableDataType.ofRegistryKey(), Optional.empty());
private final DataTracker.Entry<Optional<Vec3d>> position = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty());
private Optional<RegistryKey<World>> dimension = Optional.empty(); private final DataTracker.Entry<Optional<Vec3d>> orientation = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty());
private Optional<Vec3d> position = Optional.empty();
private Optional<Vec3d> orientation = Optional.empty();
@Nullable @Nullable
private Spell delegate; private Spell delegate;
@ -46,26 +46,23 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
} }
public Optional<Vec3d> getPosition() { public Optional<Vec3d> getPosition() {
return position; return position.get();
} }
public void setDimension(RegistryKey<World> dimension) { public void setDimension(RegistryKey<World> dimension) {
this.dimension = Optional.of(dimension); this.dimension.set(Optional.of(dimension));
setDirty();
} }
public void setPosition(Vec3d position) { public void setPosition(Vec3d position) {
this.position = Optional.of(position); this.position.set(Optional.of(position));
setDirty();
} }
@Override @Override
public void setOrientation(Caster<?> caster, float pitch, float yaw) { public void setOrientation(Caster<?> caster, float pitch, float yaw) {
this.orientation = Optional.of(new Vec3d(pitch, yaw, 0)); this.orientation.set(Optional.of(new Vec3d(pitch, yaw, 0)));
if (delegate instanceof OrientedSpell o) { if (delegate instanceof OrientedSpell o) {
o.setOrientation(caster, pitch, yaw); o.setOrientation(caster, pitch, yaw);
} }
setDirty();
if (!caster.isClient()) { if (!caster.isClient()) {
var entry = getConnection(caster); var entry = getConnection(caster);
if (entry != null) { if (entry != null) {
@ -84,24 +81,23 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
public boolean tick(Caster<?> source, Situation situation) { public boolean tick(Caster<?> source, Situation situation) {
if (!source.isClient()) { if (!source.isClient()) {
if (placedEntityId == null) { if (placedEntityId.get() == null) {
if (dimension.isEmpty()) { if (dimension.get().isEmpty()) {
setDimension(source.asWorld().getRegistryKey()); setDimension(source.asWorld().getRegistryKey());
} }
if (position.isEmpty()) { if (getPosition().isEmpty()) {
setPosition(source.asEntity().getPos()); setPosition(source.asEntity().getPos());
} }
System.out.println("Creating placed spell");
CastSpellEntity entity = new CastSpellEntity(source.asWorld(), source, this); CastSpellEntity entity = new CastSpellEntity(source.asWorld(), source, this);
Vec3d pos = position.get(); Vec3d pos = getPosition().get();
Vec3d rot = orientation.orElse(Vec3d.ZERO); Vec3d rot = orientation.get().orElse(Vec3d.ZERO);
entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x); entity.updatePositionAndAngles(pos.x, pos.y, pos.z, (float)rot.y, (float)rot.x);
entity.getWorld().spawnEntity(entity); entity.getWorld().spawnEntity(entity);
placedEntityId = entity.getUuid(); placedEntityId.set(entity.getUuid());
setDirty();
} else { } else {
if (getConnection(source) == null) { if (getConnection(source) == null) {
setDead(); setDead();
@ -114,24 +110,24 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
@Nullable @Nullable
private Ether.Entry<?> getConnection(Caster<?> source) { private Ether.Entry<?> getConnection(Caster<?> source) {
return delegate == null || placedEntityId == null ? null : getWorld(source) return delegate == null || placedEntityId.get() == null ? null : getWorld(source)
.map(world -> Ether.get(world).get(getDelegate().getTypeAndTraits().type(), placedEntityId, delegate.getUuid())) .map(world -> Ether.get(world).get(getDelegate().getTypeAndTraits().type(), placedEntityId.get(), delegate.getUuid()))
.orElse(null); .orElse(null);
} }
private Optional<World> getWorld(Caster<?> source) { private Optional<World> getWorld(Caster<?> source) {
return dimension.map(source.asWorld().getServer()::getWorld); return dimension.get().map(source.asWorld().getServer()::getWorld);
} }
@Override @Override
public void toNBT(NbtCompound compound) { public void toNBT(NbtCompound compound) {
super.toNBT(compound); super.toNBT(compound);
compound.put("spell", Spell.writeNbt(delegate)); compound.put("spell", Spell.writeNbt(delegate));
position.ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos))); position.get().ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos)));
orientation.ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o))); orientation.get().ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o)));
dimension.ifPresent(d -> compound.putString("dimension", d.getValue().toString())); dimension.get().ifPresent(d -> compound.putString("dimension", d.getValue().toString()));
if (placedEntityId != null) { if (placedEntityId.get() != null) {
compound.putUuid("placedEntityId", placedEntityId); compound.putUuid("placedEntityId", placedEntityId.get());
} }
} }
@ -139,12 +135,10 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound) {
super.fromNBT(compound); super.fromNBT(compound);
delegate = Spell.readNbt(compound.getCompound("spell")); delegate = Spell.readNbt(compound.getCompound("spell"));
placedEntityId = compound.containsUuid("placedEntityId") ? compound.getUuid("placedEntityId") : null; placedEntityId.set(compound.containsUuid("placedEntityId") ? compound.getUuid("placedEntityId") : null);
position = compound.contains("position") ? Optional.of(NbtSerialisable.readVector(compound.getList("position", NbtElement.DOUBLE_TYPE))) : Optional.empty(); position.set(compound.contains("position") ? Optional.of(NbtSerialisable.readVector(compound.getList("position", NbtElement.DOUBLE_TYPE))) : Optional.empty());
orientation = compound.contains("orientation") ? Optional.of(NbtSerialisable.readVector(compound.getList("orientation", NbtElement.DOUBLE_TYPE))) : Optional.empty(); orientation.set(compound.contains("orientation") ? Optional.of(NbtSerialisable.readVector(compound.getList("orientation", NbtElement.DOUBLE_TYPE))) : Optional.empty());
if (compound.contains("dimension", NbtElement.STRING_TYPE)) { dimension.set(compound.contains("dimension", NbtElement.STRING_TYPE) ? Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id)) : Optional.empty());
dimension = Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id));
}
} }
public interface PlacementDelegate { public interface PlacementDelegate {

View file

@ -74,18 +74,6 @@ public interface Spell extends NbtSerialisable, Affine {
boolean isDying(); boolean isDying();
/**
* Returns true if this effect has changes that need to be sent to the client.
*/
@Deprecated
boolean isDirty();
/**
* Marks this effect as dirty.
*/
@Deprecated
void setDirty();
/** /**
* Applies this spell to the supplied caster. * Applies this spell to the supplied caster.
* @param caster The caster to apply the spell to * @param caster The caster to apply the spell to

View file

@ -25,11 +25,6 @@ public final class SpellReference<T extends Spell> implements NbtSerialisable {
set(spell, null); set(spell, null);
} }
@Deprecated
public boolean hasDirtySpell() {
return spell != null && spell.isDirty();
}
public boolean set(T spell, @Nullable Caster<?> owner) { public boolean set(T spell, @Nullable Caster<?> owner) {
spell = spell == null || spell.isDead() ? null : spell; spell = spell == null || spell.isDead() ? null : spell;
if (spell == this.spell) { if (spell == this.spell) {

View file

@ -20,7 +20,6 @@ public abstract class AbstractSpell implements Spell {
private final DataTracker.Entry<Boolean> dead = dataTracker.startTracking(TrackableDataType.BOOLEAN, false); private final DataTracker.Entry<Boolean> dead = dataTracker.startTracking(TrackableDataType.BOOLEAN, false);
private final DataTracker.Entry<Boolean> dying = dataTracker.startTracking(TrackableDataType.BOOLEAN, false); private final DataTracker.Entry<Boolean> dying = dataTracker.startTracking(TrackableDataType.BOOLEAN, false);
private boolean dirty;
private final DataTracker.Entry<Boolean> hidden = dataTracker.startTracking(TrackableDataType.BOOLEAN, false); private final DataTracker.Entry<Boolean> hidden = dataTracker.startTracking(TrackableDataType.BOOLEAN, false);
private boolean destroyed; private boolean destroyed;
@ -66,18 +65,6 @@ public abstract class AbstractSpell implements Spell {
return dying.get(); return dying.get();
} }
@Deprecated
@Override
public final boolean isDirty() {
return dirty;
}
@Deprecated
@Override
public final void setDirty() {
dirty = true;
}
@Override @Override
public final boolean isHidden() { public final boolean isHidden() {
return hidden.get(); return hidden.get();
@ -120,7 +107,6 @@ public abstract class AbstractSpell implements Spell {
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound) {
dirty = false;
if (compound.containsUuid("uuid")) { if (compound.containsUuid("uuid")) {
uuid = compound.getUuid("uuid"); uuid = compound.getUuid("uuid");
} }

View file

@ -28,14 +28,12 @@ public class AttractiveSpell extends ShieldSpell implements HomingSpell, TimedSp
static final TooltipFactory TARGET = (type, tooltip) -> (TARGET_FOCUSED_ENTITY.get(type.traits()) ? TARGET_FOCUSED_ENTITY : ShieldSpell.TARGET).appendTooltip(type, tooltip); static final TooltipFactory TARGET = (type, tooltip) -> (TARGET_FOCUSED_ENTITY.get(type.traits()) ? TARGET_FOCUSED_ENTITY : ShieldSpell.TARGET).appendTooltip(type, tooltip);
static final TooltipFactory TOOLTIP = TooltipFactory.of(TIME, RANGE, TARGET, STICK_TO_TARGET, CAST_ON); static final TooltipFactory TOOLTIP = TooltipFactory.of(TIME, RANGE, TARGET, STICK_TO_TARGET, CAST_ON);
private final EntityReference<Entity> target = new EntityReference<>(); private final EntityReference<Entity> target = dataTracker.startTracking(new EntityReference<>());
private final Timer timer; private final Timer timer = new Timer(TIME.get(getTraits()));
protected AttractiveSpell(CustomisedSpellType<?> type) { protected AttractiveSpell(CustomisedSpellType<?> type) {
super(type); super(type);
timer = new Timer(TIME.get(getTraits()));
dataTracker.startTracking(target);
} }
@Override @Override

View file

@ -19,11 +19,10 @@ import net.minecraft.registry.Registries;
public class AwkwardSpell extends AbstractSpell implements TimedSpell { public class AwkwardSpell extends AbstractSpell implements TimedSpell {
private final Timer timer; private final Timer timer = new Timer(20);
protected AwkwardSpell(CustomisedSpellType<?> type) { protected AwkwardSpell(CustomisedSpellType<?> type) {
super(type); super(type);
timer = new Timer(20);
} }
@Override @Override

View file

@ -56,17 +56,14 @@ public class BubbleSpell extends AbstractSpell implements TimedSpell,
static final TooltipFactory TOOLTIP = TooltipFactory.of(TimedSpell.TIME, SOAPINESS); static final TooltipFactory TOOLTIP = TooltipFactory.of(TimedSpell.TIME, SOAPINESS);
private final Timer timer; private final Timer timer = new Timer(TIME.get(getTraits()));
private float prevRadius; private float prevRadius;
private DataTracker.Entry<Float> radius; private DataTracker.Entry<Float> radius = dataTracker.startTracking(TrackableDataType.FLOAT, 0F);
private DataTracker.Entry<Integer> struggles; private DataTracker.Entry<Integer> struggles = dataTracker.startTracking(TrackableDataType.INT, SOAPINESS.get(getTraits()));
protected BubbleSpell(CustomisedSpellType<?> type) { protected BubbleSpell(CustomisedSpellType<?> type) {
super(type); super(type);
timer = new Timer(TIME.get(getTraits()));
radius = dataTracker.startTracking(TrackableDataType.FLOAT, 0F);
struggles = dataTracker.startTracking(TrackableDataType.INT, SOAPINESS.get(getTraits()));
} }
@Override @Override

View file

@ -59,11 +59,10 @@ public class FeatherFallSpell extends AbstractSpell implements TimedSpell {
.with(Trait.ORDER, 15) .with(Trait.ORDER, 15)
.build(); .build();
private final Timer timer; private final Timer timer = new Timer(DURATION.get(getTraits()));
protected FeatherFallSpell(CustomisedSpellType<?> type) { protected FeatherFallSpell(CustomisedSpellType<?> type) {
super(type); super(type);
timer = new Timer(DURATION.get(getTraits()));
} }
@Override @Override

View file

@ -47,7 +47,7 @@ public class FireBoltSpell extends AbstractSpell implements HomingSpell,
static final TooltipFactory TOOLTIP = TooltipFactory.of(EXPLOSION_STRENGTH, VELOCITY, PROJECTILE_COUNT, FOLLOWS_TARGET, FOLLOW_RANGE.conditionally(FOLLOWS_TARGET::get)); static final TooltipFactory TOOLTIP = TooltipFactory.of(EXPLOSION_STRENGTH, VELOCITY, PROJECTILE_COUNT, FOLLOWS_TARGET, FOLLOW_RANGE.conditionally(FOLLOWS_TARGET::get));
private final EntityReference<Entity> target = new EntityReference<>(); private final EntityReference<Entity> target = dataTracker.startTracking(new EntityReference<>());
protected FireBoltSpell(CustomisedSpellType<?> type) { protected FireBoltSpell(CustomisedSpellType<?> type) {
super(type); super(type);

View file

@ -38,13 +38,12 @@ public class LightSpell extends AbstractSpell implements TimedSpell, ProjectileD
static final TooltipFactory TOOLTIP = TooltipFactory.of(TIME, ORB_COUNT); static final TooltipFactory TOOLTIP = TooltipFactory.of(TIME, ORB_COUNT);
private final Timer timer; private final Timer timer = new Timer(TIME.get(getTraits()));
private final List<EntityReference<FairyEntity>> lights = new ArrayList<>(); private final List<EntityReference<FairyEntity>> lights = new ArrayList<>();
protected LightSpell(CustomisedSpellType<?> type) { protected LightSpell(CustomisedSpellType<?> type) {
super(type); super(type);
timer = new Timer(TIME.get(getTraits()));
} }
@Override @Override

View file

@ -11,11 +11,10 @@ public class MimicSpell extends AbstractDisguiseSpell implements HomingSpell, Ti
static final TooltipFactory TOOLTIP = TimedSpell.TIME; static final TooltipFactory TOOLTIP = TimedSpell.TIME;
private final Timer timer; private final Timer timer = new Timer(TIME.get(getTraits()));
protected MimicSpell(CustomisedSpellType<?> type) { protected MimicSpell(CustomisedSpellType<?> type) {
super(type); super(type);
timer = new Timer(TIME.get(getTraits()));
} }
@Override @Override

View file

@ -46,7 +46,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
private final DataTracker.Entry<UUID> targetPortalId = dataTracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID); private final DataTracker.Entry<UUID> targetPortalId = dataTracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID);
private final DataTracker.Entry<Float> targetPortalPitch = dataTracker.startTracking(TrackableDataType.FLOAT, 0F); private final DataTracker.Entry<Float> targetPortalPitch = dataTracker.startTracking(TrackableDataType.FLOAT, 0F);
private final DataTracker.Entry<Float> targetPortalYaw = dataTracker.startTracking(TrackableDataType.FLOAT, 0F); private final DataTracker.Entry<Float> targetPortalYaw = dataTracker.startTracking(TrackableDataType.FLOAT, 0F);
private final EntityReference<Entity> teleportationTarget = new EntityReference<>(); private final EntityReference<Entity> teleportationTarget = dataTracker.startTracking(new EntityReference<>());
private final DataTracker.Entry<Float> pitch = dataTracker.startTracking(TrackableDataType.FLOAT, 0F); private final DataTracker.Entry<Float> pitch = dataTracker.startTracking(TrackableDataType.FLOAT, 0F);
private final DataTracker.Entry<Float> yaw = dataTracker.startTracking(TrackableDataType.FLOAT, 0F); private final DataTracker.Entry<Float> yaw = dataTracker.startTracking(TrackableDataType.FLOAT, 0F);

View file

@ -67,10 +67,6 @@ class EntityReplacementManager implements Disguise {
return disguise; return disguise;
} }
@Override
public void setDirty() {
}
@Override @Override
public boolean isDead() { public boolean isDead() {
return false; return false;

View file

@ -24,8 +24,6 @@ public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider
EntityAppearance getDisguise(); EntityAppearance getDisguise();
void setDirty();
boolean isDead(); boolean isDead();
default Optional<EntityAppearance> getAppearance() { default Optional<EntityAppearance> getAppearance() {
@ -57,7 +55,6 @@ public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider
} }
getDisguise().setAppearance(entity); getDisguise().setAppearance(entity);
setDirty();
return this; return this;
} }

View file

@ -21,6 +21,7 @@ import com.minelittlepony.unicopia.entity.mob.SombraEntity;
import com.minelittlepony.unicopia.entity.mob.UEntityAttributes; import com.minelittlepony.unicopia.entity.mob.UEntityAttributes;
import com.minelittlepony.unicopia.entity.player.PlayerDimensions; import com.minelittlepony.unicopia.entity.player.PlayerDimensions;
import com.minelittlepony.unicopia.entity.player.Pony; import com.minelittlepony.unicopia.entity.player.Pony;
import com.minelittlepony.unicopia.network.track.TrackableObject;
import com.minelittlepony.unicopia.projectile.ProjectileUtil; import com.minelittlepony.unicopia.projectile.ProjectileUtil;
import com.minelittlepony.unicopia.util.NbtSerialisable; import com.minelittlepony.unicopia.util.NbtSerialisable;
import com.mojang.authlib.GameProfile; import com.mojang.authlib.GameProfile;
@ -51,7 +52,7 @@ import net.minecraft.nbt.NbtElement;
import net.minecraft.util.math.Vec3d; import net.minecraft.util.math.Vec3d;
import net.minecraft.util.shape.VoxelShape; import net.minecraft.util.shape.VoxelShape;
public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider, EntityCollisions.ComplexCollidable { public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provider, FlightType.Provider, EntityCollisions.ComplexCollidable, TrackableObject<EntityAppearance> {
private static final Optional<Float> BLOCK_HEIGHT = Optional.of(0.5F); private static final Optional<Float> BLOCK_HEIGHT = Optional.of(0.5F);
@NotNull @NotNull
@ -77,6 +78,8 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
@Nullable @Nullable
private NbtCompound entityNbt; private NbtCompound entityNbt;
private boolean dirty;
@Nullable @Nullable
public Entity getAppearance() { public Entity getAppearance() {
return entity; return entity;
@ -109,6 +112,7 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
entityNbt = entity == null ? null : encodeEntityToNBT(entity); entityNbt = entity == null ? null : encodeEntityToNBT(entity);
entityId = entityNbt == null ? "" : entityNbt.getString("id"); entityId = entityNbt == null ? "" : entityNbt.getString("id");
markDirty();
} }
public boolean isPresent() { public boolean isPresent() {
@ -393,4 +397,44 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e.entity(), context, output)); getAttachments().forEach(e -> EntityCollisions.getCollissionShapes(e.entity(), context, output));
} }
public void markDirty() {
dirty = true;
}
@Override
public Status getStatus() {
if (dirty) {
dirty = false;
return Status.UPDATED;
}
return Status.DEFAULT;
}
@Override
public void readTrackedNbt(NbtCompound nbt) {
fromNBT(nbt);
}
@Override
public NbtCompound writeTrackedNbt() {
return toNBT();
}
@Override
public void discard(boolean immediate) {
setAppearance(null);
dirty = false;
}
@Override
public void copyTo(EntityAppearance destination) {
destination.entityId = entityId;
destination.entity = entity;
destination.blockEntity = blockEntity;
destination.attachments.addAll(attachments);
destination.dimensions = dimensions;
destination.tag = tag == null ? null : tag.copy();
destination.entityNbt = entityNbt == null ? null : entityNbt.copy();
}
} }

View file

@ -65,7 +65,7 @@ public class SheepBehaviour extends EntityBehaviour<SheepEntity> {
} }
} while (dropAmount-- > 0); } while (dropAmount-- > 0);
} }
spell.setDirty(); spell.getAppearance().ifPresent(EntityAppearance::markDirty);
} }
} }
} }

View file

@ -11,8 +11,10 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import net.minecraft.nbt.NbtCompound; import net.minecraft.nbt.NbtCompound;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
public record TrackableDataType<T>(int id, PacketCodec<T> codec) { public record TrackableDataType<T>(int id, PacketCodec<T> codec) {
private static final Int2ObjectMap<TrackableDataType<?>> REGISTRY = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<TrackableDataType<?>> REGISTRY = new Int2ObjectOpenHashMap<>();
@ -26,8 +28,16 @@ public record TrackableDataType<T>(int id, PacketCodec<T> codec) {
public static final TrackableDataType<Optional<PacketByteBuf>> RAW_BYTES = of(new Identifier("raw_bytes"), PacketCodec.RAW_BYTES.asOptional()); public static final TrackableDataType<Optional<PacketByteBuf>> RAW_BYTES = of(new Identifier("raw_bytes"), PacketCodec.RAW_BYTES.asOptional());
public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(new Identifier("optional_pos"), PacketCodec.OPTIONAL_POS); public static final TrackableDataType<Optional<BlockPos>> OPTIONAL_POS = of(new Identifier("optional_pos"), PacketCodec.OPTIONAL_POS);
public static final TrackableDataType<Optional<Vec3d>> OPTIONAL_VECTOR = of(new Identifier("optional_vector"), PacketCodec.OPTIONAL_VECTOR);
private static final TrackableDataType<Optional<RegistryKey<?>>> OPTIONAL_REGISTRY_KEY = of(new Identifier("optional_registry_key"), PacketCodec.OPTIONAL_REGISTRY_KEY);
public static final TrackableDataType<Race> RACE = TrackableDataType.of(Unicopia.id("race"), PacketCodec.ofRegistry(Race.REGISTRY)); public static final TrackableDataType<Race> RACE = TrackableDataType.of(Unicopia.id("race"), PacketCodec.ofRegistry(Race.REGISTRY));
@SuppressWarnings({ "rawtypes", "unchecked" })
public static <T> TrackableDataType<Optional<RegistryKey<T>>> ofRegistryKey() {
return (TrackableDataType)OPTIONAL_REGISTRY_KEY;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static <T> TrackableDataType<T> of(PacketByteBuf buffer) { public static <T> TrackableDataType<T> of(PacketByteBuf buffer) {
int id = buffer.readInt(); int id = buffer.readInt();

View file

@ -16,9 +16,11 @@ import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtIo; import net.minecraft.nbt.NbtIo;
import net.minecraft.network.PacketByteBuf; import net.minecraft.network.PacketByteBuf;
import net.minecraft.registry.Registry; import net.minecraft.registry.Registry;
import net.minecraft.registry.RegistryKey;
import net.minecraft.util.Identifier; import net.minecraft.util.Identifier;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
public record PacketCodec<T>(PacketByteBuf.PacketReader<T> reader, PacketByteBuf.PacketWriter<T> writer) { public record PacketCodec<T>(PacketByteBuf.PacketReader<T> reader, PacketByteBuf.PacketWriter<T> writer) {
public static final PacketCodec<Boolean> BOOLEAN = new PacketCodec<>(PacketByteBuf::readBoolean, PacketByteBuf::writeBoolean); public static final PacketCodec<Boolean> BOOLEAN = new PacketCodec<>(PacketByteBuf::readBoolean, PacketByteBuf::writeBoolean);
@ -30,7 +32,7 @@ public record PacketCodec<T>(PacketByteBuf.PacketReader<T> reader, PacketByteBuf
public static final PacketCodec<UUID> UUID = new PacketCodec<>(PacketByteBuf::readUuid, PacketByteBuf::writeUuid); public static final PacketCodec<UUID> UUID = new PacketCodec<>(PacketByteBuf::readUuid, PacketByteBuf::writeUuid);
public static final PacketCodec<Optional<UUID>> OPTIONAL_UUID = UUID.asOptional(); public static final PacketCodec<Optional<UUID>> OPTIONAL_UUID = UUID.asOptional();
public static final PacketCodec<Identifier> IDENTIFIER = STRING.xMap(Identifier::new, Identifier::toString); public static final PacketCodec<Identifier> IDENTIFIER = new PacketCodec<>(PacketByteBuf::readIdentifier, PacketByteBuf::writeIdentifier);
public static final PacketCodec<NbtCompound> NBT = new PacketCodec<>(PacketByteBuf::readNbt, PacketByteBuf::writeNbt); public static final PacketCodec<NbtCompound> NBT = new PacketCodec<>(PacketByteBuf::readNbt, PacketByteBuf::writeNbt);
@ -58,6 +60,19 @@ public record PacketCodec<T>(PacketByteBuf.PacketReader<T> reader, PacketByteBuf
public static final PacketCodec<BlockPos> POS = new PacketCodec<>(PacketByteBuf::readBlockPos, PacketByteBuf::writeBlockPos); public static final PacketCodec<BlockPos> POS = new PacketCodec<>(PacketByteBuf::readBlockPos, PacketByteBuf::writeBlockPos);
public static final PacketCodec<Optional<BlockPos>> OPTIONAL_POS = POS.asOptional(); public static final PacketCodec<Optional<BlockPos>> OPTIONAL_POS = POS.asOptional();
public static final PacketCodec<Vec3d> VECTOR = new PacketCodec<>(buffer -> new Vec3d(buffer.readDouble(), buffer.readDouble(), buffer.readDouble()), (buffer, vector) -> {
buffer.writeDouble(vector.x);
buffer.writeDouble(vector.y);
buffer.writeDouble(vector.z);
});
public static final PacketCodec<Optional<Vec3d>> OPTIONAL_VECTOR = VECTOR.asOptional();
public static final PacketCodec<RegistryKey<?>> REGISTRY_KEY = new PacketCodec<>(buffer -> {
return RegistryKey.of(RegistryKey.ofRegistry(IDENTIFIER.read(buffer)), IDENTIFIER.read(buffer));
}, (buffer, key) -> {
IDENTIFIER.write(buffer, key.getRegistry());
IDENTIFIER.write(buffer, key.getValue());
});
public static final PacketCodec<Optional<RegistryKey<?>>> OPTIONAL_REGISTRY_KEY = REGISTRY_KEY.asOptional();
public static final <T> PacketCodec<T> ofRegistry(Registry<T> registry) { public static final <T> PacketCodec<T> ofRegistry(Registry<T> registry) {
return INT.xMap(registry::get, registry::getRawId); return INT.xMap(registry::get, registry::getRawId);