Fix up equipping inventory items, fill out the rest of the inventory labels
This commit is contained in:
@@ -181,9 +181,9 @@ public partial class Enemy : CharacterBody3D, IEnemy, IProvide<IEnemyLogic>
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var roll = rng.Randf();
|
||||
if (roll <= GameRepo.EquippedWeapon.WeaponInfo.Luck)
|
||||
if (roll <= GameRepo.EquippedWeapon.Value.WeaponInfo.Luck)
|
||||
isCriticalHit = true;
|
||||
var damage = DamageCalculator.CalculatePlayerDamage(hitBox.Damage, hitBox.GetParent<IPlayer>().PlayerStatInfo, EnemyStatInfo, GameRepo.EquippedWeapon.WeaponInfo, isCriticalHit);
|
||||
var damage = DamageCalculator.CalculatePlayerDamage(hitBox.Damage, hitBox.GetParent<IPlayer>().PlayerStatInfo, EnemyStatInfo, GameRepo.EquippedWeapon.Value.WeaponInfo, isCriticalHit);
|
||||
GD.Print($"Enemy Hit for {damage} damage.");
|
||||
EnemyLogic.Input(new EnemyLogic.Input.HitByPlayer(damage));
|
||||
}
|
||||
|
||||
@@ -5,14 +5,23 @@ namespace GameJamDungeon
|
||||
[GlobalClass]
|
||||
public partial class EnemyStatInfo : Resource, ICharacterStats
|
||||
{
|
||||
[Export]
|
||||
public double CurrentHP { get; set; }
|
||||
|
||||
[Export]
|
||||
public double MaximumHP { get; set; }
|
||||
|
||||
[Export]
|
||||
public int BaseAttack { get; set; }
|
||||
public int CurrentAttack { get; set; }
|
||||
|
||||
[Export]
|
||||
public int BaseDefense { get; set; }
|
||||
public int CurrentDefense { get; set; }
|
||||
|
||||
[Export]
|
||||
public int MaxAttack { get; set; }
|
||||
|
||||
[Export]
|
||||
public int MaxDefense { get; set; }
|
||||
|
||||
[Export]
|
||||
public float Luck { get; set; } = 0.05f;
|
||||
|
||||
@@ -91,9 +91,9 @@ public partial class Game : Node3D, IGame
|
||||
var currentFloor = Floors.ElementAt(_currentFloor);
|
||||
currentFloor.CallDeferred(MethodName.QueueFree, []);
|
||||
|
||||
if (GameRepo.EquippedWeapon.WeaponInfo != null && GameRepo.EquippedWeapon.WeaponInfo.WeaponTags.Contains(WeaponTag.BreaksOnChange))
|
||||
if (GameRepo.EquippedWeapon.Value.WeaponInfo != null && GameRepo.EquippedWeapon.Value.WeaponInfo.WeaponTags.Contains(WeaponTag.BreaksOnChange))
|
||||
{
|
||||
GameRepo.InventoryItems.Value.Remove(GameRepo.EquippedWeapon);
|
||||
GameRepo.InventoryItems.Value.Remove(GameRepo.EquippedWeapon.Value);
|
||||
GameRepo.OnWeaponEquipped(new Weapon());
|
||||
}
|
||||
|
||||
|
||||
@@ -23,25 +23,29 @@ public interface IGameRepo : IDisposable
|
||||
|
||||
void SetPlayerGlobalPosition(Vector3 playerGlobalPosition);
|
||||
|
||||
void SetPlayerStatInfo(PlayerStatInfo playerStatInfo);
|
||||
|
||||
public void OnWeaponEquipped(Weapon equippedItem);
|
||||
|
||||
public void OnArmorEquipped(Armor equippedItem);
|
||||
|
||||
public void OnAccessoryEquipped(Accessory equippedItem);
|
||||
|
||||
public Weapon EquippedWeapon { get; }
|
||||
public AutoProp<Weapon> EquippedWeapon { get; }
|
||||
|
||||
public Armor EquippedArmor { get; }
|
||||
public AutoProp<Armor> EquippedArmor { get; }
|
||||
|
||||
public Accessory EquippedAccessory { get; }
|
||||
|
||||
public AutoProp<int> HPBarValue { get; }
|
||||
|
||||
public AutoProp<int> VTBarValue { get; }
|
||||
|
||||
bool IsWithinDialogueSpace { get; set; }
|
||||
public AutoProp<Accessory> EquippedAccessory { get; }
|
||||
|
||||
public int MaxItemSize { get; }
|
||||
|
||||
public AutoProp<PlayerStatInfo> PlayerStatInfo { get; }
|
||||
|
||||
public bool IsItemEquipped(IEquipable item);
|
||||
|
||||
public void EquipItem(IEquipable item);
|
||||
|
||||
public void UnequipItem(IEquipable item);
|
||||
}
|
||||
|
||||
public class GameRepo : IGameRepo
|
||||
@@ -61,20 +65,16 @@ public class GameRepo : IGameRepo
|
||||
public IAutoProp<bool> IsPaused => _isPaused;
|
||||
private readonly AutoProp<bool> _isPaused;
|
||||
|
||||
private Weapon _equippedWeapon;
|
||||
public Weapon EquippedWeapon => _equippedWeapon;
|
||||
private AutoProp<Weapon> _equippedWeapon;
|
||||
public AutoProp<Weapon> EquippedWeapon => _equippedWeapon;
|
||||
|
||||
private Armor _equippedArmor;
|
||||
private AutoProp<Armor> _equippedArmor;
|
||||
|
||||
public Armor EquippedArmor => _equippedArmor;
|
||||
public AutoProp<Armor> EquippedArmor => _equippedArmor;
|
||||
|
||||
private Accessory _equippedAccessory;
|
||||
private AutoProp<Accessory> _equippedAccessory;
|
||||
|
||||
public Accessory EquippedAccessory => _equippedAccessory;
|
||||
|
||||
public AutoProp<int> HPBarValue { get; }
|
||||
|
||||
public AutoProp<int> VTBarValue { get; }
|
||||
public AutoProp<Accessory> EquippedAccessory => _equippedAccessory;
|
||||
|
||||
public bool IsWithinDialogueSpace { get; set; }
|
||||
|
||||
@@ -82,16 +82,20 @@ public class GameRepo : IGameRepo
|
||||
|
||||
private bool _disposedValue;
|
||||
|
||||
private AutoProp<PlayerStatInfo> _playerStatInfo;
|
||||
|
||||
public AutoProp<PlayerStatInfo> PlayerStatInfo => _playerStatInfo;
|
||||
|
||||
public GameRepo()
|
||||
{
|
||||
_inventoryItems = new AutoProp<List<IInventoryItem>>([]);
|
||||
_isInventoryScreenOpened = new AutoProp<bool>(false);
|
||||
_isPaused = new AutoProp<bool>(false);
|
||||
_playerGlobalPosition = new AutoProp<Vector3>(Vector3.Zero);
|
||||
_equippedWeapon = new Weapon();
|
||||
HPBarValue = new AutoProp<int>(0);
|
||||
VTBarValue = new AutoProp<int>(0);
|
||||
IsWithinDialogueSpace = false;
|
||||
_equippedWeapon = new AutoProp<Weapon>(new Weapon());
|
||||
_equippedArmor = new AutoProp<Armor>(new Armor());
|
||||
_equippedAccessory = new AutoProp<Accessory>(new Accessory());
|
||||
_playerStatInfo = new AutoProp<PlayerStatInfo>(new PlayerStatInfo());
|
||||
}
|
||||
|
||||
public void Pause()
|
||||
@@ -108,19 +112,21 @@ public class GameRepo : IGameRepo
|
||||
|
||||
public void SetPlayerGlobalPosition(Vector3 playerGlobalPosition) => _playerGlobalPosition.OnNext(playerGlobalPosition);
|
||||
|
||||
public void SetPlayerStatInfo(PlayerStatInfo playerStatInfo) => _playerStatInfo.OnNext(playerStatInfo);
|
||||
|
||||
public void OnWeaponEquipped(Weapon equippedItem)
|
||||
{
|
||||
_equippedWeapon = equippedItem;
|
||||
_equippedWeapon.OnNext(equippedItem);
|
||||
}
|
||||
|
||||
public void OnArmorEquipped(Armor equippedItem)
|
||||
{
|
||||
_equippedArmor = equippedItem;
|
||||
_equippedArmor.OnNext(equippedItem);
|
||||
}
|
||||
|
||||
public void OnAccessoryEquipped(Accessory equippedItem)
|
||||
{
|
||||
_equippedAccessory = equippedItem;
|
||||
_equippedAccessory.OnNext(equippedItem);
|
||||
}
|
||||
|
||||
public void OnGameEnded()
|
||||
@@ -129,6 +135,42 @@ public class GameRepo : IGameRepo
|
||||
Ended?.Invoke();
|
||||
}
|
||||
|
||||
public bool IsItemEquipped(IEquipable item)
|
||||
{
|
||||
if (item is Weapon)
|
||||
return EquippedWeapon.Value == item;
|
||||
|
||||
if (item is Armor)
|
||||
return EquippedArmor.Value == item;
|
||||
|
||||
if (item is Accessory)
|
||||
return EquippedAccessory.Value == item;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void EquipItem(IEquipable item)
|
||||
{
|
||||
if (item is Weapon weapon)
|
||||
OnWeaponEquipped(weapon);
|
||||
|
||||
if (item is Armor armor)
|
||||
OnArmorEquipped(armor);
|
||||
|
||||
if (item is Accessory accessory)
|
||||
OnAccessoryEquipped(accessory);
|
||||
}
|
||||
|
||||
public void UnequipItem(IEquipable item)
|
||||
{
|
||||
if (item == EquippedWeapon.Value)
|
||||
OnWeaponEquipped(new Weapon());
|
||||
if (item == EquippedArmor.Value)
|
||||
OnArmorEquipped(new Armor());
|
||||
if (item == EquippedAccessory.Value)
|
||||
OnAccessoryEquipped(new Accessory());
|
||||
}
|
||||
|
||||
protected void Dispose(bool disposing)
|
||||
{
|
||||
if (!_disposedValue)
|
||||
|
||||
@@ -54,15 +54,65 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
||||
|
||||
private int _currentIndex = 0;
|
||||
|
||||
private ItemSlot[] ItemSlots => ItemsPage.GetChildren().OfType<ItemSlot>().ToArray();
|
||||
|
||||
private static LabelSettings ItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextRegular.tres");
|
||||
private static LabelSettings SelectedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontItalicized.tres");
|
||||
private static LabelSettings EquippedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontEquipped.tres");
|
||||
|
||||
private static LabelSettings SelectedEquippedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontSelectedEquipped.tres");
|
||||
private IItemSlot[] ItemSlots => ItemsPage.GetChildren().OfType<IItemSlot>().ToArray();
|
||||
|
||||
public void PopulateItems()
|
||||
{
|
||||
PopulatePlayerInfo();
|
||||
PopulateInventory();
|
||||
}
|
||||
|
||||
public void PopulatePlayerInfo()
|
||||
{
|
||||
|
||||
FloorLabel.Text = $"Floor 0";
|
||||
|
||||
var currentLevel = GameRepo.PlayerStatInfo.Value.CurrentLevel;
|
||||
CurrentLevelLabel.Text = $"Level {currentLevel:D2}";
|
||||
|
||||
var currentHP = GameRepo.PlayerStatInfo.Value.CurrentHP;
|
||||
var maxHP = GameRepo.PlayerStatInfo.Value.MaximumHP;
|
||||
|
||||
HPValue.Text = $"{currentHP}/{maxHP}";
|
||||
|
||||
var currentVT = GameRepo.PlayerStatInfo.Value.CurrentVT;
|
||||
var maxVT = GameRepo.PlayerStatInfo.Value.MaximumVT;
|
||||
|
||||
VTValue.Text = $"{currentVT}/{maxVT}";
|
||||
|
||||
var currentAttack = GameRepo.PlayerStatInfo.Value.CurrentAttack;
|
||||
var maxAttack = GameRepo.PlayerStatInfo.Value.MaxAttack;
|
||||
|
||||
ATKValue.Text = $"{currentAttack}/{maxAttack}";
|
||||
|
||||
var currentDefense = GameRepo.PlayerStatInfo.Value.CurrentDefense;
|
||||
var maxDefense = GameRepo.PlayerStatInfo.Value.MaxDefense;
|
||||
DEFValue.Text = $"{currentDefense}/{maxDefense}";
|
||||
|
||||
var atkBonus = GameRepo.PlayerStatInfo.Value.BonusAttack;
|
||||
var defBonus = GameRepo.PlayerStatInfo.Value.BonusDefense;
|
||||
|
||||
ATKBonusLabel.Text = atkBonus != 0 ? $"{atkBonus}" : "...";
|
||||
DEFBonusLabel.Text = defBonus != 0 ? $"{defBonus}" : "...";
|
||||
|
||||
// TODO: Change font style when EXP Bonus effect is active
|
||||
var currentExp = GameRepo.PlayerStatInfo.Value.CurrentEXP;
|
||||
var expToNextLevel = GameRepo.PlayerStatInfo.Value.EXPToNextLevel;
|
||||
EXPValue.Text = $"{currentExp}/{expToNextLevel}";
|
||||
|
||||
if (ItemSlots.Any())
|
||||
{
|
||||
ItemDescriptionTitle.Text = $"{ItemSlots.ElementAtOrDefault(_currentIndex).Item.Info.Name}";
|
||||
ItemEffectLabel.Text = $"{ItemSlots.ElementAtOrDefault(_currentIndex).Item.Info.Description}";
|
||||
}
|
||||
else
|
||||
{
|
||||
ItemDescriptionTitle.Text = string.Empty;
|
||||
ItemEffectLabel.Text = string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopulateInventory()
|
||||
{
|
||||
var inventory = GameRepo.InventoryItems.Value;
|
||||
var numberOfItemsToDisplay = _currentPageNumber == InventoryPageNumber.FirstPage ? Mathf.Min(inventory.Count, _itemsPerPage) : Mathf.Min(inventory.Count - _itemsPerPage, _itemsPerPage);
|
||||
@@ -88,15 +138,19 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
||||
var item = inventory.ElementAt(i + indexToStart);
|
||||
var itemScene = GD.Load<PackedScene>(ITEM_SLOT_SCENE);
|
||||
var itemSlot = itemScene.Instantiate<IItemSlot>();
|
||||
itemSlot.Item = item;
|
||||
ItemsPage.AddChildEx(itemSlot);
|
||||
|
||||
itemSlot.ItemName.Text = item.Info.Name;
|
||||
itemSlot.ItemTexture.Texture = item.Info.Texture;
|
||||
itemSlot.EquipBonus.Text = "...";
|
||||
if (itemSlot.Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable))
|
||||
itemSlot.SetEquippedItemStyle();
|
||||
}
|
||||
|
||||
if (ItemSlots.Any())
|
||||
ItemSlots.ElementAt(_currentIndex).ItemName.LabelSettings = SelectedItemFont;
|
||||
{
|
||||
ItemSlots.ElementAt(_currentIndex).SetSelectedItemStyle();
|
||||
if (ItemSlots.ElementAt(_currentIndex).Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable))
|
||||
ItemSlots.ElementAt(_currentIndex).SetEquippedSelectedItemStyle();
|
||||
}
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
@@ -120,31 +174,53 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
||||
|
||||
if (ItemSlots.Any() && Input.IsActionJustPressed(GameInputs.UiDown))
|
||||
{
|
||||
if (!inventory.Any() || _currentIndex + 1 >= _itemsPerPage)
|
||||
if (!inventory.Any())
|
||||
return;
|
||||
|
||||
ItemSlots.ElementAt(_currentIndex).ItemName.LabelSettings = ItemFont;
|
||||
_currentIndex++;
|
||||
ItemSlots.ElementAt(_currentIndex).ItemName.LabelSettings = SelectedItemFont;
|
||||
var oldItem = ItemSlots.ElementAt(_currentIndex);
|
||||
ItemSlots.ElementAt(_currentIndex).SetItemStyle();
|
||||
var index = new[] { _currentIndex + 1, _itemsPerPage - 1, ItemSlots.Count() - 1 };
|
||||
_currentIndex = index.Min();
|
||||
var newItem = ItemSlots.ElementAt(_currentIndex);
|
||||
newItem.SetSelectedItemStyle();
|
||||
if (oldItem.Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable))
|
||||
oldItem.SetEquippedItemStyle();
|
||||
if (newItem.Item is IEquipable newEquipable && GameRepo.IsItemEquipped(newEquipable))
|
||||
newItem.SetEquippedSelectedItemStyle();
|
||||
}
|
||||
|
||||
if (ItemSlots.Any() && Input.IsActionJustPressed(GameInputs.UiUp))
|
||||
{
|
||||
if (!inventory.Any() || _currentIndex <= 0)
|
||||
if (!inventory.Any())
|
||||
return;
|
||||
|
||||
ItemSlots.ElementAt(_currentIndex).ItemName.LabelSettings = ItemFont;
|
||||
_currentIndex--;
|
||||
ItemSlots.ElementAt(_currentIndex).ItemName.LabelSettings = SelectedItemFont;
|
||||
var oldItem = ItemSlots.ElementAt(_currentIndex);
|
||||
ItemSlots.ElementAt(_currentIndex).SetItemStyle();
|
||||
var index = new[] { _currentIndex - 1, 0 };
|
||||
_currentIndex = index.Max();
|
||||
var newItem = ItemSlots.ElementAt(_currentIndex);
|
||||
newItem.SetSelectedItemStyle();
|
||||
if (oldItem.Item is IEquipable equipable && GameRepo.IsItemEquipped(equipable))
|
||||
oldItem.SetEquippedItemStyle();
|
||||
if (newItem.Item is IEquipable newEquipable && GameRepo.IsItemEquipped(newEquipable))
|
||||
newItem.SetEquippedSelectedItemStyle();
|
||||
}
|
||||
|
||||
if (ItemSlots.Any() && Input.IsActionJustPressed(GameInputs.UiAccept))
|
||||
{
|
||||
if (_currentPageNumber == InventoryPageNumber.FirstPage)
|
||||
var itemSlot = ItemSlots[_currentIndex];
|
||||
if (itemSlot.Item is IEquipable equipableItem)
|
||||
{
|
||||
var item = inventory.ElementAt(_currentIndex);
|
||||
if (item is IEquippable)
|
||||
ItemSlots.ElementAt(_currentIndex).ItemName.LabelSettings = EquippedItemFont;
|
||||
if (GameRepo.IsItemEquipped(equipableItem))
|
||||
{
|
||||
GameRepo.UnequipItem(equipableItem);
|
||||
itemSlot.SetSelectedItemStyle();
|
||||
}
|
||||
else
|
||||
{
|
||||
GameRepo.EquipItem(equipableItem);
|
||||
itemSlot.SetEquippedSelectedItemStyle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,7 +229,7 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
||||
{
|
||||
foreach (var item in ItemSlots)
|
||||
{
|
||||
ItemsPage.RemoveChild(item);
|
||||
ItemsPage.RemoveChildEx(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ layout_mode = 2
|
||||
|
||||
[node name="PlayerInfo" type="VBoxContainer" parent="InventoryInfo/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 40
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="FloorBox" type="HBoxContainer" parent="InventoryInfo/HBoxContainer/PlayerInfo"]
|
||||
layout_mode = 2
|
||||
|
||||
@@ -1,15 +1,20 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Chickensoft.Introspection;
|
||||
using GameJamDungeon;
|
||||
using Godot;
|
||||
|
||||
public interface IItemSlot : IHBoxContainer
|
||||
{
|
||||
public Label EquipBonus { get; }
|
||||
public IInventoryItem Item { get; set; }
|
||||
|
||||
public TextureRect ItemTexture { get; }
|
||||
public void SetItemStyle();
|
||||
|
||||
public Label ItemName { get; }
|
||||
public void SetSelectedItemStyle();
|
||||
|
||||
public void SetEquippedItemStyle();
|
||||
|
||||
public void SetEquippedSelectedItemStyle();
|
||||
}
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
@@ -17,9 +22,70 @@ public partial class ItemSlot : HBoxContainer, IItemSlot
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency]
|
||||
public IGameRepo GameRepo => this.DependOn<IGameRepo>();
|
||||
|
||||
[Node] public Label EquipBonus { get; set; } = default!;
|
||||
|
||||
[Node] public TextureRect ItemTexture { get; set; } = default!;
|
||||
|
||||
[Node] public Label ItemName { get; set; } = default!;
|
||||
|
||||
private static LabelSettings ItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextRegular.tres");
|
||||
private static LabelSettings SelectedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontItalicized.tres");
|
||||
private static LabelSettings EquippedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontEquipped.tres");
|
||||
|
||||
private static LabelSettings SelectedEquippedItemFont => GD.Load<LabelSettings>("res://src/ui/label_settings/MainTextFontSelectedEquipped.tres");
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
ItemName.Text = Item.Info.Name;
|
||||
EquipBonus.Text = "...";
|
||||
ItemTexture.Texture = Item.Info.Texture;
|
||||
GameRepo.EquippedWeapon.Sync += EquippedWeapon_Sync;
|
||||
GameRepo.EquippedArmor.Sync += EquippedArmor_Sync;
|
||||
GameRepo.EquippedAccessory.Sync += EquippedAccessory_Sync;
|
||||
}
|
||||
|
||||
private void EquippedWeapon_Sync(Weapon obj)
|
||||
{
|
||||
if (Item is Weapon unequippedItem && unequippedItem != obj)
|
||||
SetItemStyle();
|
||||
}
|
||||
|
||||
private void EquippedArmor_Sync(Armor obj)
|
||||
{
|
||||
if (Item is Armor unequippedItem && unequippedItem != obj)
|
||||
SetItemStyle();
|
||||
}
|
||||
|
||||
private void EquippedAccessory_Sync(Accessory obj)
|
||||
{
|
||||
if (Item is Accessory unequippedItem && unequippedItem != obj)
|
||||
SetItemStyle();
|
||||
}
|
||||
|
||||
public void SetItemStyle()
|
||||
{
|
||||
ItemName.LabelSettings = ItemFont;
|
||||
EquipBonus.LabelSettings = ItemFont;
|
||||
}
|
||||
public void SetSelectedItemStyle()
|
||||
{
|
||||
ItemName.LabelSettings = SelectedItemFont;
|
||||
EquipBonus.LabelSettings = SelectedItemFont;
|
||||
}
|
||||
public void SetEquippedItemStyle()
|
||||
{
|
||||
ItemName.LabelSettings = EquippedItemFont;
|
||||
EquipBonus.LabelSettings = EquippedItemFont;
|
||||
}
|
||||
|
||||
public void SetEquippedSelectedItemStyle()
|
||||
{
|
||||
ItemName.LabelSettings = SelectedEquippedItemFont;
|
||||
EquipBonus.LabelSettings = SelectedEquippedItemFont;
|
||||
}
|
||||
|
||||
public IInventoryItem Item { get; set; } = default!;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace GameJamDungeon
|
||||
{
|
||||
public interface IEquippable;
|
||||
public interface IEquipable;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ using Godot;
|
||||
using System.Linq;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Accessory : Node3D, IInventoryItem, IEquippable
|
||||
public partial class Accessory : Node3D, IInventoryItem, IEquipable
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using Godot;
|
||||
using System.Linq;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Armor : Node3D, IInventoryItem, IEquippable
|
||||
public partial class Armor : Node3D, IInventoryItem, IEquipable
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ using Godot;
|
||||
using System.Linq;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Weapon : Node3D, IInventoryItem, IEquippable
|
||||
public partial class Weapon : Node3D, IInventoryItem, IEquipable
|
||||
{
|
||||
public Weapon()
|
||||
{
|
||||
|
||||
@@ -98,6 +98,8 @@ namespace GameJamDungeon
|
||||
GameRepo.SetPlayerGlobalPosition(GlobalPosition);
|
||||
GameRepo.PlayerGlobalPosition.Sync += OnPlayerPositionUpdated;
|
||||
|
||||
GameRepo.SetPlayerStatInfo(PlayerStatInfo);
|
||||
|
||||
_currentHP = new AutoProp<double>(PlayerStatInfo.MaximumHP);
|
||||
_currentVT = new AutoProp<int>(PlayerStatInfo.MaximumVT);
|
||||
_currentHP.Sync += OnHPChanged;
|
||||
@@ -119,7 +121,7 @@ namespace GameJamDungeon
|
||||
})
|
||||
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
|
||||
{
|
||||
var weaponInfo = GameRepo.EquippedWeapon.WeaponInfo;
|
||||
var weaponInfo = GameRepo.EquippedWeapon.Value.WeaponInfo;
|
||||
var attackSpeed = (float)weaponInfo.AttackSpeed;
|
||||
AnimationPlayer.SetSpeedScale(attackSpeed);
|
||||
AnimationPlayer.Play("attack");
|
||||
@@ -160,7 +162,7 @@ namespace GameJamDungeon
|
||||
var roll = rng.Randf();
|
||||
if (roll <= enemy.EnemyStatInfo.Luck)
|
||||
isCriticalHit = true;
|
||||
var damage = DamageCalculator.CalculateEnemyDamage(hitBox.Damage, PlayerStatInfo, enemy.EnemyStatInfo, GameRepo.EquippedArmor.ArmorInfo, isCriticalHit);
|
||||
var damage = DamageCalculator.CalculateEnemyDamage(hitBox.Damage, PlayerStatInfo, enemy.EnemyStatInfo, GameRepo.EquippedArmor.Value.ArmorInfo, isCriticalHit);
|
||||
_currentHP.OnNext(_currentHP.Value - damage);
|
||||
GD.Print($"Player hit for {damage} damage.");
|
||||
}
|
||||
|
||||
@@ -15,10 +15,19 @@
|
||||
|
||||
[sub_resource type="Resource" id="Resource_up0v1"]
|
||||
script = ExtResource("2_n88di")
|
||||
CurrentHP = 100.0
|
||||
MaximumHP = 100.0
|
||||
CurrentVT = 90
|
||||
MaximumVT = 90
|
||||
BaseAttack = 10
|
||||
BaseDefense = 5
|
||||
CurrentLevel = 1
|
||||
CurrentEXP = 0
|
||||
EXPToNextLevel = 100
|
||||
CurrentAttack = 12
|
||||
MaxAttack = 12
|
||||
CurrentDefense = 8
|
||||
MaxDefense = 8
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
|
||||
[sub_resource type="BoxShape3D" id="BoxShape3D_wedu3"]
|
||||
|
||||
|
||||
@@ -1,31 +1,7 @@
|
||||
using Chickensoft.Collections;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace GameJamDungeon
|
||||
namespace GameJamDungeon
|
||||
{
|
||||
public partial record PlayerData
|
||||
{
|
||||
[Save("global_transform")]
|
||||
public required Transform3D GlobalTransform { get; init; }
|
||||
|
||||
[Save("state_machine")]
|
||||
public required PlayerLogic StateMachine { get; init; }
|
||||
|
||||
[Save("PlayerEquippedSword")]
|
||||
public required IAutoProp<WeaponInfo> EquippedWeapon { get; set; }
|
||||
|
||||
[Save("PlayerInventory")]
|
||||
public required InventoryItemInfo[] Inventory { get; set; } = new InventoryItemInfo[5];
|
||||
|
||||
[Save("PlayerStats")]
|
||||
public required PlayerStatInfo PlayerStats { get; set; }
|
||||
|
||||
[Save("CurrentHP")]
|
||||
public required int CurrentHP { get; set; }
|
||||
|
||||
[Save("CurrentVT")]
|
||||
public required int CurrentVT { get; set; }
|
||||
// TODO: Implement save system
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Godot;
|
||||
using Chickensoft.Collections;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon
|
||||
{
|
||||
@@ -6,15 +7,62 @@ namespace GameJamDungeon
|
||||
public partial class PlayerStatInfo : Resource, ICharacterStats
|
||||
{
|
||||
[Export]
|
||||
public double MaximumHP { get; set; }
|
||||
public double CurrentHP { get => _currentHP.Value; set => _currentHP.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int MaximumVT { get; set; }
|
||||
public double MaximumHP { get => _maximumHP.Value; set => _maximumHP.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int BaseAttack { get; set; }
|
||||
public int CurrentVT { get => _currentVT.Value; set => _currentVT.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int BaseDefense { get; set; }
|
||||
public int MaximumVT { get => _maximumVT.Value; set => _maximumVT.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int CurrentLevel { get => _currentLevel.Value; set => _currentLevel.OnNext(value); }
|
||||
|
||||
|
||||
[Export]
|
||||
public int CurrentEXP { get => _currentExp.Value; set => _currentExp.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int EXPToNextLevel { get => _expToNextLevel.Value; set => _expToNextLevel.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int CurrentAttack { get => _currentAttack.Value; set => _currentAttack.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int MaxAttack { get => _maxAttack.Value; set => _maxAttack.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int CurrentDefense { get => _currentDefense.Value; set => _currentDefense.OnNext(value); }
|
||||
[Export]
|
||||
public int MaxDefense { get => _maxDefense.Value; set => _maxDefense.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int BonusAttack { get => _bonusAttack.Value; set => _bonusAttack.OnNext(value); }
|
||||
|
||||
[Export]
|
||||
public int BonusDefense { get => _bonusDefense.Value; set => _bonusDefense.OnNext(value); }
|
||||
|
||||
// AutoProp backing data
|
||||
private readonly AutoProp<double> _currentHP = new AutoProp<double>(0);
|
||||
private readonly AutoProp<double> _maximumHP = new AutoProp<double>(0);
|
||||
|
||||
private readonly AutoProp<int> _currentVT = new AutoProp<int>(0);
|
||||
private readonly AutoProp<int> _maximumVT = new AutoProp<int>(0);
|
||||
|
||||
private readonly AutoProp<int> _currentExp = new AutoProp<int>(0);
|
||||
private readonly AutoProp<int> _expToNextLevel = new AutoProp<int>(0);
|
||||
private readonly AutoProp<int> _currentLevel = new AutoProp<int>(0);
|
||||
|
||||
private readonly AutoProp<int> _currentAttack = new AutoProp<int>(0);
|
||||
private readonly AutoProp<int> _currentDefense = new AutoProp<int>(0);
|
||||
|
||||
private readonly AutoProp<int> _maxAttack = new AutoProp<int>(0);
|
||||
private readonly AutoProp<int> _maxDefense = new AutoProp<int>(0);
|
||||
|
||||
private readonly AutoProp<int> _bonusAttack = new AutoProp<int>(0);
|
||||
private readonly AutoProp<int> _bonusDefense = new AutoProp<int>(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace GameJamDungeon
|
||||
{
|
||||
public static double CalculatePlayerDamage(int attackDamage, PlayerStatInfo playerStatInfo, EnemyStatInfo enemyStatInfo, WeaponInfo weapon, bool isCriticalHit)
|
||||
{
|
||||
var baseDamage = attackDamage + playerStatInfo.BaseAttack;
|
||||
var baseDamage = attackDamage + playerStatInfo.CurrentAttack;
|
||||
var hydricResistance = enemyStatInfo.HydricResistance;
|
||||
var igneousResistance = enemyStatInfo.IgneousResistance;
|
||||
var telluricResistance = enemyStatInfo.TelluricResistance;
|
||||
@@ -28,7 +28,7 @@ namespace GameJamDungeon
|
||||
var elementDDamage = (weapon.AeolicDamageBonus > 0 ? weapon.AeolicDamageBonus - aeolicResistance : 0) / 100;
|
||||
var elementEDamage = (weapon.FerrumDamageBonus > 0 ? weapon.FerrumDamageBonus - ferrumResistance : 0) / 100;
|
||||
var elementalBonusDamage = baseDamage + (baseDamage * elementADamage) + (baseDamage * elementBDamage) + (baseDamage * elementCDamage) + (baseDamage * elementDDamage) + (baseDamage * elementEDamage);
|
||||
var calculatedDamage = elementalBonusDamage - enemyStatInfo.BaseDefense;
|
||||
var calculatedDamage = elementalBonusDamage - enemyStatInfo.CurrentDefense;
|
||||
|
||||
if (isCriticalHit)
|
||||
calculatedDamage *= 2;
|
||||
@@ -38,14 +38,14 @@ namespace GameJamDungeon
|
||||
|
||||
public static double CalculateEnemyDamage(int attackDamage, PlayerStatInfo playerStatInfo, EnemyStatInfo enemyStatInfo, ArmorInfo armor, bool isCriticalHit)
|
||||
{
|
||||
var baseDamage = attackDamage + enemyStatInfo.BaseAttack;
|
||||
var baseDamage = attackDamage + enemyStatInfo.CurrentAttack;
|
||||
var elementADamage = (enemyStatInfo.BaseHydricDamageBonus > 0 ? enemyStatInfo.BaseHydricDamageBonus - armor.HydricResistance : 0) / 100;
|
||||
var elementBDamage = (enemyStatInfo.IgneousDamageBonus > 0 ? enemyStatInfo.IgneousDamageBonus - armor.IgneousResistance : 0) / 100;
|
||||
var elementCDamage = (enemyStatInfo.TelluricDamageBonus > 0 ? enemyStatInfo.TelluricDamageBonus - armor.TelluricResistance : 0) / 100;
|
||||
var elementDDamage = (enemyStatInfo.AeolicDamageBonus > 0 ? enemyStatInfo.AeolicDamageBonus - armor.AeolicResistance : 0) / 100;
|
||||
var elementEDamage = (enemyStatInfo.FerrumDamageBonus > 0 ? enemyStatInfo.FerrumDamageBonus - armor.FerrumResistance : 0) / 100;
|
||||
var elementalBonusDamage = baseDamage + (baseDamage * elementADamage) + (baseDamage * elementBDamage) + (baseDamage * elementCDamage) + (baseDamage * elementDDamage) + (baseDamage * elementEDamage);
|
||||
var calculatedDamage = elementalBonusDamage - playerStatInfo.BaseDefense - (armor != null ? armor.Defense : 0);
|
||||
var calculatedDamage = elementalBonusDamage - playerStatInfo.CurrentDefense - (armor != null ? armor.Defense : 0);
|
||||
|
||||
if (isCriticalHit)
|
||||
calculatedDamage *= 2;
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon
|
||||
namespace GameJamDungeon
|
||||
{
|
||||
public interface ICharacterStats
|
||||
{
|
||||
public double CurrentHP { get; }
|
||||
|
||||
public double MaximumHP { get; }
|
||||
|
||||
public int BaseAttack { get; }
|
||||
public int CurrentAttack { get; }
|
||||
|
||||
public int BaseDefense { get; }
|
||||
public int CurrentDefense { get; }
|
||||
|
||||
public int MaxAttack { get; }
|
||||
|
||||
public int MaxDefense { get; }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user