mirror of
https://github.com/Sollace/Unicopia.git
synced 2024-11-23 21:38:00 +01:00
Fixed data not being copied when the player changes dimensions
This commit is contained in:
parent
6057d8ea3b
commit
e9114f9e12
10 changed files with 101 additions and 20 deletions
|
@ -7,6 +7,7 @@ import org.jetbrains.annotations.Nullable;
|
|||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.SpellReference;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.network.track.ObjectTracker;
|
||||
import com.minelittlepony.unicopia.network.track.Trackable;
|
||||
import com.minelittlepony.unicopia.network.track.TrackableObject;
|
||||
|
@ -128,4 +129,13 @@ class MultiSpellSlot implements SpellSlots, NbtSerialisable {
|
|||
spell.fromNBT(compound);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(SpellSlots other, boolean alive) {
|
||||
if (alive) {
|
||||
other.stream().forEach(this::put);
|
||||
} else {
|
||||
other.stream().filter(SpellType.PLACE_CONTROL_SPELL).forEach(this::put);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,4 +65,9 @@ class SingleSpellSlot implements SpellSlots, NbtSerialisable {
|
|||
public void fromNBT(NbtCompound compound) {
|
||||
entry.readTrackedNbt(compound.getCompound("effect"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(SpellSlots other, boolean alive) {
|
||||
other.get().ifPresent(this::put);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,9 +7,10 @@ import java.util.stream.Stream;
|
|||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
|
||||
import com.minelittlepony.unicopia.util.Copyable;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
public interface SpellSlots extends NbtSerialisable {
|
||||
public interface SpellSlots extends NbtSerialisable, Copyable<SpellSlots> {
|
||||
static SpellInventory ofUnbounded(Caster<?> caster) {
|
||||
return new SpellInventory(caster, new MultiSpellSlot(caster));
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import com.minelittlepony.unicopia.USounds;
|
|||
import com.minelittlepony.unicopia.ability.magic.spell.effect.CustomisedSpellType;
|
||||
import com.minelittlepony.unicopia.ability.magic.spell.effect.SpellType;
|
||||
import com.minelittlepony.unicopia.item.EnchantableItem;
|
||||
import com.minelittlepony.unicopia.util.Copyable;
|
||||
import com.minelittlepony.unicopia.util.NbtSerialisable;
|
||||
|
||||
import net.minecraft.nbt.NbtCompound;
|
||||
|
@ -15,7 +16,7 @@ import net.minecraft.nbt.NbtList;
|
|||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.TypedActionResult;
|
||||
|
||||
public class PlayerCharmTracker implements NbtSerialisable {
|
||||
public class PlayerCharmTracker implements NbtSerialisable, Copyable<PlayerCharmTracker> {
|
||||
|
||||
private final Pony pony;
|
||||
|
||||
|
@ -62,6 +63,13 @@ public class PlayerCharmTracker implements NbtSerialisable {
|
|||
return previous;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void copyFrom(PlayerCharmTracker old, boolean alive) {
|
||||
for (int i = 0; i < handSpells.length; i++) {
|
||||
handSpells[i] = old.handSpells[i];
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
NbtList equippedSpells = new NbtList();
|
||||
|
|
|
@ -63,7 +63,6 @@ import net.minecraft.server.world.ServerWorld;
|
|||
import net.minecraft.sound.SoundEvents;
|
||||
import net.minecraft.text.Text;
|
||||
import net.minecraft.util.ActionResult;
|
||||
import net.minecraft.util.Hand;
|
||||
import net.minecraft.util.math.*;
|
||||
import net.minecraft.world.GameMode;
|
||||
import net.minecraft.world.GameRules;
|
||||
|
@ -116,6 +115,7 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
sender.accept(Channel.SERVER_PLAYER_CAPABILITIES.toPacket(new MsgPlayerCapabilities(this)));
|
||||
}
|
||||
});
|
||||
|
||||
race = this.tracker.startTracking(Race.TRACKABLE_TYPE, Race.UNSET);
|
||||
suppressedRace = this.tracker.startTracking(Race.TRACKABLE_TYPE, Race.UNSET);
|
||||
this.levels = new PlayerLevelStore(this, tracker, true, USounds.Vanilla.ENTITY_PLAYER_LEVELUP);
|
||||
|
@ -817,8 +817,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
@Override
|
||||
public void toNBT(NbtCompound compound) {
|
||||
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
|
||||
compound.putString("suppressedSpecies", Race.REGISTRY.getId(getSuppressedRace()).toString());
|
||||
compound.put("mana", mana.toNBT());
|
||||
compound.putInt("levels", levels.get());
|
||||
compound.putInt("corruption", corruption.get());
|
||||
|
@ -827,8 +825,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
@Override
|
||||
public void fromNBT(NbtCompound compound) {
|
||||
setSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN));
|
||||
setSuppressedRace(Race.fromName(compound.getString("suppressedSpecies"), Race.UNSET));
|
||||
levels.set(compound.getInt("levels"));
|
||||
corruption.set(compound.getInt("corruption"));
|
||||
mana.fromNBT(compound.getCompound("mana"));
|
||||
|
@ -837,7 +833,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
@Override
|
||||
public void toSyncronisedNbt(NbtCompound compound) {
|
||||
System.out.println("toSyncNbt");
|
||||
super.toSyncronisedNbt(compound);
|
||||
compound.putString("playerSpecies", Race.REGISTRY.getId(getSpecies()).toString());
|
||||
compound.putString("suppressedSpecies", Race.REGISTRY.getId(getSuppressedRace()).toString());
|
||||
compound.putFloat("magicExhaustion", magicExhaustion);
|
||||
compound.putInt("ticksInSun", ticksInSun);
|
||||
compound.putBoolean("hasShades", hasShades);
|
||||
|
@ -857,7 +856,10 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
@Override
|
||||
public void fromSynchronizedNbt(NbtCompound compound) {
|
||||
System.out.println("fromSyncNbt");
|
||||
super.fromSynchronizedNbt(compound);
|
||||
setSpecies(Race.fromName(compound.getString("playerSpecies"), Race.HUMAN));
|
||||
setSuppressedRace(Race.fromName(compound.getString("suppressedSpecies"), Race.UNSET));
|
||||
powers.fromNBT(compound.getCompound("powers"));
|
||||
gravity.fromNBT(compound.getCompound("gravity"));
|
||||
charms.fromNBT(compound.getCompound("charms"));
|
||||
|
@ -877,7 +879,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|
||||
@Override
|
||||
public void copyFrom(Pony oldPlayer, boolean alive) {
|
||||
|
||||
boolean forcedSwap = (!alive
|
||||
&& entity instanceof ServerPlayerEntity
|
||||
&& entity.getWorld().getGameRules().getBoolean(UGameRules.SWAP_TRIBE_ON_DEATH)
|
||||
|
@ -885,17 +886,20 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
|| oldPlayer.getSpecies().isUnset();
|
||||
|
||||
Race oldSuppressedRace = oldPlayer.getSuppressedRace();
|
||||
Race newRace = oldPlayer.respawnRace != Race.UNSET && !alive ? oldPlayer.respawnRace : oldPlayer.getSpecies();
|
||||
|
||||
if (alive) {
|
||||
oldPlayer.getSpellSlot().stream().forEach(getSpellSlot()::put);
|
||||
if (forcedSwap || !newRace.canCast()) {
|
||||
getSpellSlot().clear();
|
||||
} else {
|
||||
getSpellSlot().copyFrom(oldPlayer.getSpellSlot(), alive);
|
||||
}
|
||||
|
||||
if (forcedSwap) {
|
||||
oldSuppressedRace = Race.UNSET;
|
||||
Channel.SERVER_SELECT_TRIBE.sendToPlayer(new MsgTribeSelect(Race.allPermitted(entity), "gui.unicopia.tribe_selection.respawn"), (ServerPlayerEntity)entity);
|
||||
} else {
|
||||
oldPlayer.getSpellSlot().stream().filter(SpellType.PLACE_CONTROL_SPELL).forEach(getSpellSlot()::put);
|
||||
}
|
||||
|
||||
if (!alive) {
|
||||
// putting it here instead of adding another injection point into ServerPlayerEntity.copyFrom()
|
||||
if (!asWorld().getGameRules().getBoolean(GameRules.KEEP_INVENTORY)) {
|
||||
PlayerInventory inventory = oldPlayer.asEntity().getInventory();
|
||||
|
@ -908,14 +912,13 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
|
|||
}
|
||||
}
|
||||
|
||||
setSpecies(oldPlayer.respawnRace != Race.UNSET && !alive ? oldPlayer.respawnRace : oldPlayer.getSpecies());
|
||||
setSpecies(newRace);
|
||||
setSuppressedRace(oldSuppressedRace);
|
||||
getDiscoveries().copyFrom(oldPlayer.getDiscoveries(), alive);
|
||||
getPhysics().copyFrom(oldPlayer.getPhysics(), alive);
|
||||
if (!forcedSwap) {
|
||||
getArmour().copyFrom(oldPlayer.getArmour(), alive);
|
||||
getCharms().equipSpell(Hand.MAIN_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.MAIN_HAND));
|
||||
getCharms().equipSpell(Hand.OFF_HAND, oldPlayer.getCharms().getEquippedSpell(Hand.OFF_HAND));
|
||||
getCharms().copyFrom(oldPlayer.getCharms(), alive);
|
||||
corruption.set(oldPlayer.getCorruption().get());
|
||||
levels.set(oldPlayer.getLevel().get());
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.minelittlepony.unicopia.mixin.client;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.spongepowered.asm.mixin.Final;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
|
@ -10,13 +12,19 @@ import com.minelittlepony.unicopia.ability.magic.SpellPredicate;
|
|||
import com.minelittlepony.unicopia.entity.Living;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.Disguise;
|
||||
import com.minelittlepony.unicopia.entity.behaviour.EntityAppearance;
|
||||
import com.minelittlepony.unicopia.entity.player.Pony;
|
||||
import com.minelittlepony.unicopia.network.track.Trackable;
|
||||
|
||||
import net.minecraft.client.MinecraftClient;
|
||||
import net.minecraft.client.network.ClientPlayNetworkHandler;
|
||||
import net.minecraft.client.network.ClientPlayerEntity;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket;
|
||||
import net.minecraft.network.packet.s2c.play.PlayerRespawnS2CPacket;
|
||||
|
||||
@Mixin(ClientPlayNetworkHandler.class)
|
||||
abstract class MixinClientPlayNetworkHandler {
|
||||
@Shadow private @Final MinecraftClient client;
|
||||
@Shadow private ClientWorld world;
|
||||
|
||||
@Inject(method = "onEntityStatus", at = @At("TAIL"))
|
||||
|
@ -32,4 +40,20 @@ abstract class MixinClientPlayNetworkHandler {
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private ClientPlayerEntity oldPlayer;
|
||||
|
||||
@Inject(method = "onPlayerRespawn", at = @At("HEAD"))
|
||||
public void beforeOnPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo info) {
|
||||
oldPlayer = client.player;
|
||||
}
|
||||
|
||||
@Inject(method = "onPlayerRespawn", at = @At("RETURN"))
|
||||
public void afterOnPlayerRespawn(PlayerRespawnS2CPacket packet, CallbackInfo info) {
|
||||
if (oldPlayer != null && oldPlayer != client.player) {
|
||||
Trackable.of(oldPlayer).getDataTrackers().copyTo(Trackable.of(client.player).getDataTrackers());
|
||||
Pony.of(client.player).copyFrom(Pony.of(oldPlayer), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@ abstract class MixinServerPlayNetworkHandler implements EntityTrackingListener,
|
|||
}
|
||||
|
||||
@Inject(method = "tick()V", at = @At("HEAD"))
|
||||
private void beforePlayerTick() {
|
||||
private void beforePlayerTick(CallbackInfo info) {
|
||||
if (Pony.of(player).getPhysics().isFlyingSurvival) {
|
||||
floating = false;
|
||||
floatingTicks = 0;
|
||||
|
|
|
@ -75,6 +75,17 @@ public class DataTracker {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
synchronized void copyTo(DataTracker destination) {
|
||||
for (int i = 0; i < codecs.size(); i++) {
|
||||
((Pair<Object>)destination.codecs.get(i)).value = codecs.get(i).value;
|
||||
TrackableObject o = destination.persistentObjects.get(i);
|
||||
if (o != null) {
|
||||
o.readTrackedNbt((NbtCompound)codecs.get(i).value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized Optional<MsgTrackedValues.TrackerEntries> getInitialPairs() {
|
||||
initial = false;
|
||||
dirtyIndices = new IntOpenHashSet();
|
||||
|
|
|
@ -80,6 +80,16 @@ public class DataTrackerManager {
|
|||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public synchronized void copyTo(DataTrackerManager destination) {
|
||||
for (int i = 0; i < trackers.size(); i++) {
|
||||
trackers.get(i).copyTo(i >= destination.trackers.size() ? destination.checkoutTracker() : destination.trackers.get(i));
|
||||
}
|
||||
for (int i = 0; i < objectTrackers.size(); i++) {
|
||||
((ObjectTracker)objectTrackers.get(i)).copyTo(destination.objectTrackers.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
public synchronized void sendInitial(ServerPlayerEntity player, Consumer<Packet<ClientPlayPacketListener>> sender) {
|
||||
synchronized (this) {
|
||||
|
|
|
@ -73,6 +73,15 @@ public class ObjectTracker<T extends TrackableObject> implements NbtSerialisable
|
|||
quickAccess = Map.copyOf(trackedObjects);
|
||||
}
|
||||
|
||||
synchronized void copyTo(ObjectTracker<T> destination) {
|
||||
for (var entry : trackedObjects.entrySet()) {
|
||||
T copy = destination.constructor.get();
|
||||
copy.readTrackedNbt(entry.getValue().toTrackedNbt());
|
||||
destination.trackedObjects.put(entry.getKey(), copy);
|
||||
}
|
||||
destination.quickAccess = Map.copyOf(destination.trackedObjects);
|
||||
}
|
||||
|
||||
synchronized Optional<MsgTrackedValues.TrackerObjects> getInitialPairs() {
|
||||
if (trackedObjects.isEmpty()) {
|
||||
return Optional.empty();
|
||||
|
|
Loading…
Reference in a new issue