mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Fix crashes due to null uuids and fix entity references not serializing
This commit is contained in:
parent
b003abdcb1
commit
8d944a2dbf
6 changed files with 30 additions and 38 deletions
|
@ -20,12 +20,11 @@ import net.minecraft.registry.RegistryKey;
|
||||||
import net.minecraft.registry.RegistryKeys;
|
import net.minecraft.registry.RegistryKeys;
|
||||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Util;
|
|
||||||
import net.minecraft.util.math.Vec3d;
|
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 {
|
||||||
private final DataTracker.Entry<UUID> placedEntityId = dataTracker.startTracking(TrackableDataType.UUID, Util.NIL_UUID);
|
private final DataTracker.Entry<Optional<UUID>> placedEntityId = dataTracker.startTracking(TrackableDataType.UUID, Optional.empty());
|
||||||
private final DataTracker.Entry<Optional<RegistryKey<World>>> dimension = dataTracker.startTracking(TrackableDataType.ofRegistryKey(), Optional.empty());
|
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 final DataTracker.Entry<Optional<Vec3d>> position = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty());
|
||||||
private final DataTracker.Entry<Optional<Vec3d>> orientation = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty());
|
private final DataTracker.Entry<Optional<Vec3d>> orientation = dataTracker.startTracking(TrackableDataType.OPTIONAL_VECTOR, Optional.empty());
|
||||||
|
@ -83,7 +82,7 @@ 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 (Util.NIL_UUID.equals(placedEntityId.getOrDefault(Util.NIL_UUID))) {
|
if (placedEntityId.get().isEmpty()) {
|
||||||
if (dimension.get().isEmpty()) {
|
if (dimension.get().isEmpty()) {
|
||||||
setDimension(source.asWorld().getRegistryKey());
|
setDimension(source.asWorld().getRegistryKey());
|
||||||
}
|
}
|
||||||
|
@ -99,7 +98,7 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
|
||||||
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.set(entity.getUuid());
|
placedEntityId.set(Optional.of(entity.getUuid()));
|
||||||
} else {
|
} else {
|
||||||
if (getConnection(source) == null) {
|
if (getConnection(source) == null) {
|
||||||
setDead();
|
setDead();
|
||||||
|
@ -112,8 +111,8 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private Ether.Entry<?> getConnection(Caster<?> source) {
|
private Ether.Entry<?> getConnection(Caster<?> source) {
|
||||||
return delegate == null || Util.NIL_UUID.equals(placedEntityId.getOrDefault(Util.NIL_UUID)) ? null : getWorld(source)
|
return delegate == null || placedEntityId.get().isEmpty() ? null : getWorld(source)
|
||||||
.map(world -> Ether.get(world).get(getDelegate().getTypeAndTraits().type(), placedEntityId.get(), delegate.getUuid()))
|
.map(world -> Ether.get(world).get(getDelegate().getTypeAndTraits().type(), placedEntityId.get().get(), delegate.getUuid()))
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,17 +127,14 @@ public class PlacementControlSpell extends AbstractSpell implements OrientedSpel
|
||||||
position.get().ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos)));
|
position.get().ifPresent(pos -> compound.put("position", NbtSerialisable.writeVector(pos)));
|
||||||
orientation.get().ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o)));
|
orientation.get().ifPresent(o -> compound.put("orientation", NbtSerialisable.writeVector(o)));
|
||||||
dimension.get().ifPresent(d -> compound.putString("dimension", d.getValue().toString()));
|
dimension.get().ifPresent(d -> compound.putString("dimension", d.getValue().toString()));
|
||||||
@Nullable UUID placeEntityUuid = placedEntityId.getOrDefault(Util.NIL_UUID);
|
placedEntityId.get().ifPresent(i -> compound.putUuid("placedEntityId", i));
|
||||||
if (!Util.NIL_UUID.equals(placeEntityUuid)) {
|
|
||||||
compound.putUuid("placedEntityId", placeEntityUuid);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
|
public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
|
||||||
super.fromNBT(compound, lookup);
|
super.fromNBT(compound, lookup);
|
||||||
delegate = Spell.readNbt(compound.getCompound("spell"), lookup);
|
delegate = Spell.readNbt(compound.getCompound("spell"), lookup);
|
||||||
placedEntityId.set(compound.containsUuid("placedEntityId") ? compound.getUuid("placedEntityId") : Util.NIL_UUID);
|
placedEntityId.set(compound.containsUuid("placedEntityId") ? Optional.of(compound.getUuid("placedEntityId")) : Optional.empty());
|
||||||
position.set(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.set(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());
|
||||||
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.set(compound.contains("dimension", NbtElement.STRING_TYPE) ? Optional.ofNullable(Identifier.tryParse(compound.getString("dimension"))).map(id -> RegistryKey.of(RegistryKeys.WORLD, id)) : Optional.empty());
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
package com.minelittlepony.unicopia.ability.magic.spell.effect;
|
||||||
|
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
@ -29,7 +30,6 @@ import net.minecraft.particle.ParticleTypes;
|
||||||
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
import net.minecraft.registry.RegistryWrapper.WrapperLookup;
|
||||||
import net.minecraft.server.network.ServerPlayerEntity;
|
import net.minecraft.server.network.ServerPlayerEntity;
|
||||||
import net.minecraft.server.world.ServerWorld;
|
import net.minecraft.server.world.ServerWorld;
|
||||||
import net.minecraft.util.Util;
|
|
||||||
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;
|
import net.minecraft.util.math.Vec3d;
|
||||||
|
@ -43,8 +43,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
.build();
|
.build();
|
||||||
private static final Shape PARTICLE_AREA = new Sphere(true, 2, 1, 1, 0);
|
private static final Shape PARTICLE_AREA = new Sphere(true, 2, 1, 1, 0);
|
||||||
|
|
||||||
@Nullable
|
private final DataTracker.Entry<Optional<UUID>> targetPortalId = dataTracker.startTracking(TrackableDataType.UUID, Optional.empty());
|
||||||
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 = dataTracker.startTracking(new EntityReference<>());
|
private final EntityReference<Entity> teleportationTarget = dataTracker.startTracking(new EntityReference<>());
|
||||||
|
@ -84,11 +83,11 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
private Ether.Entry<PortalSpell> getDestination(Caster<?> source) {
|
private Ether.Entry<PortalSpell> getDestination(Caster<?> source) {
|
||||||
return Util.NIL_UUID.equals(targetPortalId.getOrDefault(Util.NIL_UUID)) ? null : getDestinationReference()
|
return targetPortalId.get().flatMap(id -> getDestinationReference()
|
||||||
.getTarget()
|
.getTarget()
|
||||||
.map(target -> Ether.get(source.asWorld()).get((SpellType<PortalSpell>)getType(), target.uuid(), targetPortalId.get()))
|
.map(target -> Ether.get(source.asWorld()).get((SpellType<PortalSpell>)getType(), target.uuid(), id))
|
||||||
.filter(destination -> destination.isClaimedBy(getUuid()))
|
.filter(destination -> destination.isClaimedBy(getUuid()))
|
||||||
.orElse(null);
|
).orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -99,10 +98,10 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
protected void setDestination(@Nullable Ether.Entry<?> destination) {
|
protected void setDestination(@Nullable Ether.Entry<?> destination) {
|
||||||
if (destination == null) {
|
if (destination == null) {
|
||||||
teleportationTarget.set(null);
|
teleportationTarget.set(null);
|
||||||
targetPortalId.set(Util.NIL_UUID);
|
targetPortalId.set(Optional.empty());
|
||||||
} else {
|
} else {
|
||||||
teleportationTarget.copyFrom(destination.entity);
|
teleportationTarget.copyFrom(destination.entity);
|
||||||
targetPortalId.set(destination.getSpellId());
|
targetPortalId.set(Optional.of(destination.getSpellId()));
|
||||||
targetPortalPitch.set(destination.getPitch());
|
targetPortalPitch.set(destination.getPitch());
|
||||||
targetPortalYaw.set(destination.getYaw());
|
targetPortalYaw.set(destination.getYaw());
|
||||||
}
|
}
|
||||||
|
@ -229,10 +228,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(NbtCompound compound, WrapperLookup lookup) {
|
public void toNBT(NbtCompound compound, WrapperLookup lookup) {
|
||||||
super.toNBT(compound, lookup);
|
super.toNBT(compound, lookup);
|
||||||
@Nullable UUID otherPortalUuid = targetPortalId.getOrDefault(Util.NIL_UUID);
|
targetPortalId.get().ifPresent(i -> compound.putUuid("targetPortalId", i));
|
||||||
if (!Util.NIL_UUID.equals(otherPortalUuid)) {
|
|
||||||
compound.putUuid("targetPortalId", otherPortalUuid);
|
|
||||||
}
|
|
||||||
compound.put("teleportationTarget", teleportationTarget.toNBT(lookup));
|
compound.put("teleportationTarget", teleportationTarget.toNBT(lookup));
|
||||||
compound.putFloat("pitch", getPitch());
|
compound.putFloat("pitch", getPitch());
|
||||||
compound.putFloat("yaw", getYaw());
|
compound.putFloat("yaw", getYaw());
|
||||||
|
@ -243,7 +239,7 @@ public class PortalSpell extends AbstractSpell implements PlacementControlSpell.
|
||||||
@Override
|
@Override
|
||||||
public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
|
public void fromNBT(NbtCompound compound, WrapperLookup lookup) {
|
||||||
super.fromNBT(compound, lookup);
|
super.fromNBT(compound, lookup);
|
||||||
targetPortalId.set(compound.containsUuid("targetPortalId") ? compound.getUuid("targetPortalId") : Util.NIL_UUID);
|
targetPortalId.set(compound.containsUuid("targetPortalId") ? Optional.of(compound.getUuid("targetPortalId")) : Optional.empty());
|
||||||
teleportationTarget.fromNBT(compound.getCompound("teleportationTarget"), lookup);
|
teleportationTarget.fromNBT(compound.getCompound("teleportationTarget"), lookup);
|
||||||
pitch.set(compound.getFloat("pitch"));
|
pitch.set(compound.getFloat("pitch"));
|
||||||
yaw.set(compound.getFloat("yaw"));
|
yaw.set(compound.getFloat("yaw"));
|
||||||
|
|
|
@ -42,10 +42,6 @@ public class PortalSpellRenderer extends SpellRenderer<PortalSpell> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fancy portal rendering is disabled for now
|
|
||||||
// Need to fix:
|
|
||||||
// 1. Transparent parts of the sky (because the game sets the clear to (0,0,0,0)
|
|
||||||
|
|
||||||
if (caster.asEntity().distanceTo(client.cameraEntity) > 50) {
|
if (caster.asEntity().distanceTo(client.cameraEntity) > 50) {
|
||||||
return; // don't bother rendering if too far away
|
return; // don't bother rendering if too far away
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,6 +74,7 @@ public class EntityReference<T extends Entity> implements NbtSerialisable, Track
|
||||||
public void copyFrom(EntityReference<? extends T> other) {
|
public void copyFrom(EntityReference<? extends T> other) {
|
||||||
this.reference = ((EntityReference<T>)other).reference;
|
this.reference = ((EntityReference<T>)other).reference;
|
||||||
this.directReference = new WeakReference<>(other.directReference.get());
|
this.directReference = new WeakReference<>(other.directReference.get());
|
||||||
|
dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean set(@Nullable T entity) {
|
public boolean set(@Nullable T entity) {
|
||||||
|
@ -128,7 +129,9 @@ public class EntityReference<T extends Entity> implements NbtSerialisable, Track
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void toNBT(NbtCompound tag, WrapperLookup lookup) {
|
public void toNBT(NbtCompound tag, WrapperLookup lookup) {
|
||||||
getTarget().ifPresent(ref -> EntityValues.CODEC.encode(ref, lookup.getOps(NbtOps.INSTANCE), tag));
|
getTarget().ifPresent(ref -> {
|
||||||
|
EntityValues.CODEC.encodeStart(lookup.getOps(NbtOps.INSTANCE), ref).result().ifPresent(nbt -> tag.copyFrom((NbtCompound)nbt));
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
|
@ -160,7 +163,10 @@ public class EntityReference<T extends Entity> implements NbtSerialisable, Track
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public NbtCompound writeTrackedNbt(WrapperLookup lookup) {
|
public NbtCompound writeTrackedNbt(WrapperLookup lookup) {
|
||||||
return toNBT(lookup);
|
return getTarget()
|
||||||
|
.flatMap(ref -> EntityValues.CODEC.encodeStart(lookup.getOps(NbtOps.INSTANCE), ref).result())
|
||||||
|
.map(NbtCompound.class::cast)
|
||||||
|
.orElseGet(NbtCompound::new);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -73,7 +73,6 @@ import net.minecraft.sound.BlockSoundGroup;
|
||||||
import net.minecraft.sound.SoundCategory;
|
import net.minecraft.sound.SoundCategory;
|
||||||
import net.minecraft.util.Hand;
|
import net.minecraft.util.Hand;
|
||||||
import net.minecraft.util.Identifier;
|
import net.minecraft.util.Identifier;
|
||||||
import net.minecraft.util.Util;
|
|
||||||
import net.minecraft.util.hit.BlockHitResult;
|
import net.minecraft.util.hit.BlockHitResult;
|
||||||
import net.minecraft.util.math.BlockPos;
|
import net.minecraft.util.math.BlockPos;
|
||||||
import net.minecraft.util.math.Direction;
|
import net.minecraft.util.math.Direction;
|
||||||
|
@ -110,7 +109,7 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
protected final DataTrackerManager trackers;
|
protected final DataTrackerManager trackers;
|
||||||
protected final DataTracker tracker;
|
protected final DataTracker tracker;
|
||||||
|
|
||||||
protected final DataTracker.Entry<UUID> carrierId;
|
protected final DataTracker.Entry<Optional<UUID>> carrierId;
|
||||||
|
|
||||||
protected Living(T entity) {
|
protected Living(T entity) {
|
||||||
this.entity = entity;
|
this.entity = entity;
|
||||||
|
@ -121,7 +120,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.UUID, Util.NIL_UUID);
|
carrierId = tracker.startTracking(TrackableDataType.UUID, Optional.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
public <Q extends Tickable> Q addTicker(Q tickable) {
|
public <Q extends Tickable> Q addTicker(Q tickable) {
|
||||||
|
@ -176,16 +175,15 @@ public abstract class Living<T extends LivingEntity> implements Equine<T>, Caste
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<UUID> getCarrierId() {
|
public Optional<UUID> getCarrierId() {
|
||||||
UUID carrierId = this.carrierId.get();
|
return carrierId.get();
|
||||||
return carrierId == Util.NIL_UUID ? Optional.empty() : Optional.of(carrierId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCarrier(UUID carrier) {
|
public void setCarrier(UUID carrier) {
|
||||||
carrierId.set(carrier == null ? Util.NIL_UUID : carrier);
|
carrierId.set(Optional.ofNullable(carrier));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCarrier(Entity carrier) {
|
public void setCarrier(Entity carrier) {
|
||||||
setCarrier(carrier == null ? Util.NIL_UUID : carrier.getUuid());
|
setCarrier(carrier == null ? null : carrier.getUuid());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|
|
@ -32,7 +32,7 @@ public record TrackableDataType<T>(int id, PacketCodec<RegistryByteBuf, TypedVal
|
||||||
public static final TrackableDataType<Integer> INT = of(Identifier.of("integer"), PacketCodecs.INTEGER);
|
public static final TrackableDataType<Integer> INT = of(Identifier.of("integer"), PacketCodecs.INTEGER);
|
||||||
public static final TrackableDataType<Float> FLOAT = of(Identifier.of("float"), PacketCodecs.FLOAT);
|
public static final TrackableDataType<Float> FLOAT = of(Identifier.of("float"), PacketCodecs.FLOAT);
|
||||||
public static final TrackableDataType<Boolean> BOOLEAN = of(Identifier.of("boolean"), PacketCodecs.BOOL);
|
public static final TrackableDataType<Boolean> BOOLEAN = of(Identifier.of("boolean"), PacketCodecs.BOOL);
|
||||||
public static final TrackableDataType<UUID> UUID = of(Identifier.of("uuid"), Uuids.PACKET_CODEC);
|
public static final TrackableDataType<Optional<UUID>> UUID = of(Identifier.of("uuid"), PacketCodecs.optional(Uuids.PACKET_CODEC));
|
||||||
public static final TrackableDataType<NbtCompound> NBT = of(Identifier.of("nbt"), PacketCodecs.NBT_COMPOUND);
|
public static final TrackableDataType<NbtCompound> NBT = of(Identifier.of("nbt"), PacketCodecs.NBT_COMPOUND);
|
||||||
public static final TrackableDataType<NbtCompound> COMPRESSED_NBT = of(Identifier.of("compressed_nbt"), PacketCodecs.NBT_COMPOUND);
|
public static final TrackableDataType<NbtCompound> COMPRESSED_NBT = of(Identifier.of("compressed_nbt"), PacketCodecs.NBT_COMPOUND);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue