From 612a90681e16c718afeb6cb145db7c8e0c13ef68 Mon Sep 17 00:00:00 2001 From: Jonas Herzig Date: Sun, 15 Aug 2021 18:09:57 +0200 Subject: [PATCH] Reset camera inventory when no longer spectating (fixes #546) --- .../com/replaymod/core/versions/Patterns.java | 10 +++++ .../replaymod/replay/camera/CameraEntity.java | 39 +++++++++++++++++++ .../camera/SpectatorCameraController.java | 27 ------------- versions/1.11.2/mapping.txt | 1 + versions/1.14.4-forge/mapping.txt | 1 + 5 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/replaymod/core/versions/Patterns.java b/src/main/java/com/replaymod/core/versions/Patterns.java index 2de3d7b5..f7dee207 100644 --- a/src/main/java/com/replaymod/core/versions/Patterns.java +++ b/src/main/java/com/replaymod/core/versions/Patterns.java @@ -9,6 +9,7 @@ import net.minecraft.client.world.ClientWorld; import net.minecraft.client.render.Tessellator; import net.minecraft.client.render.entity.EntityRenderDispatcher; import net.minecraft.client.sound.PositionedSoundInstance; +import net.minecraft.entity.player.PlayerInventory; import net.minecraft.util.crash.CrashReportSection; import net.minecraft.entity.Entity; import net.minecraft.entity.player.PlayerEntity; @@ -215,6 +216,15 @@ class Patterns { //#endif } + @Pattern + private static PlayerInventory getInventory(PlayerEntity entity) { + //#if MC>=11700 + //$$ return entity.getInventory(); + //#else + return entity.inventory; + //#endif + } + @Pattern private static Iterable loadedEntityList(ClientWorld world) { //#if MC>=11400 diff --git a/src/main/java/com/replaymod/replay/camera/CameraEntity.java b/src/main/java/com/replaymod/replay/camera/CameraEntity.java index 973e4fbc..8cf54d2d 100644 --- a/src/main/java/com/replaymod/replay/camera/CameraEntity.java +++ b/src/main/java/com/replaymod/replay/camera/CameraEntity.java @@ -10,6 +10,7 @@ import com.replaymod.core.events.SettingsChangedCallback; import com.replaymod.replay.ReplayHandler; import com.replaymod.replay.events.RenderHotbarCallback; import com.replaymod.replay.events.RenderSpectatorCrosshairCallback; +import com.replaymod.replay.mixin.EntityPlayerAccessor; import de.johni0702.minecraft.gui.utils.EventRegistrations; import de.johni0702.minecraft.gui.versions.callbacks.PreTickCallback; import com.replaymod.core.utils.Utils; @@ -24,6 +25,7 @@ import net.minecraft.entity.Entity; import net.minecraft.entity.mob.MobEntity; import net.minecraft.entity.decoration.ItemFrameEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; import net.minecraft.item.ItemStack; import net.minecraft.stat.StatHandler; import net.minecraft.util.Identifier; @@ -618,6 +620,43 @@ public class CameraEntity //#if MC>=10800 this.noClip = this.isSpectator(); //#endif + + syncInventory(); + } + + private final PlayerInventory originalInventory = this.inventory; + + // If we are spectating a player, "steal" its inventory so the rendering code knows what item(s) to render + // and if we aren't, then reset ours. + private void syncInventory() { + Entity view = this.client.getCameraEntity(); + PlayerEntity viewPlayer = view != this && view instanceof PlayerEntity ? (PlayerEntity) view : null; + EntityPlayerAccessor cameraA = (EntityPlayerAccessor) this; + EntityPlayerAccessor viewPlayerA = (EntityPlayerAccessor) viewPlayer; + + //#if MC>=11100 + ItemStack empty = ItemStack.EMPTY; + //#else + //$$ ItemStack empty = null; + //#endif + + // TODO switch to replacing the entire inventory for 1.14+ as well, should be easier and faster + //#if MC>=11400 + this.equipStack(EquipmentSlot.HEAD, viewPlayer != null ? viewPlayer.getEquippedStack(EquipmentSlot.HEAD) : empty); + this.equipStack(EquipmentSlot.MAINHAND, viewPlayer != null ? viewPlayer.getEquippedStack(EquipmentSlot.MAINHAND) : empty); + this.equipStack(EquipmentSlot.OFFHAND, viewPlayer != null ? viewPlayer.getEquippedStack(EquipmentSlot.OFFHAND) : empty); + //#else + //$$ this.inventory = viewPlayer != null ? viewPlayer.inventory : originalInventory; + //#endif + + //#if MC>=10904 + cameraA.setItemStackMainHand(viewPlayerA != null ? viewPlayerA.getItemStackMainHand() : empty); + this.preferredHand = viewPlayer != null ? viewPlayer.preferredHand : Hand.MAIN_HAND; + cameraA.setActiveItemStackUseCount(viewPlayerA != null ? viewPlayerA.getActiveItemStackUseCount() : 0); + //#else + //$$ cameraA.setItemInUse(viewPlayerA != null ? viewPlayerA.getItemInUse() : empty); + //$$ cameraA.setItemInUseCount(viewPlayerA != null ? viewPlayerA.getItemInUseCount() : 0); + //#endif } private void handleInputEvents() { diff --git a/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java b/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java index 30a15018..3422a5de 100644 --- a/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java +++ b/src/main/java/com/replaymod/replay/camera/SpectatorCameraController.java @@ -1,15 +1,9 @@ package com.replaymod.replay.camera; import com.replaymod.replay.ReplayModReplay; -import com.replaymod.replay.mixin.EntityPlayerAccessor; import net.minecraft.client.MinecraftClient; import net.minecraft.client.options.KeyBinding; import net.minecraft.entity.Entity; -import net.minecraft.entity.player.PlayerEntity; - -//#if MC>=11400 -import net.minecraft.entity.EquipmentSlot; -//#endif //#if MC>=11400 //#else @@ -55,27 +49,6 @@ public class SpectatorCameraController implements CameraController { Entity view = mc.getCameraEntity(); if (view != null && view != camera) { camera.setCameraPosRot(mc.getCameraEntity()); - // If it's a player, also 'steal' its inventory so the rendering code knows what item to render - if (view instanceof PlayerEntity) { - PlayerEntity viewPlayer = (PlayerEntity) view; - //#if MC>=11400 - camera.equipStack(EquipmentSlot.HEAD, viewPlayer.getEquippedStack(EquipmentSlot.HEAD)); - camera.equipStack(EquipmentSlot.MAINHAND, viewPlayer.getEquippedStack(EquipmentSlot.MAINHAND)); - camera.equipStack(EquipmentSlot.OFFHAND, viewPlayer.getEquippedStack(EquipmentSlot.OFFHAND)); - //#else - //$$ camera.inventory = viewPlayer.inventory; - //#endif - EntityPlayerAccessor cameraA = (EntityPlayerAccessor) camera; - EntityPlayerAccessor viewPlayerA = (EntityPlayerAccessor) viewPlayer; - //#if MC>=10904 - cameraA.setItemStackMainHand(viewPlayerA.getItemStackMainHand()); - camera.preferredHand = viewPlayer.preferredHand; - cameraA.setActiveItemStackUseCount(viewPlayerA.getActiveItemStackUseCount()); - //#else - //$$ cameraA.setItemInUse(viewPlayerA.getItemInUse()); - //$$ cameraA.setItemInUseCount(viewPlayerA.getItemInUseCount()); - //#endif - } } } diff --git a/versions/1.11.2/mapping.txt b/versions/1.11.2/mapping.txt index e69de29b..7f741972 100644 --- a/versions/1.11.2/mapping.txt +++ b/versions/1.11.2/mapping.txt @@ -0,0 +1 @@ +net.minecraft.item.ItemStack EMPTY field_190927_a diff --git a/versions/1.14.4-forge/mapping.txt b/versions/1.14.4-forge/mapping.txt index d57a46f3..f858f3e5 100644 --- a/versions/1.14.4-forge/mapping.txt +++ b/versions/1.14.4-forge/mapping.txt @@ -1,3 +1,4 @@ +net.minecraft.entity.player.PlayerInventory net.minecraft.entity.player.InventoryPlayer net.minecraft.potion.EffectInstance net.minecraft.potion.PotionEffect net.minecraft.client.gui.screen.AddServerScreen net.minecraft.client.gui.GuiScreenAddServer net.minecraft.resources.AbstractResourcePack net.minecraft.client.resources.AbstractResourcePack