From d9682921d15bf125fee9f7e79da1aa6b13ddbad3 Mon Sep 17 00:00:00 2001 From: Ethan Moffat Date: Mon, 19 Sep 2022 13:44:00 -0700 Subject: [PATCH] Fix mouseover check for irregularly sized NPC texture sets. Fixes bug where mouseover would cause crash when standing frame was sized differently than different direction frames. --- EndlessClient/Rendering/NPC/NPCRenderer.cs | 28 ++++++++++++---------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/EndlessClient/Rendering/NPC/NPCRenderer.cs b/EndlessClient/Rendering/NPC/NPCRenderer.cs index 404f35074..e30ca5b3f 100644 --- a/EndlessClient/Rendering/NPC/NPCRenderer.cs +++ b/EndlessClient/Rendering/NPC/NPCRenderer.cs @@ -41,7 +41,6 @@ public class NPCRenderer : DrawableGameComponent, INPCRenderer private readonly IUserInputProvider _userInputProvider; private readonly ISpellSlotDataProvider _spellSlotDataProvider; private readonly ISfxPlayer _sfxPlayer; - private readonly Rectangle _baseTextureFrameRectangle; private readonly int _readonlyTopPixel, _readonlyBottomPixel; private readonly bool _hasStandingAnimation; private readonly IEffectRenderer _effectRenderer; @@ -106,7 +105,7 @@ public class NPCRenderer : DrawableGameComponent, INPCRenderer _spellSlotDataProvider = spellSlotDataProvider; _sfxPlayer = sfxPlayer; - _baseTextureFrameRectangle = GetStandingFrameRectangle(); + DrawArea = GetStandingFrameRectangle(); _readonlyTopPixel = GetTopPixel(); _readonlyBottomPixel = GetBottomPixel(); @@ -151,15 +150,15 @@ public override void Update(GameTime gameTime) UpdateStandingFrameAnimation(); UpdateDeadState(); - var currentMousePosition = _userInputProvider.CurrentMouseState.Position; - if (DrawArea.Contains(currentMousePosition)) + var currentMousePosition = _userInputProvider.CurrentMouseState.Position - DrawArea.Location; + var currentFrame = _npcSpriteSheet.GetNPCTexture(_enfFileProvider.ENFFile[NPC.ID].Graphic, NPC.Frame, NPC.Direction); + + if (currentFrame.Bounds.Contains(currentMousePosition)) { var colorData = new Color[1]; - var textureCoord = (currentMousePosition - DrawArea.Location); - _npcSpriteSheet.GetNPCTexture(_enfFileProvider.ENFFile[NPC.ID].Graphic, NPC.Frame, NPC.Direction) - .GetData(0, new Rectangle(textureCoord.X, textureCoord.Y, 1, 1), colorData, 0, 1); + currentFrame.GetData(0, new Rectangle(currentMousePosition.X, currentMousePosition.Y, 1, 1), colorData, 0, 1); - _nameLabel.Visible = DrawArea.Contains(currentMousePosition) && !_healthBarRenderer.Visible && !_isDying && (_isBlankSprite || colorData[0].A > 0); + _nameLabel.Visible = !_healthBarRenderer.Visible && !_isDying && (_isBlankSprite || colorData[0].A > 0); _nameLabel.DrawPosition = GetNameLabelPosition(); if (!_userInputProvider.ClickHandled && @@ -302,18 +301,21 @@ private void UpdateDrawAreas() var mainOffsetX = _renderOffsetCalculator.CalculateOffsetX(mainRenderer.Character.RenderProperties); var mainOffsetY = _renderOffsetCalculator.CalculateOffsetY(mainRenderer.Character.RenderProperties); + var data = _enfFileProvider.ENFFile[NPC.ID]; + var frameTexture = _npcSpriteSheet.GetNPCTexture(data.Graphic, NPCFrame.StandingFrame1, NPC.Direction); + // Some NPCs have an off-center sprite that needs to be divided by 3 (normal sprites are centered properly) // If e.g. Apozen is facing Down or Left it needs to be offset by 2/3 the sprite width instead of 1/3 the sprite width var widthFactor = _npcsThatAreNotCentered.Contains(NPC.ID) ? NPC.IsFacing(EODirection.Down, EODirection.Left) - ? (_baseTextureFrameRectangle.Width * 2) / 3 - : _baseTextureFrameRectangle.Width / 3 - : _baseTextureFrameRectangle.Width / 2; + ? (frameTexture.Width * 2) / 3 + : frameTexture.Width / 3 + : frameTexture.Width / 2; // y coordinate Formula courtesy of Apollo var xCoord = offsetX + 320 - mainOffsetX - widthFactor; - var yCoord = (Math.Min(41, _baseTextureFrameRectangle.Width - 23) / 4) + offsetY + 168 - mainOffsetY - _baseTextureFrameRectangle.Height; - DrawArea = _baseTextureFrameRectangle.WithPosition(new Vector2(xCoord, yCoord)); + var yCoord = (Math.Min(41, frameTexture.Width - 23) / 4) + offsetY + 168 - mainOffsetY - frameTexture.Height; + DrawArea = frameTexture.Bounds.WithPosition(new Vector2(xCoord, yCoord)); var oneGridSize = new Vector2(mainRenderer.DrawArea.Width, mainRenderer.DrawArea.Height);