Fixed shapeshifting and fixed disguise entities not playing animations

This commit is contained in:
Sollace 2024-02-12 13:14:29 +00:00
parent 46dcf0802b
commit ae5464b758
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
9 changed files with 71 additions and 4 deletions

View file

@ -50,6 +50,10 @@ public final class SpellReference<T extends Spell> implements NbtSerialisable {
@Override @Override
public void fromNBT(NbtCompound compound) { public void fromNBT(NbtCompound compound) {
fromNBT(compound, true);
}
public void fromNBT(NbtCompound compound, boolean force) {
final int hash = compound.hashCode(); final int hash = compound.hashCode();
if (nbtHash == hash) { if (nbtHash == hash) {
return; return;
@ -58,7 +62,7 @@ public final class SpellReference<T extends Spell> implements NbtSerialisable {
if (spell == null || !Objects.equals(Spell.getUuid(compound), spell.getUuid())) { if (spell == null || !Objects.equals(Spell.getUuid(compound), spell.getUuid())) {
spell = Spell.readNbt(compound); spell = Spell.readNbt(compound);
} else { } else if (force || !spell.isDirty()) {
spell.fromNBT(compound); spell.fromNBT(compound);
} }
} }

View file

@ -51,7 +51,7 @@ public class ShieldSpellRenderer extends SpellRenderer<ShieldSpell> {
model.render(matrices, buffer, light, 1, radius, colors[0], colors[1], colors[2], alpha * 0.2F); model.render(matrices, buffer, light, 1, radius, colors[0], colors[1], colors[2], alpha * 0.2F);
} else { } else {
matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180)); matrices.multiply(RotationAxis.POSITIVE_X.rotationDegrees(180));
matrices.scale(1, radius == 0 ? 1 : 2.6F / radius, 1); matrices.scale(1, radius == 0 ? 1 : MathHelper.clamp(2.6F / radius, 0.7F, 1), 1);
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness, colors[0], colors[1], colors[2], alpha * 0.08F); SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness, colors[0], colors[1], colors[2], alpha * 0.08F);
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius - thickness, colors[0], colors[1], colors[2], alpha * 0.05F); SphereModel.SPHERE.render(matrices, buffer, light, 1, radius - thickness, colors[0], colors[1], colors[2], alpha * 0.05F);
SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness * 2, colors[0], colors[1], colors[2], alpha * 0.05F); SphereModel.SPHERE.render(matrices, buffer, light, 1, radius + thickness * 2, colors[0], colors[1], colors[2], alpha * 0.05F);

View file

@ -9,6 +9,7 @@ import com.minelittlepony.unicopia.Owned;
import com.minelittlepony.unicopia.ability.magic.Caster; import com.minelittlepony.unicopia.ability.magic.Caster;
import com.minelittlepony.unicopia.entity.Living; import com.minelittlepony.unicopia.entity.Living;
import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck; import com.minelittlepony.unicopia.entity.duck.LivingEntityDuck;
import com.minelittlepony.unicopia.entity.duck.RotatedView;
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;
@ -100,7 +101,14 @@ public interface Disguise extends FlightType.Provider, PlayerDimensions.Provider
behaviour.copyBaseAttributes(owner, entity); behaviour.copyBaseAttributes(owner, entity);
if (tick && !getDisguise().skipsUpdate()) { if (tick && !getDisguise().skipsUpdate()) {
entity.tick(); ((RotatedView)entity.getWorld()).setMirrorEntityStatuses(entity.getWorld().isClient);
if (entity.getWorld().isClient) {
entity.tick();
} else {
entity.tick();
}
((RotatedView)entity.getWorld()).setMirrorEntityStatuses(false);
} }
if (!(owner instanceof PlayerEntity) && !((LivingEntityDuck)owner).isJumping()) { if (!(owner instanceof PlayerEntity) && !((LivingEntityDuck)owner).isJumping()) {

View file

@ -211,6 +211,8 @@ public class EntityAppearance implements NbtSerialisable, PlayerDimensions.Provi
if (source.isClient()) { if (source.isClient()) {
source.asWorld().spawnEntity(entity); source.asWorld().spawnEntity(entity);
} else {
entity.setId(source.asEntity().getId());
} }
} }

