Rewrite mindswap to better swap all the properties of players

This commit is contained in:
Sollace 2023-08-29 01:08:39 +01:00
parent b0c1c91c04
commit 9f7050ef28
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
2 changed files with 88 additions and 24 deletions

View file

@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.ability.magic.spell.HomingSpell;
import com.minelittlepony.unicopia.ability.magic.spell.Situation;
import com.minelittlepony.unicopia.ability.magic.spell.Spell;
import com.minelittlepony.unicopia.entity.EntityReference;
import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.behaviour.EntitySwap;
import com.minelittlepony.unicopia.entity.behaviour.Inventory;
import com.minelittlepony.unicopia.projectile.MagicProjectileEntity;
@ -18,7 +19,9 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.LivingEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtElement;
import net.minecraft.server.network.ServerPlayerEntity;
import net.minecraft.util.hit.EntityHitResult;
import net.minecraft.world.GameMode;
public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.EntityHitListener {
@ -43,8 +46,16 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
super.onDestroyed(caster);
if (initialized && !caster.isClient()) {
counterpart.ifPresent(caster.asWorld(), e -> {
initialized = false;
LivingEntity master = caster.getMaster();
Caster<?> other = Caster.of(e).get();
other.getSpellSlot().removeIf(SpellType.MIMIC, true);
caster.getSpellSlot().removeIf(getType(), true);
if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) {
swapPlayerData(sMaster, sE);
} else {
EntitySwap.ALL.accept(e, master);
Inventory.swapInventories(
e, myStoredInventory.or(() -> Inventory.of(e)),
@ -52,12 +63,10 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
a -> {},
a -> {}
);
}
Caster<?> other = Caster.of(e).get();
other.getSpellSlot().removeIf(SpellType.MIMIC, true);
other.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 1);
caster.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 1);
other.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 0.2F);
caster.playSound(USounds.SPELL_MINDSWAP_UNSWAP, 0.2F);
});
counterpart.set(null);
}
@ -72,8 +81,6 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
if (!caster.isClient()) {
if (!initialized) {
initialized = true;
setDirty();
counterpart.ifPresent(caster.asWorld(), e -> {
LivingEntity master = caster.getMaster();
@ -81,6 +88,9 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
Caster<?> other = Caster.of(e).get();
SpellType.MIMIC.withTraits().apply(other, CastingMethod.INDIRECT).setDisguise(master);
if (master instanceof ServerPlayerEntity sMaster && e instanceof ServerPlayerEntity sE) {
swapPlayerData(sMaster, sE);
} else {
EntitySwap.ALL.accept(master, e);
Inventory.swapInventories(
master, Inventory.of(master),
@ -88,18 +98,31 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
a -> myStoredInventory = Optional.of(a),
a -> theirStoredInventory = Optional.of(a)
);
}
other.playSound(USounds.SPELL_MINDSWAP_SWAP, 1);
caster.playSound(USounds.SPELL_MINDSWAP_SWAP, 1);
});
initialized = true;
setDirty();
}
if (counterpart.isSet() && counterpart.get(caster.asWorld()) == null) {
if (counterpart.isSet()) {
LivingEntity other = counterpart.get(caster.asWorld());
if (other == null) {
caster.getOriginatingCaster().asEntity().damage(caster.asWorld().getDamageSources().magic(), Float.MAX_VALUE);
setDead();
return false;
}
if (!Caster.of(other).get().getSpellSlot().contains(SpellType.MIMIC)) {
onDestroyed(caster);
setDead();
return false;
}
}
if (!caster.asEntity().isAlive()) {
counterpart.ifPresent(caster.asWorld(), e -> {
e.damage(e.getDamageSources().magic(), Float.MAX_VALUE);
@ -149,6 +172,48 @@ public class MindSwapSpell extends MimicSpell implements ProjectileDelegate.Enti
myStoredInventory = Optional.ofNullable(compound.contains("myStoredInventory", NbtElement.COMPOUND_TYPE) ? Inventory.fromNBT(compound.getCompound("myStoredInventory")) : null);
theirStoredInventory = Optional.ofNullable(compound.contains("theirStoredInventory", NbtElement.COMPOUND_TYPE) ? Inventory.fromNBT(compound.getCompound("theirStoredInventory")) : null);
}
private static void swapPlayerData(ServerPlayerEntity a, ServerPlayerEntity b) {
final GameMode aMode = a.interactionManager.getGameMode();
final GameMode bMode = b.interactionManager.getGameMode();
final ServerPlayerEntity aClone = clonePlayer(a);
final ServerPlayerEntity bClone = clonePlayer(b);
aClone.getAbilities().creativeMode = a.getAbilities().creativeMode;
bClone.getAbilities().creativeMode = b.getAbilities().creativeMode;
a.copyFrom(bClone, true);
b.copyFrom(aClone, true);
a.interactionManager.changeGameMode(aMode);
b.interactionManager.changeGameMode(bMode);
a.deathTime = 0;
b.deathTime = 0;
EntitySwap.POSITION.accept(a, b);
EntitySwap.VELOCITY.accept(a, b);
EntitySwap.PITCH.accept(a, b);
EntitySwap.YAW.accept(a, b);
a.sendAbilitiesUpdate();
b.sendAbilitiesUpdate();
Living.updateVelocity(a);
Living.updateVelocity(b);
}
private static ServerPlayerEntity clonePlayer(ServerPlayerEntity player) {
ServerPlayerEntity clone = new ServerPlayerEntity(player.getServer(), player.getServerWorld(), player.getGameProfile());
NbtCompound compound = player.writeNbt(new NbtCompound());
compound.remove("Dimension");
compound.getCompound("unicopia_caster").remove("spells");
clone.readNbt(compound);
return clone;
}
}

View file

@ -862,7 +862,6 @@ public class Pony extends Living<PlayerEntity> implements Copyable<Pony>, Update
}
}
oldPlayer.getSpellSlot().put(null);
setSpecies(oldPlayer.respawnRace != Race.UNSET && !alive ? oldPlayer.respawnRace : oldPlayer.getActualSpecies());
getDiscoveries().copyFrom(oldPlayer.getDiscoveries(), alive);
getPhysics().copyFrom(oldPlayer.getPhysics(), alive);