LADXHD/InGame/Overlay/InventoryOverlay.cs
2023-12-14 17:21:22 -05:00

503 lines
23 KiB
C#

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using ProjectZ.InGame.Controls;
using ProjectZ.InGame.SaveLoad;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.Overlay
{
class InventoryOverlay
{
private const int Margin = 6;
private RenderTarget2D _renderTarget;
private readonly Rectangle _background0 = new Rectangle(0, 0, 268, 24);
private readonly Rectangle _background1 = new Rectangle(0, 26, 268, 182);
private readonly Rectangle _keyRectangle = new Rectangle(94, 6, 20, 114);
private readonly Rectangle[] _keyPositions = new Rectangle[5];
private readonly Rectangle _relictsRectangle = new Rectangle(118, 6, 144, 22);
private readonly Point _relictPosition = new Point(123, 9);
private readonly Rectangle[] _relicOffsets = new Rectangle[8];
private readonly DictAtlasEntry[] _ocarinaFaces = new DictAtlasEntry[3];
private readonly Point _heartsPosition = new Point(6, 5);
private readonly Point _rubeePosition;
private readonly Rectangle _flipperRectangle;
private readonly Rectangle _potionRectangle;
private readonly Rectangle _tradeStuffRectangle = new Rectangle(6, 6, 84, 22);
private Rectangle _tradeRectangle;
private Rectangle _shellRectangle;
private Rectangle _leafRectangle;
private readonly Point _skirtPosition;
private readonly Point _heartPiecePosition;
private readonly Point _itemSlotsPosition = new Point(14, 41);
private readonly Rectangle _skirtRectangle = new Rectangle(180, 31, 16, 15);
private readonly Rectangle _skirtColorRectangle = new Rectangle(198, 37, 14, 10);
private readonly Rectangle _heartPiecesRectangle = new Rectangle(4, 72, 16, 14);
private const int ItemSlotWidth = 4;
public static Rectangle RecItemselection = new Rectangle(0, 0, 30, 20);
public const int DistX = 8;
public const int DistY = 5;
private static string[] _itemSlotString = new[] { "A", "B", "X", "Y" };
// 3
// 2 1
// 0
private static Rectangle[] _itemSlots = {
new Rectangle(RecItemselection.Width + DistX / 2 - RecItemselection.Width / 2,
RecItemselection.Height * 2 + DistY * 2,
RecItemselection.Width, RecItemselection.Height),
new Rectangle(RecItemselection.Width + DistX, RecItemselection.Height + DistY,
RecItemselection.Width, RecItemselection.Height),
new Rectangle(0, RecItemselection.Height + DistY,
RecItemselection.Width, RecItemselection.Height),
new Rectangle(RecItemselection.Width + DistX / 2 - RecItemselection.Width / 2, 0,
RecItemselection.Width, RecItemselection.Height)
};
private int _selectedItemSlot;
private readonly Point _itemRectangleSize = new Point(27, 26);
private readonly Point _itemRecMargin = new Point(0, 0);
private readonly Point _equipmentPosition = new Point(6, 123);
private readonly Rectangle _itemsRectangle = new Rectangle(6, 124, 108, 52);
private readonly int _width;
private readonly int _height;
private float _selectionCounter;
private const int SelectionTime = 125;
private bool _selectionButtonPressed;
public InventoryOverlay(int width, int height)
{
_width = width;
_height = height;
_rubeePosition = new Point(width - ItemDrawHelper.RubeeSize.X - Margin, 10);
var blockPosition = 97;
_skirtPosition = new Point(blockPosition, 5);
_heartPiecePosition = new Point(blockPosition += 34, 6);
_flipperRectangle = new Rectangle(blockPosition += 18, 0, 12, _background0.Height);
_potionRectangle = new Rectangle(blockPosition += 12, 0, 12, _background0.Height);
// key positions
for (var i = 0; i < 5; i++)
_keyPositions[i] = new Rectangle(96, 12 + i * 21, 16, 16);
// relict positions
for (var i = 0; i < 8; i++)
_relicOffsets[i] = new Rectangle(i * 17, 0, 16, 16);
_ocarinaFaces[0] = Resources.GetSprite("ocarina1");
_ocarinaFaces[1] = Resources.GetSprite("ocarina2");
_ocarinaFaces[2] = Resources.GetSprite("ocarina3");
}
public void UpdateRenderTarget()
{
if (_renderTarget == null || _renderTarget.Width != _width * Game1.UiScale || _renderTarget.Height != _height * Game1.UiScale)
_renderTarget = new RenderTarget2D(Game1.Graphics.GraphicsDevice, _width * Game1.UiScale, _height * Game1.UiScale);
}
public void UpdateMenu()
{
for (var i = 0; i < 4; i++)
{
if (ControlHandler.ButtonPressed((CButtons)((int)CButtons.A * Math.Pow(2, i))))
{
Game1.GameManager.PlaySoundEffect("D360-19-13");
Game1.GameManager.ChangeItem(i, _selectedItemSlot + Values.HandItemSlots);
}
}
var selectionOffset = 0;
var direction = ControlHandler.GetMoveVector2();
if (direction.Length() > Values.ControllerDeadzone)
{
_selectionCounter -= Game1.DeltaTime;
if (_selectionCounter <= 0 || !_selectionButtonPressed)
{
_selectionCounter += SelectionTime;
var dir = AnimationHelper.GetDirection(direction);
if (dir == 0)
selectionOffset -= 1;
else if (dir == 1)
selectionOffset -= ItemSlotWidth;
else if (dir == 2)
selectionOffset += 1;
else if (dir == 3)
selectionOffset += ItemSlotWidth;
}
_selectionButtonPressed = true;
}
else
{
_selectionButtonPressed = false;
_selectionCounter = SelectionTime;
}
// update the selected ocarina song
var selectedItem = Game1.GameManager.Equipment[Values.HandItemSlots + _selectedItemSlot];
if (selectedItem != null && selectedItem.Name == "ocarina")
{
if ((selectionOffset == -1 || selectionOffset == 1) &&
MoveOcarinaSelection(selectionOffset))
selectionOffset = 0;
}
_selectedItemSlot += selectionOffset;
var slots = GameManager.EquipmentSlots - 4;
if (_selectedItemSlot < 0)
_selectedItemSlot += slots;
if (_selectedItemSlot >= slots)
_selectedItemSlot = _selectedItemSlot % slots;
}
private bool MoveOcarinaSelection(int direction)
{
var previousSong = Game1.GameManager.SelectedOcarinaSong;
for (var i = 0; i < Game1.GameManager.Equipment.Length; i++)
{
Game1.GameManager.SelectedOcarinaSong += direction;
if (Game1.GameManager.SelectedOcarinaSong < 0 ||
Game1.GameManager.SelectedOcarinaSong >= _ocarinaFaces.Length)
{
Game1.GameManager.SelectedOcarinaSong = previousSong;
return false;
}
if (Game1.GameManager.SelectedOcarinaSong != -1 &&
Game1.GameManager.OcarinaSongs[Game1.GameManager.SelectedOcarinaSong] == 1)
return Game1.GameManager.SelectedOcarinaSong != previousSong;
}
Game1.GameManager.SelectedOcarinaSong = -1;
return false;
}
public void Draw(SpriteBatch spriteBatch, Rectangle drawPosition, Color color)
{
spriteBatch.Draw(_renderTarget, drawPosition, color);
}
public void DrawRT(SpriteBatch spriteBatch)
{
Game1.Graphics.GraphicsDevice.SetRenderTarget(_renderTarget);
Game1.Graphics.GraphicsDevice.Clear(Color.Transparent);
Resources.RoundedCornerEffect.Parameters["scale"].SetValue(Game1.UiRtScale);
Resources.RoundedCornerEffect.Parameters["radius"].SetValue(3f);
// draw the background
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Matrix.CreateScale(Game1.UiRtScale));
Resources.RoundedCornerEffect.Parameters["width"].SetValue(_background0.Width);
Resources.RoundedCornerEffect.Parameters["height"].SetValue(_background0.Height);
spriteBatch.Draw(Resources.SprWhite, _background0, Values.InventoryBackgroundColorTop);
Resources.RoundedCornerEffect.Parameters["width"].SetValue(_background1.Width);
Resources.RoundedCornerEffect.Parameters["height"].SetValue(_background1.Height);
spriteBatch.Draw(Resources.SprWhite, _background1, Values.InventoryBackgroundColor);
spriteBatch.End();
// draw the backgrounds of the items
{
spriteBatch.Begin(SpriteSortMode.Immediate, null, null, null, null, Resources.RoundedCornerEffect, Matrix.CreateScale(Game1.UiRtScale));
var offset = new Point(_background1.X, _background1.Y);
for (var i = 0; i < _itemSlots.Length; i++)
DrawBackground(spriteBatch, offset + _itemSlotsPosition, _itemSlots[i]);
DrawBackground(spriteBatch, offset, _keyRectangle);
DrawBackground(spriteBatch, offset, _relictsRectangle);
DrawBackground(spriteBatch, offset, _itemsRectangle);
DrawBackground(spriteBatch, offset, _tradeStuffRectangle);
// draw the item selection
var selectionPosition = new Point(
(_itemsRectangle.X + _selectedItemSlot % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X)),
(_itemsRectangle.Y + _selectedItemSlot / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y)));
DrawBackground(spriteBatch, offset + selectionPosition, new Rectangle(0, 0, _itemRectangleSize.X, _itemRectangleSize.Y));
// draw the collected items
for (var i = 0; i < Game1.GameManager.Equipment.Length - Values.HandItemSlots; i++)
{
var slotRectangle = new Rectangle(
i % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X) + _itemRectangleSize.X / 2 - 2,
i / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y) + _itemRectangleSize.Y - 8, 4, 2);
if (Game1.GameManager.Equipment[Values.HandItemSlots + i] == null)
DrawBackground(spriteBatch, offset + _equipmentPosition, slotRectangle, 1);
}
// key background dots
for (var i = 0; i < 5; i++)
{
var slotRectangle = new Rectangle(
_keyPositions[i].X + _keyPositions[i].Width / 2 - 2,
_keyPositions[i].Y + _keyPositions[i].Height - 2, 4, 2);
var itemKey = Game1.GameManager.GetItem("dkey" + (i + 1));
if (itemKey == null)
DrawBackground(spriteBatch, offset, slotRectangle, 1);
}
for (var i = 0; i < _relicOffsets.Length; i++)
{
var name = "instrument" + i;
var hasItem = Game1.GameManager.GetItem(name) != null;
if (!hasItem)
{
var position = new Point(_relictPosition.X + _relicOffsets[i].X + _relicOffsets[i].Width / 2 - 2, _relictPosition.Y + _relicOffsets[i].Bottom - 2);
DrawBackground(spriteBatch, offset + position, new Rectangle(0, 0, 4, 2), 1);
}
}
spriteBatch.End();
}
// draw the map
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.PointClamp, null, null, null, Matrix.CreateScale(Game1.UiRtScale));
{
var heartOffset = new Point(0, Game1.GameManager.MaxHearths > 7 ? 0 : 4);
ItemDrawHelper.DrawHearts(spriteBatch, _heartsPosition + heartOffset, 1, Color.White);
// draw the skirt
DrawSkirt(spriteBatch, _skirtPosition);
DrawHeartContainer(spriteBatch, _heartPiecePosition);
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("flippers"), Point.Zero, _flipperRectangle, 1, Color.White);
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("potion"), Point.Zero, _potionRectangle, 1, Color.White);
ItemDrawHelper.DrawRubee(spriteBatch, _rubeePosition, 1, Color.Black);
var offsetBottom = new Point(_background1.X, _background1.Y);
// center the items
{
var width = 0;
var hasTradeItem = false;
for (var i = 0; i < 15; i++)
{
hasTradeItem = Game1.GameManager.GetItem("trade" + i) != null;
if (hasTradeItem)
{
width += 28;
break;
}
}
var itemShell = Game1.GameManager.GetItem("shell");
var itemLeaf = Game1.GameManager.GetItem("goldLeaf");
if (itemShell != null)
width += 28;
if (itemLeaf != null)
width += 28;
var posX = _tradeStuffRectangle.Width / 2 - width / 2;
_tradeRectangle = new Rectangle(6 + posX, 6, 28, 22);
if (hasTradeItem)
posX += 28;
_shellRectangle = new Rectangle(6 + posX, 6, 28, 22);
if (itemShell != null)
posX += 28;
_leafRectangle = new Rectangle(6 + posX, 6, 28, 22);
// draw the current trade item
DrawTradeItem(spriteBatch, offsetBottom, 1);
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("shell"), offsetBottom, _shellRectangle, 1, Color.White);
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("goldLeaf"), offsetBottom, _leafRectangle, 1, Color.White);
}
// draw the collected equipment
DrawEquipment(spriteBatch, offsetBottom + _equipmentPosition);
// draw the item slots
for (var i = 0; i < _itemSlots.Length; i++)
{
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.Equipment[i], offsetBottom + _itemSlotsPosition, _itemSlots[i], 1, Color.White);
spriteBatch.DrawString(Resources.GameFont, _itemSlotString[i], new Vector2(
offsetBottom.X + _itemSlotsPosition.X + _itemSlots[i].Right - 4,
offsetBottom.Y + _itemSlotsPosition.Y + _itemSlots[i].Bottom - 4), Color.Black);
}
// draw the collected keys
for (var i = 0; i < 5; i++)
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.GetItem("dkey" + (i + 1)), offsetBottom, _keyPositions[i], 1, Color.White);
DrawRelicts(spriteBatch, offsetBottom + _relictPosition);
}
spriteBatch.End();
}
private void DrawBackground(SpriteBatch spriteBatch, Point offset, Rectangle rectangle, float radius = 3f)
{
Resources.RoundedCornerEffect.Parameters["radius"].SetValue(radius);
Resources.RoundedCornerEffect.Parameters["width"].SetValue(rectangle.Width);
Resources.RoundedCornerEffect.Parameters["height"].SetValue(rectangle.Height);
spriteBatch.Draw(Resources.SprWhite, new Rectangle(offset.X + rectangle.X, offset.Y + rectangle.Y, rectangle.Width, rectangle.Height), Color.Black * 0.15f);
}
public void DrawEquipment(SpriteBatch spriteBatch, Point drawPosition)
{
// draw the collected items
for (var i = 0; i < Game1.GameManager.Equipment.Length - Values.HandItemSlots; i++)
{
var slotRectangle = new Rectangle(
i % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X),
i / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y),
_itemRectangleSize.X, _itemRectangleSize.Y);
// draw the item
var itemIndex = i + Values.HandItemSlots;
var offsetY = _selectedItemSlot == i ? -1 : 0;
if (_selectedItemSlot == i &&
Game1.GameManager.Equipment[itemIndex] != null &&
Game1.GameManager.Equipment[itemIndex].Name == "ocarina")
{
var hasSong = false;
for (var j = 0; j < Game1.GameManager.OcarinaSongs.Length; j++)
if (Game1.GameManager.OcarinaSongs[j] != 0)
{
hasSong = true;
break;
}
if (hasSong)
continue;
}
ItemDrawHelper.DrawItemWithInfo(spriteBatch, Game1.GameManager.Equipment[itemIndex], new Point(drawPosition.X, drawPosition.Y + offsetY + 1), slotRectangle, 1, Color.White);
}
// draw the ocarina face selection
var selectedItem = Game1.GameManager.Equipment[4 + _selectedItemSlot];
if (selectedItem != null && selectedItem.Name == "ocarina")
{
var selectedSong = Game1.GameManager.SelectedOcarinaSong;
if (selectedSong != -1)
{
var hasSong = Game1.GameManager.OcarinaSongs[selectedSong] == 1;
var position = new Vector2(
drawPosition.X + (_selectedItemSlot % ItemSlotWidth * (_itemRectangleSize.X + _itemRecMargin.X)) +
_itemRectangleSize.X / 2 - _ocarinaFaces[selectedSong].ScaledRectangle.Width / 2,
drawPosition.Y + (_selectedItemSlot / ItemSlotWidth * (_itemRectangleSize.Y + _itemRecMargin.Y)) +
_itemRectangleSize.Y / 2 - _ocarinaFaces[selectedSong].ScaledRectangle.Height / 2);
DrawHelper.DrawNormalized(spriteBatch, _ocarinaFaces[selectedSong], position, hasSong ? Color.White : Color.Gray);
}
}
}
public void DrawRelicts(SpriteBatch spriteBatch, Point drawPosition)
{
// draw the relicts
for (var i = 0; i < _relicOffsets.Length; i++)
{
var name = "instrument" + i;
var hasItem = Game1.GameManager.GetItem(name) != null;
var item = Game1.GameManager.ItemManager[name];
if (hasItem)
ItemDrawHelper.DrawInstrument(spriteBatch, item.Sprite, new Vector2(
drawPosition.X + _relicOffsets[i].X, drawPosition.Y + _relicOffsets[i].Y));
}
}
public void DrawHeartContainer(SpriteBatch spriteBatch, Point drawPosition)
{
// heartMeter
var item = Game1.GameManager.GetItem("heartMeter");
var count = 0;
if (item != null)
count = item.Count;
// draw the heart container
spriteBatch.Draw(Resources.SprItem, new Rectangle(
drawPosition.X, drawPosition.Y, _heartPiecesRectangle.Width, _heartPiecesRectangle.Height),
new Rectangle(_heartPiecesRectangle.X + (_heartPiecesRectangle.Width + 2) * count,
_heartPiecesRectangle.Y, _heartPiecesRectangle.Width, _heartPiecesRectangle.Height), Color.White);
}
public void DrawTradeItem(SpriteBatch spriteBatch, Point drawPosition, int scale)
{
// draw the current trade item
for (var i = 0; i < 15; i++)
{
var hasItem = Game1.GameManager.GetItem("trade" + i) != null;
if (!hasItem)
continue;
// draw the key
DrawHelper.DrawCenter(spriteBatch, Resources.SprItem,
drawPosition, _tradeRectangle, Game1.GameManager.ItemManager["trade" + i].SourceRectangle.Value, scale);
break;
}
}
public void DrawSkirt(SpriteBatch spriteBatch, Point drawPosition)
{
// draw GBR
spriteBatch.Draw(Resources.SprItem, new Rectangle(
drawPosition.X,
drawPosition.Y + 2,
_skirtColorRectangle.Width, _skirtColorRectangle.Height),
new Rectangle(
_skirtColorRectangle.X,
_skirtColorRectangle.Y + Game1.GameManager.CloakType * (_skirtColorRectangle.Height + 1),
_skirtColorRectangle.Width, _skirtColorRectangle.Height), Color.White);
var skirtPosition = new Point(drawPosition.X + _skirtColorRectangle.Width + 1, drawPosition.Y);
// draw the skirt
spriteBatch.Draw(Resources.SprItem, new Rectangle(
skirtPosition.X, skirtPosition.Y,
_skirtRectangle.Width, _skirtRectangle.Height), _skirtRectangle, Color.White);
// draw the skirt color
spriteBatch.Draw(Resources.SprItem, new Rectangle(
skirtPosition.X, skirtPosition.Y,
_skirtRectangle.Width, _skirtRectangle.Height),
new Rectangle(_skirtRectangle.X, _skirtRectangle.Y + _skirtRectangle.Height,
_skirtRectangle.Width, _skirtRectangle.Height), Values.SkirtColors[Game1.GameManager.CloakType]);
}
}
}