View file

@ -10,6 +10,8 @@ public interface RotatedView {
boolean hasTransform(); boolean hasTransform();
void setMirrorEntityStatuses(boolean enable);
default void pushRotation(int y) { default void pushRotation(int y) {
getRotations().add(y); getRotations().add(y);
} }

View file

@ -6,11 +6,13 @@ import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.ModifyVariable; import org.spongepowered.asm.mixin.injection.ModifyVariable;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import com.minelittlepony.unicopia.entity.duck.RotatedView; import com.minelittlepony.unicopia.entity.duck.RotatedView;
import com.minelittlepony.unicopia.server.world.BlockDestructionManager; import com.minelittlepony.unicopia.server.world.BlockDestructionManager;
import net.minecraft.block.BlockState; import net.minecraft.block.BlockState;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldAccess; import net.minecraft.world.WorldAccess;
@ -22,6 +24,7 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source
private int recurseCount = 0; private int recurseCount = 0;
private final Stack<Integer> rotations = new Stack<>(); private final Stack<Integer> rotations = new Stack<>();
private boolean mirrorEntityStatuses;
@Override @Override
public Stack<Integer> getRotations() { public Stack<Integer> getRotations() {
@ -33,11 +36,23 @@ abstract class MixinWorld implements WorldAccess, BlockDestructionManager.Source
return recurseCount <= 0; return recurseCount <= 0;
} }
@Override
public void setMirrorEntityStatuses(boolean enable) {
mirrorEntityStatuses = enable;
}
@Override @Override
public BlockDestructionManager getDestructionManager() { public BlockDestructionManager getDestructionManager() {
return destructions.get(); return destructions.get();
} }
@Inject(method = "sendEntityStatus(Lnet/minecraft/entity/Entity;B)V", at = @At("HEAD"))
private void onSendEntityStatus(Entity entity, byte status, CallbackInfo info) {
if (mirrorEntityStatuses) {
entity.handleStatus(status);
}
}
@ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD")) @ModifyVariable(method = "setBlockState(Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/block/BlockState;II)Z", at = @At("HEAD"))
private BlockPos modifyBlockPos(BlockPos pos) { private BlockPos modifyBlockPos(BlockPos pos) {
pos = applyRotation(pos); pos = applyRotation(pos);

View file

@ -0,0 +1,35 @@
package com.minelittlepony.unicopia.mixin.client;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
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 net.minecraft.client.network.ClientPlayNetworkHandler;
import net.minecraft.client.world.ClientWorld;
import net.minecraft.network.packet.s2c.play.EntityStatusS2CPacket;
@Mixin(ClientPlayNetworkHandler.class)
abstract class MixinClientPlayNetworkHandler {
@Shadow private ClientWorld world;
@Inject(method = "onEntityStatus", at = @At("TAIL"))
private void onOnEntityStatus(EntityStatusS2CPacket packet, CallbackInfo info) {
Living<?> living = Living.living(packet.getEntity(world));
if (living != null) {
living.getSpellSlot()
.get(SpellPredicate.IS_DISGUISE, false)
.map(Disguise::getDisguise)
.map(EntityAppearance::getAppearance)
.ifPresent(appearance -> {
appearance.handleStatus(packet.getStatus());
});
}
}
}

View file

@ -31,7 +31,7 @@ public class SpellNetworkedReference<T extends Spell> implements NetworkedRefere
@Override @Override
public boolean fromNbt(NbtCompound comp) { public boolean fromNbt(NbtCompound comp) {
dirty = false; dirty = false;
currentValue.fromNBT(comp); currentValue.fromNBT(comp, owner.isClient());
return isDirty(); return isDirty();
} }

View file

@ -67,6 +67,7 @@
"client.MixinBackgroundRenderer", "client.MixinBackgroundRenderer",
"client.MixinCamera", "client.MixinCamera",
"client.MixinClientWorld", "client.MixinClientWorld",
"client.MixinClientPlayNetworkHandler",
"client.MixinEntityRenderDispatcher", "client.MixinEntityRenderDispatcher",
"client.MixinGameRenderer", "client.MixinGameRenderer",
"client.MixinHeldItemRenderer", "client.MixinHeldItemRenderer",