Compare commits
4 Commits
5ae556cb4b
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| d45bc67722 | |||
| 13ebe54474 | |||
| b9a1888bfc | |||
| 52dc8fb9e4 |
@@ -4,5 +4,21 @@ public enum ItemTag
|
||||
{
|
||||
None,
|
||||
BreaksOnChange,
|
||||
MysteryItem
|
||||
}
|
||||
MysteryItem,
|
||||
DamagesPlayer,
|
||||
ContainsRestorative,
|
||||
ContainsWeapon,
|
||||
ContainsArmor,
|
||||
ContainsBox,
|
||||
RandomSpell,
|
||||
ContainsAccessory,
|
||||
DropTo1HPAndGainRareItem,
|
||||
TradeOneRandomItem,
|
||||
TradeAllRandomItems,
|
||||
ContainsUnobtainedItem,
|
||||
ContainsBasicItem,
|
||||
RestrictUnequip,
|
||||
UnequipAllItems,
|
||||
EjectAllItems,
|
||||
UseAllItems
|
||||
}
|
||||
@@ -44,6 +44,8 @@ public interface IPlayer : IKillable, ICharacterBody3D
|
||||
|
||||
public void SetHealthTimerStatus(bool isActive);
|
||||
|
||||
public bool CanEquipState { get; set; }
|
||||
|
||||
public event Action PlayerDied;
|
||||
public delegate InventoryItem RerollItem(InventoryItem item);
|
||||
}
|
||||
|
||||
@@ -69,7 +69,6 @@ public partial class Game : Node3D, IGame
|
||||
public QuestData QuestData { get; private set; }
|
||||
|
||||
private EffectService _effectService;
|
||||
private ItemReroller _itemReroller;
|
||||
|
||||
private IInstantiator _instantiator;
|
||||
private IPlayer _player;
|
||||
@@ -88,7 +87,6 @@ public partial class Game : Node3D, IGame
|
||||
QuestData = new QuestData();
|
||||
RescuedItems = new RescuedItemDatabase();
|
||||
ItemDatabase = ItemDatabase.Instance;
|
||||
_itemReroller = new ItemReroller(ItemDatabase);
|
||||
|
||||
GameChunk = new SaveChunk<GameData>(
|
||||
(chunk) =>
|
||||
@@ -212,10 +210,13 @@ public partial class Game : Node3D, IGame
|
||||
public async Task UseItem(InventoryItem item)
|
||||
{
|
||||
if (item.ItemTag == ItemTag.MysteryItem)
|
||||
item = _itemReroller.RerollItem(item, _player.Inventory);
|
||||
_effectService.RerollItem(item);
|
||||
|
||||
switch (item)
|
||||
{
|
||||
case BoxItem boxItem:
|
||||
EnactBoxItemEffects(boxItem);
|
||||
break;
|
||||
case ConsumableItem consumableItem:
|
||||
EnactConsumableItemEffects(consumableItem);
|
||||
break;
|
||||
@@ -428,6 +429,42 @@ public partial class Game : Node3D, IGame
|
||||
|
||||
private void FinishedLoadingSaveFile() => EmitSignal(SignalName.SaveFileLoaded);
|
||||
|
||||
private void EnactBoxItemEffects(BoxItem boxItem)
|
||||
{
|
||||
switch (boxItem.ItemTag)
|
||||
{
|
||||
case ItemTag.DamagesPlayer:
|
||||
_effectService.DamagesPlayer(boxItem.Stats.DamageToPlayer);
|
||||
GameRepo.CloseInventory();
|
||||
break;
|
||||
case ItemTag.ContainsAccessory:
|
||||
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<Accessory>());
|
||||
break;
|
||||
case ItemTag.ContainsArmor:
|
||||
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<Armor>());
|
||||
break;
|
||||
case ItemTag.ContainsWeapon:
|
||||
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<Weapon>());
|
||||
break;
|
||||
case ItemTag.ContainsBox:
|
||||
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<BoxItem>());
|
||||
break;
|
||||
case ItemTag.ContainsRestorative:
|
||||
_player.Inventory.TryAdd(_effectService.GetRandomItemOfType<ConsumableItem>());
|
||||
break;
|
||||
case ItemTag.DropTo1HPAndGainRareItem:
|
||||
_effectService.DropTo1HPAndGainRareItem<InventoryItem>();
|
||||
break;
|
||||
case ItemTag.TradeAllRandomItems:
|
||||
var newInventory = _effectService.TradeAllRandomItems<InventoryItem>(boxItem);
|
||||
_player.Inventory.Items.Clear();
|
||||
_player.Inventory.TryAdd(boxItem);
|
||||
foreach (var item in newInventory)
|
||||
_player.Inventory.TryAdd(item);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void EnactConsumableItemEffects(ConsumableItem consumableItem)
|
||||
{
|
||||
if (_player.HealthComponent.AtFullHealth && consumableItem.RaiseHPAmount > 0)
|
||||
@@ -519,7 +556,7 @@ public partial class Game : Node3D, IGame
|
||||
_effectService.ChangeAffinity(throwableItem);
|
||||
break;
|
||||
case ThrowableItemTag.WarpToExitIfFound:
|
||||
_effectService.WarpToExit(_player);
|
||||
_effectService.WarpToExit();
|
||||
GameRepo.CloseInventory();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
using Godot;
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
using System;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
@@ -14,225 +15,301 @@ public class EffectService
|
||||
|
||||
public EffectService(IGame game, IPlayer player, IMap map)
|
||||
{
|
||||
_game = game;
|
||||
_player = player;
|
||||
_map = map;
|
||||
_game = game;
|
||||
_player = player;
|
||||
_map = map;
|
||||
}
|
||||
|
||||
public void TeleportEnemiesToCurrentRoom()
|
||||
{
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom monsterRoom)
|
||||
validRooms.Remove(monsterRoom);
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom monsterRoom)
|
||||
validRooms.Remove(monsterRoom);
|
||||
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
|
||||
var enemyList = validRooms.SelectMany(x => x.GetEnemiesInCurrentRoom()).OfType<Enemy>();
|
||||
var enemyList = validRooms.SelectMany(x => x.GetEnemiesInCurrentRoom()).OfType<Enemy>();
|
||||
|
||||
foreach (var enemy in enemyList)
|
||||
enemy.MoveEnemyToNewRoom(currentMonsterRoom);
|
||||
foreach (var enemy in enemyList)
|
||||
enemy.MoveEnemyToNewRoom(currentMonsterRoom);
|
||||
}
|
||||
|
||||
public void KillHalfEnemiesInRoom()
|
||||
{
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
var enemyList = currentMonsterRoom.GetEnemiesInCurrentRoom().OfType<Enemy>().ToList();
|
||||
var enemiesToKill = enemyList.Count / 2;
|
||||
for (var i = 0; i < enemiesToKill; i++)
|
||||
enemyList[i].Die();
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
var enemyList = currentMonsterRoom.GetEnemiesInCurrentRoom().OfType<Enemy>().ToList();
|
||||
var enemiesToKill = enemyList.Count / 2;
|
||||
for (var i = 0; i < enemiesToKill; i++)
|
||||
enemyList[i].Die();
|
||||
}
|
||||
|
||||
public void TurnAllEnemiesInRoomIntoHealingItem()
|
||||
{
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var currentEnemies = currentRoom.EnemiesInRoom.OfType<Enemy>().ToList();
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
enemy.OnMorph();
|
||||
DropHealingItem(enemy.GlobalPosition);
|
||||
}
|
||||
if (currentEnemies.Any())
|
||||
SfxDatabase.Instance.Play(SoundEffect.TurnAllEnemiesIntoHealingItems);
|
||||
var currentEnemies = currentRoom.EnemiesInRoom.OfType<Enemy>().ToList();
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
enemy.OnMorph();
|
||||
DropHealingItem(enemy.GlobalPosition);
|
||||
}
|
||||
if (currentEnemies.Any())
|
||||
SfxDatabase.Instance.Play(SoundEffect.TurnAllEnemiesIntoHealingItems);
|
||||
}
|
||||
|
||||
public void DropHealingItem(Vector3 vector)
|
||||
{
|
||||
var consumableFolder = "res://src/items/consumable";
|
||||
var restorativeScene = GD.Load<PackedScene>($"{consumableFolder}/ConsumableItem.tscn");
|
||||
var consumable = restorativeScene.Instantiate<ConsumableItem>();
|
||||
var resourceFiles = DirAccess.GetFilesAt($"{consumableFolder}/resources");
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomResource = resourceFiles[rng.RandiRange(0, resourceFiles.Length - 1)];
|
||||
var randomFile = ResourceLoader.Load<ConsumableItemStats>($"{consumableFolder}/resources/{randomResource}");
|
||||
consumable.Stats = randomFile;
|
||||
_game.AddChild(consumable);
|
||||
consumable.GlobalPosition = vector;
|
||||
var consumableFolder = "res://src/items/consumable";
|
||||
var restorativeScene = GD.Load<PackedScene>($"{consumableFolder}/ConsumableItem.tscn");
|
||||
var consumable = restorativeScene.Instantiate<ConsumableItem>();
|
||||
var resourceFiles = DirAccess.GetFilesAt($"{consumableFolder}/resources");
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomResource = resourceFiles[rng.RandiRange(0, resourceFiles.Length - 1)];
|
||||
var randomFile = ResourceLoader.Load<ConsumableItemStats>($"{consumableFolder}/resources/{randomResource}");
|
||||
consumable.Stats = randomFile;
|
||||
_game.AddChild(consumable);
|
||||
consumable.GlobalPosition = vector;
|
||||
}
|
||||
|
||||
public void HealAllEnemiesAndPlayerInRoomToFull()
|
||||
{
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
currentRoom.EnemiesInRoom.ForEach(e => e.HealthComponent.SetCurrentHealth(e.HealthComponent.MaximumHP.Value));
|
||||
_player.HealthComponent.SetCurrentHealth(_player.HealthComponent.MaximumHP.Value);
|
||||
currentRoom.EnemiesInRoom.ForEach(e => e.HealthComponent.SetCurrentHealth(e.HealthComponent.MaximumHP.Value));
|
||||
_player.HealthComponent.SetCurrentHealth(_player.HealthComponent.MaximumHP.Value);
|
||||
}
|
||||
|
||||
public void AbsorbHPFromAllEnemiesInRoom()
|
||||
{
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
var hpToAbsorb = 0.0;
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
var absorbAmount = enemy.HealthComponent.MaximumHP.Value * 0.05;
|
||||
enemy.HealthComponent.Damage((int)absorbAmount);
|
||||
hpToAbsorb += absorbAmount;
|
||||
enemy.OnAbsorb();
|
||||
}
|
||||
_player.HealthComponent.Heal((int)hpToAbsorb);
|
||||
GD.Print("HP to absorb: " + hpToAbsorb);
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
var hpToAbsorb = 0.0;
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
var absorbAmount = enemy.HealthComponent.MaximumHP.Value * 0.05;
|
||||
enemy.HealthComponent.Damage((int)absorbAmount);
|
||||
hpToAbsorb += absorbAmount;
|
||||
enemy.OnAbsorb();
|
||||
}
|
||||
_player.HealthComponent.Heal((int)hpToAbsorb);
|
||||
GD.Print("HP to absorb: " + hpToAbsorb);
|
||||
}
|
||||
|
||||
public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
|
||||
{
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
var currentRoom = _map.GetPlayersCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(20, elementType), 10, enemy.ElementalResistanceSet);
|
||||
enemy.HealthComponent.Damage(damageDealt);
|
||||
}
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
var damageDealt = DamageCalculator.CalculateDamage(new AttackData(20, elementType), 10, enemy.ElementalResistanceSet);
|
||||
enemy.HealthComponent.Damage(damageDealt);
|
||||
}
|
||||
}
|
||||
|
||||
public void SwapHPandVT()
|
||||
{
|
||||
var oldHp = _player.HealthComponent.CurrentHP.Value;
|
||||
var oldVt = _player.VTComponent.CurrentVT.Value;
|
||||
var oldHp = _player.HealthComponent.CurrentHP.Value;
|
||||
var oldVt = _player.VTComponent.CurrentVT.Value;
|
||||
|
||||
_player.HealthComponent.SetCurrentHealth(oldVt);
|
||||
_player.VTComponent.SetVT(oldHp);
|
||||
SfxDatabase.Instance.Play(SoundEffect.SwapHPAndVT);
|
||||
_player.HealthComponent.SetCurrentHealth(oldVt);
|
||||
_player.VTComponent.SetVT(oldHp);
|
||||
SfxDatabase.Instance.Play(SoundEffect.SwapHPAndVT);
|
||||
}
|
||||
|
||||
public void RandomEffect(EffectItem item)
|
||||
{
|
||||
var itemEffects = Enum.GetValues<UsableItemTag>().ToList();
|
||||
itemEffects.Remove(UsableItemTag.RandomEffect);
|
||||
itemEffects.Remove(UsableItemTag.None);
|
||||
var randomEffect = new Godot.Collections.Array<UsableItemTag>(itemEffects).PickRandom();
|
||||
item.SetEffectTag(randomEffect);
|
||||
_game.UseItem(item);
|
||||
var itemEffects = Enum.GetValues<UsableItemTag>().ToList();
|
||||
itemEffects.Remove(UsableItemTag.RandomEffect);
|
||||
itemEffects.Remove(UsableItemTag.None);
|
||||
var randomEffect = new Godot.Collections.Array<UsableItemTag>(itemEffects).PickRandom();
|
||||
item.SetEffectTag(randomEffect);
|
||||
_game.UseItem(item);
|
||||
}
|
||||
|
||||
public void RaiseCurrentWeaponAttack()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedWeapon.Value.ItemName))
|
||||
return;
|
||||
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedWeapon.Value.ItemName))
|
||||
return;
|
||||
|
||||
var currentWeapon = (Weapon)_player.EquipmentComponent.EquippedWeapon.Value;
|
||||
currentWeapon.IncreaseWeaponAttack(1);
|
||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||
var currentWeapon = (Weapon)_player.EquipmentComponent.EquippedWeapon.Value;
|
||||
currentWeapon.IncreaseWeaponAttack(1);
|
||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||
}
|
||||
|
||||
public void RaiseCurrentArmorDefense()
|
||||
{
|
||||
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName))
|
||||
return;
|
||||
if (string.IsNullOrEmpty(_player.EquipmentComponent.EquippedArmor.Value.ItemName))
|
||||
return;
|
||||
|
||||
var currentArmor = (Armor)_player.EquipmentComponent.EquippedArmor.Value;
|
||||
currentArmor.IncreaseArmorDefense(1);
|
||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||
var currentArmor = (Armor)_player.EquipmentComponent.EquippedArmor.Value;
|
||||
currentArmor.IncreaseArmorDefense(1);
|
||||
SfxDatabase.Instance.Play(SoundEffect.IncreaseStat);
|
||||
}
|
||||
|
||||
public void RaiseLevel() => _player.LevelUp();
|
||||
|
||||
public void TeleportToRandomRoom(IEnemy enemy)
|
||||
{
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = enemy.GetCurrentRoom(rooms);
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = enemy.GetCurrentRoom(rooms);
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
|
||||
enemy.MoveEnemyToNewRoom(randomRoom);
|
||||
enemy.MoveEnemyToNewRoom(randomRoom);
|
||||
}
|
||||
|
||||
public void TeleportToRandomRoom(IPlayer player)
|
||||
{
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
|
||||
var currentRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
|
||||
var currentRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
|
||||
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var spawnPoint = randomRoom.PlayerSpawn;
|
||||
player.TeleportPlayer((spawnPoint.Rotation, spawnPoint.Position));
|
||||
SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom);
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var spawnPoint = randomRoom.PlayerSpawn;
|
||||
player.TeleportPlayer((spawnPoint.Rotation, spawnPoint.Position));
|
||||
SfxDatabase.Instance.Play(SoundEffect.TeleportToRandomRoom);
|
||||
}
|
||||
|
||||
public void ChangeAffinity(ThrowableItem throwableItem)
|
||||
{
|
||||
var maximumElements = Enum.GetNames(typeof(ElementType)).Length;
|
||||
var newElement = ((int)throwableItem.ElementType + 1) % maximumElements;
|
||||
throwableItem.SetElementType((ElementType)newElement);
|
||||
var maximumElements = Enum.GetNames(typeof(ElementType)).Length;
|
||||
var newElement = ((int)throwableItem.ElementType + 1) % maximumElements;
|
||||
throwableItem.SetElementType((ElementType)newElement);
|
||||
|
||||
// TODO: Make this an inventory animation to cycle through elements.
|
||||
throwableItem.SetDescription(
|
||||
$"Inflicts {throwableItem.ElementType} damage when thrown." +
|
||||
$"{System.Environment.NewLine}Use item to change Affinity.");
|
||||
// TODO: Make this an inventory animation to cycle through elements.
|
||||
throwableItem.SetDescription(
|
||||
$"Inflicts {throwableItem.ElementType} damage when thrown." +
|
||||
$"{System.Environment.NewLine}Use item to change Affinity.");
|
||||
|
||||
throwableItem.SetCount(throwableItem.Count + 1);
|
||||
throwableItem.SetCount(throwableItem.Count + 1);
|
||||
}
|
||||
|
||||
public void WarpToExit(IPlayer player)
|
||||
public void WarpToExit()
|
||||
{
|
||||
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
|
||||
if (exitRoom.PlayerDiscoveredRoom)
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.TeleportToExit);
|
||||
player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, exitRoom.PlayerSpawn.Position));
|
||||
}
|
||||
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
|
||||
if (exitRoom.PlayerDiscoveredRoom)
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.TeleportToExit);
|
||||
_player.TeleportPlayer((exitRoom.PlayerSpawn.Rotation, exitRoom.PlayerSpawn.Position));
|
||||
}
|
||||
}
|
||||
|
||||
public void DamagesPlayer(int damage)
|
||||
{
|
||||
_player.TakeDamage(new AttackData(damage, ElementType.None, true, true));
|
||||
}
|
||||
|
||||
public void RerollItem(InventoryItem itemToReroll)
|
||||
{
|
||||
var itemReroller = new ItemReroller(ItemDatabase.Instance);
|
||||
itemReroller.RerollItem(itemToReroll, _player.Inventory);
|
||||
}
|
||||
|
||||
public T GetRandomItemOfType<T>(T itemToExclude = null)
|
||||
where T : InventoryItem => ItemDatabase.Instance.PickItem(itemToExclude);
|
||||
|
||||
public void RandomSpell()
|
||||
{
|
||||
throw new NotImplementedException("Spells not implemented yet.");
|
||||
}
|
||||
|
||||
public void DropTo1HPAndGainRareItem<T>()
|
||||
where T : InventoryItem
|
||||
{
|
||||
_player.HealthComponent.SetCurrentHealth(1);
|
||||
_player.Inventory.TryAdd(ItemDatabase.Instance.PickRareItem<T>());
|
||||
}
|
||||
|
||||
public void TradeRandomItem<T>(BoxItem box)
|
||||
where T : InventoryItem
|
||||
{
|
||||
var tradableItems = _player.Inventory.Items.OfType<T>().Where(x => x != box).ToList();
|
||||
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomIndex = rng.RandiRange(0, tradableItems.Count - 1);
|
||||
var randomItem = tradableItems[randomIndex];
|
||||
if (randomItem is EquipableItem equipableItem)
|
||||
{
|
||||
if (_player.EquipmentComponent.IsItemEquipped(equipableItem))
|
||||
_player.Unequip(equipableItem);
|
||||
}
|
||||
_player.Inventory.Remove(randomItem);
|
||||
|
||||
GetRandomItemOfType<T>();
|
||||
}
|
||||
|
||||
public IEnumerable<InventoryItem> TradeAllRandomItems<T>(BoxItem box)
|
||||
where T : InventoryItem
|
||||
{
|
||||
var newInventory = new List<InventoryItem>();
|
||||
var items = _player.Inventory.Items.OfType<T>().Where(x => x != box).ToList();
|
||||
foreach (var item in items)
|
||||
newInventory.Add(GetRandomItemOfType<T>());
|
||||
|
||||
return newInventory;
|
||||
}
|
||||
|
||||
public void GetUnobtainedItem()
|
||||
{
|
||||
var pickableItems = ItemDatabase.Instance.Items.Except(_player.Inventory.Items).ToList();
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomIndex = rng.RandiRange(0, pickableItems.Count - 1);
|
||||
var selectedItem = pickableItems[randomIndex];
|
||||
|
||||
if (selectedItem is ThrowableItem throwableItem)
|
||||
throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount));
|
||||
|
||||
_player.Inventory.TryAdd(selectedItem);
|
||||
}
|
||||
|
||||
public void GetBasicItem<T>()
|
||||
where T : InventoryItem
|
||||
{
|
||||
_player.Inventory.TryAdd(ItemDatabase.Instance.PickBasicItem<T>());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,33 @@ public class ItemDatabase
|
||||
|
||||
public T PickItem<T>(T itemToExclude = null)
|
||||
where T : InventoryItem
|
||||
{
|
||||
var itemsToSelectFrom = Items.OfType<T>();
|
||||
return PickItemInternal(itemsToSelectFrom, itemToExclude);
|
||||
}
|
||||
|
||||
public T PickRareItem<T>(T itemToExclude = null)
|
||||
where T : InventoryItem
|
||||
{
|
||||
var getRareItems = Items.OfType<T>().Where(x => x.SpawnRate < 0.1f);
|
||||
return PickItemInternal(getRareItems, itemToExclude);
|
||||
}
|
||||
|
||||
public T PickBasicItem<T>(T itemToExclude = null)
|
||||
where T : InventoryItem
|
||||
{
|
||||
var getBasicItems = Items.OfType<T>().Where(x => x.SpawnRate > 0.5f);
|
||||
return PickItemInternal(getBasicItems, itemToExclude);
|
||||
}
|
||||
|
||||
private T PickItemInternal<T>(IEnumerable<T> itemsToSelectFrom, T itemToExclude = null)
|
||||
where T : InventoryItem
|
||||
{
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
|
||||
var itemsToSelectFrom = Items;
|
||||
|
||||
if (itemToExclude is not null)
|
||||
itemsToSelectFrom = [.. itemsToSelectFrom.OfType<T>().Where(x => x.ItemName != itemToExclude.ItemName)];
|
||||
itemsToSelectFrom = [.. itemsToSelectFrom.Where(x => x.ItemName != itemToExclude.ItemName)];
|
||||
|
||||
var weights = itemsToSelectFrom.Select(x => x.SpawnRate).ToArray();
|
||||
var selectedItem = itemsToSelectFrom.ToArray()[rng.RandWeighted(weights)];
|
||||
@@ -33,7 +52,7 @@ public class ItemDatabase
|
||||
if (selectedItem is ThrowableItem throwableItem)
|
||||
throwableItem.SetCount(rng.RandiRange(throwableItem.Stats.MinimumCount, throwableItem.Stats.MaximumCount));
|
||||
|
||||
return (T)selectedItem;
|
||||
return selectedItem;
|
||||
}
|
||||
|
||||
private ItemDatabase()
|
||||
@@ -45,6 +64,7 @@ public class ItemDatabase
|
||||
var throwableResources = DirAccess.GetFilesAt("res://src/items/throwable/resources/");
|
||||
var consumableResources = DirAccess.GetFilesAt("res://src/items/consumable/resources/");
|
||||
var effectResources = DirAccess.GetFilesAt("res://src/items/effect/resources/");
|
||||
var boxResources = DirAccess.GetFilesAt("res://src/items/box/resources/");
|
||||
|
||||
foreach (var armor in armorResources)
|
||||
{
|
||||
@@ -100,6 +120,15 @@ public class ItemDatabase
|
||||
database.Add(effectItemScene);
|
||||
}
|
||||
|
||||
foreach (var boxItem in boxResources)
|
||||
{
|
||||
var boxItemInfo = GD.Load<BoxItemStats>($"res://src/items/box/resources/{boxItem}");
|
||||
var boxItemScene = ResourceLoader.Load<PackedScene>("res://src/items/box/BoxItem.tscn").Instantiate<BoxItem>();
|
||||
boxItemScene.Stats = boxItemInfo;
|
||||
if (!database.Contains(boxItemScene))
|
||||
database.Add(boxItemScene);
|
||||
}
|
||||
|
||||
Items = [.. database];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,21 @@ public class ItemReroller
|
||||
return rolledItem;
|
||||
}
|
||||
|
||||
public InventoryItem RerollItemToAny(InventoryItem itemToReroll, IInventory inventory, bool insertIntoInventory = true)
|
||||
{
|
||||
var currentIndex = inventory.Items.IndexOf(itemToReroll);
|
||||
|
||||
if (insertIntoInventory)
|
||||
inventory.Remove(itemToReroll);
|
||||
|
||||
var rolledItem = _database.PickItem(itemToReroll);
|
||||
|
||||
if (insertIntoInventory)
|
||||
inventory.TryInsert(rolledItem, currentIndex);
|
||||
|
||||
return rolledItem;
|
||||
}
|
||||
|
||||
private Weapon RerollItemInternal(Weapon itemToReroll) => _database.PickItem(itemToReroll);
|
||||
private Armor RerollItemInternal(Armor itemToReroll) => _database.PickItem(itemToReroll);
|
||||
private Accessory RerollItemInternal(Accessory itemToReroll) => _database.PickItem(itemToReroll);
|
||||
|
||||
12
Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs
Normal file
12
Zennysoft.Game.Ma/src/items/accessory/BoxItemStats.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
|
||||
namespace Zennysoft.Game.Ma;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("box_item_stat_type")]
|
||||
public partial class BoxItemStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
public int DamageToPlayer { get; set; } = 10;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
uid://vuavr681au06
|
||||
@@ -4,12 +4,12 @@ importer="scene"
|
||||
importer_version=1
|
||||
type="PackedScene"
|
||||
uid="uid://dkpgrhj14phdd"
|
||||
path="res://.godot/imported/plastique.glb-38f4438846eaa3d64b225272714c5d02.scn"
|
||||
path="res://.godot/imported/plastique.glb-5845ad959844e1ca0c9791ff0287bc66.scn"
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/items/assetts/plastique.glb"
|
||||
dest_files=["res://.godot/imported/plastique.glb-38f4438846eaa3d64b225272714c5d02.scn"]
|
||||
source_file="res://src/items/assets/plastique.glb"
|
||||
dest_files=["res://.godot/imported/plastique.glb-5845ad959844e1ca0c9791ff0287bc66.scn"]
|
||||
|
||||
[params]
|
||||
|
||||
|
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
@@ -3,7 +3,7 @@
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dkqs4x4pi18on"
|
||||
path="res://.godot/imported/plastique_plastique.png-3ad121f0468f0ec1d61934d8a0e41cb7.ctex"
|
||||
path="res://.godot/imported/plastique_plastique.png-06bcea5737da44088a0bd794735523f0.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
@@ -13,8 +13,8 @@ generator_parameters={
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://src/items/assetts/plastique_plastique.png"
|
||||
dest_files=["res://.godot/imported/plastique_plastique.png-3ad121f0468f0ec1d61934d8a0e41cb7.ctex"]
|
||||
source_file="res://src/items/assets/plastique_plastique.png"
|
||||
dest_files=["res://.godot/imported/plastique_plastique.png-06bcea5737da44088a0bd794735523f0.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
37
Zennysoft.Game.Ma/src/items/box/BoxItem.cs
Normal file
37
Zennysoft.Game.Ma/src/items/box/BoxItem.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using Zennysoft.Game.Ma;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
|
||||
[Meta(typeof(IAutoNode)), Id("box_item")]
|
||||
public partial class BoxItem : InventoryItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Node] private Sprite3D _sprite { get; set; }
|
||||
|
||||
[Export]
|
||||
[Save("box_stats")]
|
||||
public BoxItemStats Stats { get; set; } = new BoxItemStats();
|
||||
|
||||
public override string ItemName => Stats.Name;
|
||||
|
||||
public override string Description => Stats.Description;
|
||||
|
||||
public override float SpawnRate => Stats.SpawnRate;
|
||||
|
||||
public override int ThrowDamage => Stats.ThrowDamage;
|
||||
|
||||
public override float ThrowSpeed => Stats.ThrowSpeed;
|
||||
|
||||
public override ItemTag ItemTag => Stats.ItemTag;
|
||||
|
||||
public override Texture2D GetTexture() => Stats.Texture;
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
_sprite.Texture = Stats.Texture;
|
||||
}
|
||||
}
|
||||
1
Zennysoft.Game.Ma/src/items/box/BoxItem.cs.uid
Normal file
1
Zennysoft.Game.Ma/src/items/box/BoxItem.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cqqqj4hgywst4
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://bguomljidwgto"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/items/box/BoxItem.cs" id="1_holk0"]
|
||||
[ext_resource type="Script" uid="uid://cqqqj4hgywst4" path="res://src/items/box/BoxItem.cs" id="1_holk0"]
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="2_holk0"]
|
||||
|
||||
[sub_resource type="CylinderShape3D" id="CylinderShape3D_x6u08"]
|
||||
@@ -17,7 +17,6 @@ axis_lock_angular_x = true
|
||||
axis_lock_angular_y = true
|
||||
axis_lock_angular_z = true
|
||||
script = ExtResource("1_holk0")
|
||||
Stats = null
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.00908482, 0)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://deebat2kuxfo3"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_p2ro7"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_k6pqw"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_k6pqw")
|
||||
DamageToPlayer = 0
|
||||
Name = "Blood Acquisition"
|
||||
Description = "Contains a rare item but lowers current HP to 1."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 10
|
||||
Texture = ExtResource("1_p2ro7")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
26
Zennysoft.Game.Ma/src/items/box/resources/ChaoticPrayer.tres
Normal file
26
Zennysoft.Game.Ma/src/items/box/resources/ChaoticPrayer.tres
Normal file
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://k0uhsuxvyegw"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_yf4yo"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_xe8mc"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_xe8mc")
|
||||
DamageToPlayer = 0
|
||||
Name = "Chaotic Prayer"
|
||||
Description = "Converts all items into random items."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 12
|
||||
Texture = ExtResource("1_yf4yo")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
25
Zennysoft.Game.Ma/src/items/box/resources/EmptyPromise.tres
Normal file
25
Zennysoft.Game.Ma/src/items/box/resources/EmptyPromise.tres
Normal file
@@ -0,0 +1,25 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://cgkorwblwr12t"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_650jj"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="1_i336w"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_i336w")
|
||||
Name = "Empty Promise"
|
||||
Description = "An empty box."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 0
|
||||
Texture = ExtResource("1_650jj")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://bit6jsgs4yl7t"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_85ci2"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_pe0kd"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_pe0kd")
|
||||
DamageToPlayer = 0
|
||||
Name = "Fashionable Acquisition"
|
||||
Description = "Contains a random armor."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 6
|
||||
Texture = ExtResource("1_85ci2")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://g3buxgpmjcio"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_3hy40"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_kb1l2"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_kb1l2")
|
||||
DamageToPlayer = 0
|
||||
Name = "Furious Acquisition"
|
||||
Description = "Contains a random weapon."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 5
|
||||
Texture = ExtResource("1_3hy40")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://icdlurnmjryh"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_svub6"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_iw3ll"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_iw3ll")
|
||||
DamageToPlayer = 0
|
||||
Name = "Healthy Acquisition"
|
||||
Description = "Contains a random restorative."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 4
|
||||
Texture = ExtResource("1_svub6")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://b2buq6ckkam7i"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_dwyk7"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_pssvy"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_pssvy")
|
||||
DamageToPlayer = 0
|
||||
Name = "Identity Acquisition"
|
||||
Description = "Contains a random mask."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 9
|
||||
Texture = ExtResource("1_dwyk7")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
26
Zennysoft.Game.Ma/src/items/box/resources/Malfunction.tres
Normal file
26
Zennysoft.Game.Ma/src/items/box/resources/Malfunction.tres
Normal file
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://dsb2gcjeme5yy"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_3scao"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_vgter"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_vgter")
|
||||
DamageToPlayer = 10
|
||||
Name = "Malfunction"
|
||||
Description = "Damages self."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 3
|
||||
Texture = ExtResource("1_3scao")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
@@ -0,0 +1,26 @@
|
||||
[gd_resource type="Resource" script_class="BoxItemStats" load_steps=3 format=3 uid="uid://cf8mf2qguf7q1"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://bg47n2tmintm0" path="res://src/items/consumable/textures/past self remnant.PNG" id="1_1eojb"]
|
||||
[ext_resource type="Script" uid="uid://vuavr681au06" path="res://src/items/accessory/BoxItemStats.cs" id="2_ucc84"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("2_ucc84")
|
||||
DamageToPlayer = 0
|
||||
Name = "Speculative Acquisition"
|
||||
Description = "Contains a random box."
|
||||
SpawnRate = 0.5
|
||||
BonusAttack = 0
|
||||
BonusDefense = 0
|
||||
BonusLuck = 0.05
|
||||
BonusHP = 0
|
||||
BonusVT = 0
|
||||
AeolicResistance = 0
|
||||
TelluricResistance = 0
|
||||
HydricResistance = 0
|
||||
IgneousResistance = 0
|
||||
FerrumResistance = 0
|
||||
ThrowSpeed = 12.0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 7
|
||||
Texture = ExtResource("1_1eojb")
|
||||
metadata/_custom_type_script = "uid://vuavr681au06"
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://da8mhruqpgh6r" path="res://src/items/misc/SetItem.cs" id="1_m8dyi"]
|
||||
[ext_resource type="AudioStream" uid="uid://bjcersd5id8ee" path="res://src/audio/sfx/ITEM_PLASTIQUETIMER.ogg" id="2_kgxna"]
|
||||
[ext_resource type="Texture2D" uid="uid://dkqs4x4pi18on" path="res://src/items/assetts/plastique_plastique.png" id="2_m8dyi"]
|
||||
[ext_resource type="Texture2D" uid="uid://dkqs4x4pi18on" path="res://src/items/assets/plastique_plastique.png" id="2_m8dyi"]
|
||||
|
||||
[sub_resource type="Animation" id="Animation_eat5q"]
|
||||
length = 0.001
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System;
|
||||
using Zennysoft.Ma.Adapter;
|
||||
using Zennysoft.Ma.Adapter.Entity;
|
||||
|
||||
|
||||
@@ -20,34 +20,34 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
|
||||
|
||||
public void InitializeDungeon()
|
||||
{
|
||||
Rooms = [];
|
||||
Rooms = FindAllDungeonRooms([.. GetChildren()], Rooms);
|
||||
_playerSpawnPoint = RandomizePlayerSpawnPoint();
|
||||
Rooms = [];
|
||||
Rooms = FindAllDungeonRooms([.. GetChildren()], Rooms);
|
||||
_playerSpawnPoint = RandomizePlayerSpawnPoint();
|
||||
}
|
||||
|
||||
public void SpawnEnemies(DungeonFloorNode floorNode)
|
||||
{
|
||||
var enemyOdds = new Godot.Collections.Dictionary<EnemyType, float>
|
||||
{
|
||||
{ EnemyType.Sproingy, floorNode.Sproingy },
|
||||
{ EnemyType.Michael, floorNode.Michael },
|
||||
{ EnemyType.FilthEater, floorNode.FilthEater },
|
||||
{ EnemyType.Sara, floorNode.Sara },
|
||||
{ EnemyType.Ballos, floorNode.Ballos },
|
||||
{ EnemyType.Chariot, floorNode.Chariot },
|
||||
{ EnemyType.Chinthe, floorNode.Chinthe },
|
||||
{ EnemyType.AmbassadorGreen, floorNode.GreenAmbassador },
|
||||
{ EnemyType.AmbassadorRed, floorNode.RedAmbassador },
|
||||
{ EnemyType.AmbassadorSteel, floorNode.SteelAmbassador },
|
||||
{ EnemyType.AgniDemon, floorNode.AgniDemon },
|
||||
{ EnemyType.AqueousDemon, floorNode.AqueosDemon },
|
||||
{ EnemyType.Palan, floorNode.Palan },
|
||||
{ EnemyType.ShieldOfHeaven, floorNode.ShieldOfHeaven },
|
||||
{ EnemyType.GoldSproingy, floorNode.GoldSproingy },
|
||||
};
|
||||
var monsterRooms = Rooms.OfType<MonsterRoom>();
|
||||
foreach (var room in monsterRooms)
|
||||
room.SpawnEnemies(enemyOdds);
|
||||
var enemyOdds = new Godot.Collections.Dictionary<EnemyType, float>
|
||||
{
|
||||
{ EnemyType.Sproingy, floorNode.Sproingy },
|
||||
{ EnemyType.Michael, floorNode.Michael },
|
||||
{ EnemyType.FilthEater, floorNode.FilthEater },
|
||||
{ EnemyType.Sara, floorNode.Sara },
|
||||
{ EnemyType.Ballos, floorNode.Ballos },
|
||||
{ EnemyType.Chariot, floorNode.Chariot },
|
||||
{ EnemyType.Chinthe, floorNode.Chinthe },
|
||||
{ EnemyType.AmbassadorGreen, floorNode.GreenAmbassador },
|
||||
{ EnemyType.AmbassadorRed, floorNode.RedAmbassador },
|
||||
{ EnemyType.AmbassadorSteel, floorNode.SteelAmbassador },
|
||||
{ EnemyType.AgniDemon, floorNode.AgniDemon },
|
||||
{ EnemyType.AqueousDemon, floorNode.AqueosDemon },
|
||||
{ EnemyType.Palan, floorNode.Palan },
|
||||
{ EnemyType.ShieldOfHeaven, floorNode.ShieldOfHeaven },
|
||||
{ EnemyType.GoldSproingy, floorNode.GoldSproingy },
|
||||
};
|
||||
var monsterRooms = Rooms.OfType<MonsterRoom>();
|
||||
foreach (var room in monsterRooms)
|
||||
room.SpawnEnemies(enemyOdds);
|
||||
}
|
||||
|
||||
public (Vector3 Rotation, Vector3 Position) GetPlayerSpawnPoint() { return (_playerSpawnPoint.Rotation, new Vector3(_playerSpawnPoint.GlobalPosition.X, 0, _playerSpawnPoint.GlobalPosition.Z)); }
|
||||
@@ -55,25 +55,25 @@ public partial class DungeonFloor : Node3D, IDungeonFloor
|
||||
|
||||
private Marker3D RandomizePlayerSpawnPoint()
|
||||
{
|
||||
var randomSpawnLocations = Rooms
|
||||
.OfType<MonsterRoom>()
|
||||
.Select(x => x.PlayerSpawn);
|
||||
var godotCollection = new Godot.Collections.Array<Marker3D>(randomSpawnLocations);
|
||||
var result = godotCollection.PickRandom();
|
||||
return result;
|
||||
var randomSpawnLocations = Rooms
|
||||
.OfType<MonsterRoom>()
|
||||
.Select(x => x.PlayerSpawn);
|
||||
var godotCollection = new Godot.Collections.Array<Marker3D>(randomSpawnLocations);
|
||||
var result = godotCollection.PickRandom();
|
||||
return result;
|
||||
}
|
||||
|
||||
private static ImmutableList<IDungeonRoom> FindAllDungeonRooms(List<Node> nodesToSearch, ImmutableList<IDungeonRoom> roomsFound)
|
||||
{
|
||||
if (nodesToSearch.Count == 0)
|
||||
return roomsFound;
|
||||
if (nodesToSearch.Count == 0)
|
||||
return roomsFound;
|
||||
|
||||
foreach (var node in nodesToSearch)
|
||||
{
|
||||
if (node is IDungeonRoom dungeonRoom)
|
||||
roomsFound = roomsFound.Add(dungeonRoom);
|
||||
}
|
||||
foreach (var node in nodesToSearch)
|
||||
{
|
||||
if (node is IDungeonRoom dungeonRoom)
|
||||
roomsFound = roomsFound.Add(dungeonRoom);
|
||||
}
|
||||
|
||||
return FindAllDungeonRooms([.. nodesToSearch.SelectMany(x => x.GetChildren())], roomsFound);
|
||||
return FindAllDungeonRooms([.. nodesToSearch.SelectMany(x => x.GetChildren())], roomsFound);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,47 +28,47 @@ public abstract partial class DungeonRoom : Node3D, IDungeonRoom
|
||||
|
||||
public void Setup()
|
||||
{
|
||||
_enemiesInRoom = [];
|
||||
if (_room != null)
|
||||
{
|
||||
_room.BodyEntered += Room_BodyEntered;
|
||||
_room.BodyExited += Room_BodyExited;
|
||||
}
|
||||
_enemiesInRoom = [];
|
||||
if (_room != null)
|
||||
{
|
||||
_room.BodyEntered += Room_BodyEntered;
|
||||
_room.BodyExited += Room_BodyExited;
|
||||
}
|
||||
}
|
||||
|
||||
private void Room_BodyExited(Node3D body)
|
||||
{
|
||||
if (body is IEnemy enemy)
|
||||
_enemiesInRoom = _enemiesInRoom.Remove(enemy);
|
||||
if (body is IPlayer)
|
||||
_isPlayerInRoom = false;
|
||||
if (body is IEnemy enemy)
|
||||
_enemiesInRoom = _enemiesInRoom.Remove(enemy);
|
||||
if (body is IPlayer)
|
||||
_isPlayerInRoom = false;
|
||||
}
|
||||
private void Room_BodyEntered(Node3D body)
|
||||
{
|
||||
if (body is IEnemy enemy)
|
||||
_enemiesInRoom = _enemiesInRoom.Add(enemy);
|
||||
if (body is IPlayer)
|
||||
if (_playerDiscoveredRoom)
|
||||
_isPlayerInRoom = true;
|
||||
else
|
||||
OnPlayerDiscoveringRoom();
|
||||
if (body is IEnemy enemy)
|
||||
_enemiesInRoom = _enemiesInRoom.Add(enemy);
|
||||
if (body is IPlayer)
|
||||
if (_playerDiscoveredRoom)
|
||||
_isPlayerInRoom = true;
|
||||
else
|
||||
OnPlayerDiscoveringRoom();
|
||||
}
|
||||
|
||||
public ImmutableList<IEnemy> GetEnemiesInCurrentRoom()
|
||||
{
|
||||
return _enemiesInRoom;
|
||||
return _enemiesInRoom;
|
||||
}
|
||||
|
||||
private void OnPlayerDiscoveringRoom()
|
||||
{
|
||||
_isPlayerInRoom = true;
|
||||
_playerDiscoveredRoom = true;
|
||||
MinimapShadow.Hide();
|
||||
_isPlayerInRoom = true;
|
||||
_playerDiscoveredRoom = true;
|
||||
MinimapShadow.Hide();
|
||||
}
|
||||
|
||||
public void OnExitTree()
|
||||
{
|
||||
_room.BodyEntered -= Room_BodyEntered;
|
||||
_room.BodyExited -= Room_BodyExited;
|
||||
_room.BodyEntered -= Room_BodyEntered;
|
||||
_room.BodyExited -= Room_BodyExited;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
[gd_scene load_steps=18 format=3 uid="uid://dl6h1djc27ddl"]
|
||||
[gd_scene load_steps=19 format=3 uid="uid://dl6h1djc27ddl"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c1nhqlem1ew3m" path="res://src/map/dungeon/code/Altar.cs" id="1_5jip8"]
|
||||
[ext_resource type="Resource" uid="uid://bqnfw6r4085yv" path="res://src/dialog/Altar.dialogue" id="2_7xfp0"]
|
||||
[ext_resource type="PackedScene" uid="uid://co0fmuno2pjc7" path="res://src/map/dungeon/models/Special Floors & Rooms/Altar/02_ALTAR_FLOOR_ZER0_VER.1.glb" id="2_xpi6o"]
|
||||
[ext_resource type="PackedScene" uid="uid://bdygmhgk4k0qh" path="res://src/items/box/BoxItem.tscn" id="6_rrmfo"]
|
||||
[ext_resource type="Shader" uid="uid://c4a68uhm5o2h4" path="res://src/map/map shaders/Altar Sky Environment.gdshader" id="27_lb4gb"]
|
||||
[ext_resource type="AudioStream" uid="uid://c4ud110da8efp" path="res://src/audio/AMB/amb_wind_loop_altar.wav" id="28_je2oh"]
|
||||
|
||||
@@ -212,3 +213,5 @@ collision_mask = 64
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="NoExitArea"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 72.5243, -2.06593, -2.02953)
|
||||
shape = SubResource("BoxShape3D_tp2pi")
|
||||
|
||||
[node name="Box Item" parent="." instance=ExtResource("6_rrmfo")]
|
||||
|
||||
@@ -2,9 +2,9 @@
|
||||
|
||||
[ext_resource type="Script" uid="uid://cuhfkyh3d7noa" path="res://src/map/dungeon/code/Overworld.cs" id="1_5hmt3"]
|
||||
[ext_resource type="Texture2D" uid="uid://co6h8vyi11sl2" path="res://src/map/overworld/Models/Overworld_CLOUD_RINGS_INNER_63.png" id="2_g6b7b"]
|
||||
[ext_resource type="AudioStream" uid="uid://dqmsaok6fyhe7" path="res://src/audio/AMB/amb_perlin.wav" id="2_wbbo3"]
|
||||
[ext_resource type="AudioStream" uid="uid://dl07vg00se7hd" path="res://src/audio/AMB/amb_white_noise.wav" id="3_c2gp5"]
|
||||
[ext_resource type="AudioStream" uid="uid://boypvgaweep8a" path="res://src/audio/AMB/amb_beach.wav" id="3_pvi8n"]
|
||||
[ext_resource type="AudioStream" uid="uid://dv045ax11vybl" path="res://src/audio/AMB/amb_perlin.wav" id="2_wbbo3"]
|
||||
[ext_resource type="AudioStream" uid="uid://dsc8xu78llst6" path="res://src/audio/AMB/amb_white_noise.wav" id="3_c2gp5"]
|
||||
[ext_resource type="AudioStream" uid="uid://7hb71ilkd7qh" path="res://src/audio/AMB/amb_beach.wav" id="3_pvi8n"]
|
||||
[ext_resource type="Texture2D" uid="uid://w33fr6exryiy" path="res://src/map/overworld/Models/Overworld_CLOUD_RINGS_INNER_37.png" id="3_uyygh"]
|
||||
[ext_resource type="Texture2D" uid="uid://dv10yaqvp3mub" path="res://src/map/overworld/Models/Overworld_CLOUD_RINGS_INNER_71.png" id="4_r8r3k"]
|
||||
[ext_resource type="Shader" uid="uid://brhf7s3riyag5" path="res://src/map/map shaders/Metal.gdshader" id="5_d1qcb"]
|
||||
|
||||
@@ -94,6 +94,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
|
||||
|
||||
#endregion
|
||||
|
||||
public bool CanEquipState { get; set; } = true;
|
||||
|
||||
private bool flipAttack = false;
|
||||
|
||||
@@ -101,6 +102,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
|
||||
|
||||
private bool _healthTimerActive = true;
|
||||
|
||||
private bool _debugSprint = false;
|
||||
|
||||
private float _knockbackStrength = 0.0f;
|
||||
private Vector3 _knockbackDirection = Vector3.Zero;
|
||||
|
||||
@@ -241,9 +244,9 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
|
||||
if (@event.IsActionPressed(GameInputs.Attack))
|
||||
Attack();
|
||||
if (@event.IsActionPressed(GameInputs.Sprint))
|
||||
Settings.MoveSpeed *= 2;
|
||||
if (@event.IsActionReleased(GameInputs.Sprint))
|
||||
Settings.MoveSpeed /= 2;
|
||||
_debugSprint = true;
|
||||
else if (@event.IsActionReleased(GameInputs.Sprint))
|
||||
_debugSprint = false;
|
||||
}
|
||||
|
||||
public void PlayTestAnimation()
|
||||
@@ -349,6 +352,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
|
||||
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
|
||||
var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized();
|
||||
var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration;
|
||||
if (_debugSprint)
|
||||
velocity *= 2;
|
||||
_knockbackStrength *= 0.9f;
|
||||
Transform = Transform with { Basis = transform.Basis };
|
||||
Velocity = velocity + (_knockbackDirection * _knockbackStrength);
|
||||
|
||||
@@ -411,7 +411,7 @@ tracks/0/loop_wrap = true
|
||||
tracks/0/keys = {
|
||||
"times": PackedFloat32Array(0),
|
||||
"transitions": PackedFloat32Array(1),
|
||||
"update": 0,
|
||||
"update": 1,
|
||||
"values": [&"default"]
|
||||
}
|
||||
tracks/1/type = "value"
|
||||
|
||||
@@ -60,146 +60,141 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
||||
private IItemSlot _currentlySelectedItem = null;
|
||||
private bool _enableMenuSound = false;
|
||||
|
||||
public override void _EnterTree()
|
||||
{
|
||||
SetProcessInput(false);
|
||||
}
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
ItemSlots = [ItemSlot1, ItemSlot2, ItemSlot3, ItemSlot4, ItemSlot5, ItemSlot6, ItemSlot7, ItemSlot8, ItemSlot9, ItemSlot10, ItemSlot11, ItemSlot12, ItemSlot13, ItemSlot14, ItemSlot15, ItemSlot16, ItemSlot17, ItemSlot18, ItemSlot19, ItemSlot20];
|
||||
_currentlySelectedItem = ItemSlot1;
|
||||
foreach (var item in ItemSlots)
|
||||
{
|
||||
item.ItemPressed += Item_Pressed;
|
||||
item.ItemEnterFocus += Item_FocusEntered;
|
||||
item.ItemExitFocus += Item_ItemExitFocus;
|
||||
}
|
||||
ItemSlots = [ItemSlot1, ItemSlot2, ItemSlot3, ItemSlot4, ItemSlot5, ItemSlot6, ItemSlot7, ItemSlot8, ItemSlot9, ItemSlot10, ItemSlot11, ItemSlot12, ItemSlot13, ItemSlot14, ItemSlot15, ItemSlot16, ItemSlot17, ItemSlot18, ItemSlot19, ItemSlot20];
|
||||
_currentlySelectedItem = ItemSlot1;
|
||||
foreach (var item in ItemSlots)
|
||||
{
|
||||
item.ItemPressed += Item_Pressed;
|
||||
item.ItemEnterFocus += Item_FocusEntered;
|
||||
item.ItemExitFocus += Item_ItemExitFocus;
|
||||
}
|
||||
|
||||
_player.AttackComponent.CurrentAttack.Sync += Attack_Sync;
|
||||
_player.AttackComponent.MaximumAttack.Sync += Attack_Sync;
|
||||
_player.DefenseComponent.CurrentDefense.Sync += Defense_Sync;
|
||||
_player.DefenseComponent.MaximumDefense.Sync += Defense_Sync;
|
||||
_player.EquipmentComponent.EquipmentChanged += EquipmentComponent_EquipmentChanged;
|
||||
_player.Inventory.InventoryChanged += Inventory_InventoryChanged;
|
||||
_player.AttackComponent.CurrentAttack.Sync += Attack_Sync;
|
||||
_player.AttackComponent.MaximumAttack.Sync += Attack_Sync;
|
||||
_player.DefenseComponent.CurrentDefense.Sync += Defense_Sync;
|
||||
_player.DefenseComponent.MaximumDefense.Sync += Defense_Sync;
|
||||
_player.EquipmentComponent.EquipmentChanged += EquipmentComponent_EquipmentChanged;
|
||||
_player.Inventory.InventoryChanged += Inventory_InventoryChanged;
|
||||
|
||||
UseButton.Pressed += UseButtonPressed;
|
||||
ThrowButton.Pressed += ThrowButtonPressed;
|
||||
DropButton.Pressed += DropButtonPressed;
|
||||
UseButton.Pressed += UseButtonPressed;
|
||||
ThrowButton.Pressed += ThrowButtonPressed;
|
||||
DropButton.Pressed += DropButtonPressed;
|
||||
|
||||
UseButton.FocusEntered += ActionButtonFocusChanged;
|
||||
ThrowButton.FocusEntered += ActionButtonFocusChanged;
|
||||
DropButton.FocusEntered += ActionButtonFocusChanged;
|
||||
UseButton.FocusEntered += ActionButtonFocusChanged;
|
||||
ThrowButton.FocusEntered += ActionButtonFocusChanged;
|
||||
DropButton.FocusEntered += ActionButtonFocusChanged;
|
||||
|
||||
VisibilityChanged += InventoryMenu_VisibilityChanged;
|
||||
VisibilityChanged += InventoryMenu_VisibilityChanged;
|
||||
SetProcessUnhandledInput(false);
|
||||
}
|
||||
|
||||
private void ActionButtonFocusChanged()
|
||||
{
|
||||
if (!_enableMenuSound)
|
||||
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
|
||||
if (!_enableMenuSound)
|
||||
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
|
||||
}
|
||||
|
||||
public override void _UnhandledInput(InputEvent @event)
|
||||
{
|
||||
if (!Visible)
|
||||
return;
|
||||
if ((!Input.IsActionJustPressed(GameInputs.UiUp) && Input.IsActionPressed(GameInputs.UiUp)) || (!Input.IsActionJustPressed(GameInputs.UiDown) && Input.IsActionPressed(GameInputs.UiDown)))
|
||||
AcceptEvent();
|
||||
|
||||
if ((!Input.IsActionJustPressed(GameInputs.UiUp) && Input.IsActionPressed(GameInputs.UiUp)) || (!Input.IsActionJustPressed(GameInputs.UiDown) && Input.IsActionPressed(GameInputs.UiDown)))
|
||||
AcceptEvent();
|
||||
if (Input.IsActionJustPressed(GameInputs.UiCancel) && (UseItemPrompt.Visible))
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
||||
AcceptEvent();
|
||||
HideUserActionPrompt();
|
||||
}
|
||||
else if (Input.IsActionJustPressed(GameInputs.UiCancel))
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
||||
AcceptEvent();
|
||||
_gameRepo.CloseInventory();
|
||||
}
|
||||
|
||||
if (Input.IsActionJustPressed(GameInputs.UiCancel) && (UseButton.HasFocus() || DropButton.HasFocus() || ThrowButton.HasFocus()))
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
||||
AcceptEvent();
|
||||
HideUserActionPrompt();
|
||||
}
|
||||
else if (Input.IsActionJustPressed(GameInputs.UiCancel))
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
||||
AcceptEvent();
|
||||
_gameRepo.CloseInventory();
|
||||
}
|
||||
if (Input.IsActionJustPressed(GameInputs.InventorySort))
|
||||
{
|
||||
var isChanged = _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value);
|
||||
if (!isChanged)
|
||||
return;
|
||||
|
||||
if (Input.IsActionJustPressed(GameInputs.InventorySort))
|
||||
{
|
||||
var isChanged = _player.Inventory.Sort(_player.EquipmentComponent.EquippedWeapon.Value, _player.EquipmentComponent.EquippedArmor.Value, _player.EquipmentComponent.EquippedAccessory.Value);
|
||||
if (!isChanged)
|
||||
return;
|
||||
|
||||
SfxDatabase.Instance.Play(SoundEffect.SortInventory);
|
||||
Inventory_InventoryChanged();
|
||||
foreach (var slot in ItemSlots)
|
||||
slot.SetItemStyle();
|
||||
Item_ItemExitFocus(_currentlySelectedItem);
|
||||
_currentlySelectedItem = ItemSlot1;
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
}
|
||||
SfxDatabase.Instance.Play(SoundEffect.SortInventory);
|
||||
Inventory_InventoryChanged();
|
||||
foreach (var slot in ItemSlots)
|
||||
slot.SetItemStyle();
|
||||
Item_ItemExitFocus(_currentlySelectedItem);
|
||||
_currentlySelectedItem = ItemSlot1;
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private void InventoryMenu_VisibilityChanged()
|
||||
{
|
||||
if (Visible)
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.OpenInventory);
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
_enableMenuSound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
||||
_enableMenuSound = false;
|
||||
}
|
||||
if (Visible)
|
||||
{
|
||||
SetProcessUnhandledInput(true);
|
||||
SfxDatabase.Instance.Play(SoundEffect.OpenInventory);
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
_enableMenuSound = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetProcessUnhandledInput(false);
|
||||
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
|
||||
_enableMenuSound = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void Item_ItemExitFocus(IItemSlot itemSlot)
|
||||
{
|
||||
ItemDescriptionTitle.Text = string.Empty;
|
||||
ItemEffectLabel.Text = string.Empty;
|
||||
itemSlot.IsSelected = false;
|
||||
itemSlot.SetItemStyle();
|
||||
ItemDescriptionTitle.Text = string.Empty;
|
||||
ItemEffectLabel.Text = string.Empty;
|
||||
itemSlot.IsSelected = false;
|
||||
itemSlot.SetItemStyle();
|
||||
}
|
||||
|
||||
private void Item_FocusEntered(IItemSlot itemSlot)
|
||||
{
|
||||
if (itemSlot.Item.Value == null)
|
||||
return;
|
||||
if (itemSlot.Item.Value == null)
|
||||
return;
|
||||
|
||||
if (_enableMenuSound)
|
||||
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
|
||||
if (_enableMenuSound)
|
||||
SfxDatabase.Instance.Play(SoundEffect.MoveUI);
|
||||
|
||||
ItemDescriptionTitle.Text = $"{itemSlot.Item.Value.ItemName}";
|
||||
ItemEffectLabel.Text = $"{itemSlot.Item.Value.Description}";
|
||||
_currentlySelectedItem = itemSlot;
|
||||
itemSlot.IsSelected = true;
|
||||
itemSlot.SetItemStyle();
|
||||
AcceptEvent();
|
||||
ItemDescriptionTitle.Text = $"{itemSlot.Item.Value.ItemName}";
|
||||
ItemEffectLabel.Text = $"{itemSlot.Item.Value.Description}";
|
||||
_currentlySelectedItem = itemSlot;
|
||||
itemSlot.IsSelected = true;
|
||||
itemSlot.SetItemStyle();
|
||||
AcceptEvent();
|
||||
}
|
||||
|
||||
private void Item_Pressed(InventoryItem item) => DisplayUserActionPrompt(item);
|
||||
|
||||
private async void Inventory_InventoryChanged()
|
||||
{
|
||||
foreach (var slot in ItemSlots)
|
||||
{
|
||||
slot.Visible = false;
|
||||
slot.SetItemStyle();
|
||||
}
|
||||
foreach (var slot in ItemSlots)
|
||||
{
|
||||
slot.Visible = false;
|
||||
slot.SetItemStyle();
|
||||
}
|
||||
|
||||
var itemsToDisplay = _player.Inventory.Items;
|
||||
for (var i = 0; i < itemsToDisplay.Count; i++)
|
||||
{
|
||||
ItemSlots[i].Item.OnNext(itemsToDisplay[i]);
|
||||
ItemSlots[i].Visible = true;
|
||||
}
|
||||
var itemsToDisplay = _player.Inventory.Items;
|
||||
for (var i = 0; i < itemsToDisplay.Count; i++)
|
||||
{
|
||||
ItemSlots[i].Item.OnNext(itemsToDisplay[i]);
|
||||
ItemSlots[i].Visible = true;
|
||||
}
|
||||
|
||||
if (!_player.Inventory.Items.Contains(_currentlySelectedItem.Item.Value))
|
||||
{
|
||||
_currentlySelectedItem.Item.OnNext(null);
|
||||
var elementToSelect = Mathf.Max(0, ItemSlots.IndexOf(_currentlySelectedItem) - 1);
|
||||
_currentlySelectedItem = ItemSlots.ElementAt(elementToSelect);
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
}
|
||||
if (!_player.Inventory.Items.Contains(_currentlySelectedItem.Item.Value))
|
||||
{
|
||||
_currentlySelectedItem.Item.OnNext(null);
|
||||
var elementToSelect = Mathf.Max(0, ItemSlots.IndexOf(_currentlySelectedItem) - 1);
|
||||
_currentlySelectedItem = ItemSlots.ElementAt(elementToSelect);
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
}
|
||||
}
|
||||
|
||||
private void Attack_Sync(int obj) => ATKValue.Text = $"{_player.AttackComponent.CurrentAttack.Value}/{_player.AttackComponent.MaximumAttack.Value}";
|
||||
@@ -207,125 +202,128 @@ public partial class InventoryMenu : Control, IInventoryMenu
|
||||
|
||||
private void EquipmentComponent_EquipmentChanged(EquipableItem equipableItem)
|
||||
{
|
||||
ATKBonusLabel.Text = $"{_player.EquipmentComponent.BonusAttack:+0;-#;\\.\\.\\.}";
|
||||
DEFBonusLabel.Text = $"{_player.EquipmentComponent.BonusDefense:+0;-#;\\.\\.\\.}";
|
||||
ATKBonusLabel.Text = $"{_player.EquipmentComponent.BonusAttack:+0;-#;\\.\\.\\.}";
|
||||
DEFBonusLabel.Text = $"{_player.EquipmentComponent.BonusDefense:+0;-#;\\.\\.\\.}";
|
||||
}
|
||||
|
||||
private async void UseButtonPressed()
|
||||
{
|
||||
UseButton.Disabled = true;
|
||||
if (_currentlySelectedItem.Item.Value is EquipableItem equipable)
|
||||
await EquipOrUnequipItem(equipable);
|
||||
else if (_currentlySelectedItem.Item.Value is Plastique plastique)
|
||||
SetItem();
|
||||
else
|
||||
await _game.UseItem(_currentlySelectedItem.Item.Value);
|
||||
UseButton.Disabled = false;
|
||||
UseButton.Disabled = true;
|
||||
if (_currentlySelectedItem.Item.Value is EquipableItem equipable)
|
||||
await EquipOrUnequipItem(equipable);
|
||||
else if (_currentlySelectedItem.Item.Value is Plastique plastique)
|
||||
SetItem();
|
||||
else
|
||||
await _game.UseItem(_currentlySelectedItem.Item.Value);
|
||||
UseButton.Disabled = false;
|
||||
|
||||
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
await ToSignal(GetTree().CreateTimer(1f), "timeout");
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
await ToSignal(GetTree().CreateTimer(1f), "timeout");
|
||||
}
|
||||
|
||||
private async void SetItem()
|
||||
{
|
||||
_game.SetItem(_currentlySelectedItem.Item.Value);
|
||||
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
_gameRepo.CloseInventory();
|
||||
_game.SetItem(_currentlySelectedItem.Item.Value);
|
||||
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
_gameRepo.CloseInventory();
|
||||
}
|
||||
|
||||
private async void ThrowButtonPressed()
|
||||
{
|
||||
_game.ThrowItem(_currentlySelectedItem.Item.Value);
|
||||
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
_gameRepo.CloseInventory();
|
||||
_game.ThrowItem(_currentlySelectedItem.Item.Value);
|
||||
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
_gameRepo.CloseInventory();
|
||||
}
|
||||
|
||||
private async void DropButtonPressed()
|
||||
{
|
||||
_game.DropItem(_currentlySelectedItem.Item.Value);
|
||||
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
_game.DropItem(_currentlySelectedItem.Item.Value);
|
||||
_player.Inventory.Remove(_currentlySelectedItem.Item.Value);
|
||||
HideUserActionPrompt();
|
||||
await ShowInventoryInfo();
|
||||
}
|
||||
|
||||
private void DisplayUserActionPrompt(InventoryItem item)
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.SelectUI);
|
||||
ItemDescriptionTitle.Hide();
|
||||
ItemEffectLabel.Hide();
|
||||
UseItemPrompt.Show();
|
||||
UseButton.Show();
|
||||
ThrowButton.Show();
|
||||
DropButton.Show();
|
||||
SfxDatabase.Instance.Play(SoundEffect.SelectUI);
|
||||
ItemDescriptionTitle.Hide();
|
||||
ItemEffectLabel.Hide();
|
||||
UseItemPrompt.Show();
|
||||
UseButton.Show();
|
||||
ThrowButton.Show();
|
||||
DropButton.Show();
|
||||
|
||||
if (item is EquipableItem equipable)
|
||||
{
|
||||
var isItemEquipped = _player.EquipmentComponent.IsItemEquipped(equipable);
|
||||
UseButton.Text = isItemEquipped ? "Unequip" : "Equip";
|
||||
ThrowButton.Disabled = isItemEquipped;
|
||||
ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
|
||||
DropButton.Disabled = isItemEquipped;
|
||||
DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
|
||||
}
|
||||
else if (item is Plastique plastique)
|
||||
{
|
||||
UseButton.Text = "Set";
|
||||
}
|
||||
else
|
||||
{
|
||||
UseButton.Text = "Use";
|
||||
}
|
||||
if (item is EquipableItem equipable)
|
||||
{
|
||||
var isItemEquipped = _player.EquipmentComponent.IsItemEquipped(equipable);
|
||||
UseButton.Text = isItemEquipped ? "Unequip" : "Equip";
|
||||
ThrowButton.Disabled = isItemEquipped;
|
||||
ThrowButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
|
||||
DropButton.Disabled = isItemEquipped;
|
||||
DropButton.FocusMode = isItemEquipped ? FocusModeEnum.None : FocusModeEnum.All;
|
||||
|
||||
UseButton.GrabFocus();
|
||||
_enableMenuSound = false;
|
||||
UseButton.GrabFocus();
|
||||
|
||||
if (!_player.CanEquipState && isItemEquipped)
|
||||
UseButton.Disabled = true;
|
||||
}
|
||||
else if (item is Plastique plastique)
|
||||
{
|
||||
UseButton.Text = "Set";
|
||||
}
|
||||
else
|
||||
{
|
||||
UseButton.Text = "Use";
|
||||
}
|
||||
_enableMenuSound = false;
|
||||
}
|
||||
|
||||
private void HideUserActionPrompt()
|
||||
{
|
||||
UseItemPrompt.Hide();
|
||||
UseButton.Hide();
|
||||
ThrowButton.Hide();
|
||||
DropButton.Hide();
|
||||
UseButton.ReleaseFocus();
|
||||
ThrowButton.ReleaseFocus();
|
||||
DropButton.ReleaseFocus();
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
_enableMenuSound = true;
|
||||
UseItemPrompt.Hide();
|
||||
UseButton.Hide();
|
||||
ThrowButton.Hide();
|
||||
DropButton.Hide();
|
||||
UseButton.ReleaseFocus();
|
||||
ThrowButton.ReleaseFocus();
|
||||
DropButton.ReleaseFocus();
|
||||
_currentlySelectedItem.GrabFocus();
|
||||
_enableMenuSound = true;
|
||||
}
|
||||
|
||||
private async Task EquipOrUnequipItem(EquipableItem equipable)
|
||||
{
|
||||
if (_player.EquipmentComponent.IsItemEquipped(equipable))
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.Unequip);
|
||||
ItemEffectLabel.Text = $"{equipable.GetType().Name} unequipped.";
|
||||
_player.Unequip(equipable);
|
||||
}
|
||||
else
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.Equip);
|
||||
var itemSlot = _currentlySelectedItem;
|
||||
ItemEffectLabel.Text = $"{equipable.GetType().Name} equipped.";
|
||||
_player.Equip(equipable);
|
||||
_currentlySelectedItem = itemSlot;
|
||||
}
|
||||
if (_player.EquipmentComponent.IsItemEquipped(equipable))
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.Unequip);
|
||||
ItemEffectLabel.Text = $"{equipable.GetType().Name} unequipped.";
|
||||
_player.Unequip(equipable);
|
||||
}
|
||||
else
|
||||
{
|
||||
SfxDatabase.Instance.Play(SoundEffect.Equip);
|
||||
var itemSlot = _currentlySelectedItem;
|
||||
ItemEffectLabel.Text = $"{equipable.GetType().Name} equipped.";
|
||||
_player.Equip(equipable);
|
||||
_currentlySelectedItem = itemSlot;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task ShowInventoryInfo()
|
||||
{
|
||||
ItemDescriptionTitle.Show();
|
||||
ItemEffectLabel.Show();
|
||||
ItemDescriptionTitle.Show();
|
||||
ItemEffectLabel.Show();
|
||||
}
|
||||
|
||||
private enum InventoryPageNumber
|
||||
{
|
||||
FirstPage,
|
||||
SecondPage
|
||||
FirstPage,
|
||||
SecondPage
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,12 +62,6 @@ public partial class LoadNextLevel : Control, IFloorClearMenu
|
||||
ExitButton.Pressed += ExitButton_Pressed;
|
||||
}
|
||||
|
||||
public override void _Input(InputEvent @event)
|
||||
{
|
||||
if (_fadingIn)
|
||||
GetViewport().SetInputAsHandled();
|
||||
}
|
||||
|
||||
private void CurrentFloorNumber_Sync(int _) => FloorNumber.Text = _map.CurrentFloorNumber.Value.ToString("D2");
|
||||
|
||||
private void EquipmentComponent_EquipmentChanged(EquipableItem obj)
|
||||
|
||||
@@ -101,7 +101,7 @@ public partial class PauseDebugMenu : Control, IDebugMenu
|
||||
{
|
||||
var enemyToSpawn = _spawnableEnemies.ElementAt((int)index);
|
||||
var loadedEnemy = GD.Load<PackedScene>(enemyToSpawn).Instantiate<Enemy>();
|
||||
AddChild(loadedEnemy);
|
||||
_game.AddChild(loadedEnemy);
|
||||
loadedEnemy.GlobalPosition = new Vector3(_player.GlobalPosition.X, _player.GlobalPosition.Y + 1, _player.GlobalPosition.Z) + (-_player.GlobalBasis.Z * 2);
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public partial class PauseDebugMenu : Control, IDebugMenu
|
||||
{
|
||||
var itemToSpawn = _spawnableItems.ElementAt((int)index);
|
||||
var duplicated = itemToSpawn.Duplicate((int)DuplicateFlags.UseInstantiation) as Node3D;
|
||||
AddChild(duplicated);
|
||||
_game.AddChild(duplicated);
|
||||
duplicated.GlobalPosition = new Vector3(_player.GlobalPosition.X, _player.GlobalPosition.Y + 1, _player.GlobalPosition.Z) + (-_player.GlobalBasis.Z * 2);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user