193 lines
6.3 KiB
C#
193 lines
6.3 KiB
C#
using Chickensoft.AutoInject;
|
|
using Chickensoft.Introspection;
|
|
using Godot;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace GameJamDungeon;
|
|
|
|
[Meta(typeof(IAutoNode))]
|
|
public partial class EffectItem : Node3D, IUsableItem
|
|
{
|
|
public override void _Notification(int what) => this.Notify(what);
|
|
|
|
[Dependency] public IGame Game => this.DependOn<IGame>();
|
|
|
|
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
|
|
|
[Export]
|
|
private EffectItemStats _effectItemStats { get; set; }
|
|
|
|
[Node] private Sprite3D Sprite { get; set; } = new Sprite3D();
|
|
|
|
[Node] private Area3D Pickup { get; set; } = default!;
|
|
|
|
public Guid ID => Guid.NewGuid();
|
|
|
|
public string ItemName => _effectItemStats.Name;
|
|
|
|
public string Description => _effectItemStats.Description;
|
|
|
|
public float SpawnRate => _effectItemStats.SpawnRate;
|
|
|
|
public Texture2D GetTexture() => _effectItemStats.Texture;
|
|
|
|
public double ThrowDamage => _effectItemStats.ThrowDamage;
|
|
|
|
public float ThrowSpeed => _effectItemStats.ThrowSpeed;
|
|
|
|
public void Use()
|
|
{
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.DoubleEXP))
|
|
Game.DoubleEXP(TimeSpan.FromSeconds(30));
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.TeleportAllEnemiesToRoom))
|
|
TeleportEnemiesToCurrentRoom();
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.KillHalfEnemiesInRoom))
|
|
KillHalfEnemiesInRoom();
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.TurnAllEnemiesIntoHealingItem))
|
|
TurnAllEnemiesInRoomIntoHealingItem();
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.HealsAllInRoomToMaxHP))
|
|
HealAllEnemiesAndPlayerInRoomToFull();
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.AbsorbHPFromAllEnemiesInRoom))
|
|
AbsorbHPFromAllEnemiesInRoom();
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.DealElementalDamageToAllEnemiesInRoom))
|
|
DealElementalDamageToAllEnemiesInRoom(ElementType.Hydric);
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.SwapHPAndVT))
|
|
SwapHPandVT();
|
|
|
|
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.RandomEffect))
|
|
RandomEffect();
|
|
|
|
}
|
|
|
|
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
|
{
|
|
_effectItemStats = (EffectItemStats)inventoryItemStats;
|
|
}
|
|
|
|
public void OnReady()
|
|
{
|
|
Pickup.BodyEntered += OnEntered;
|
|
Sprite.Texture = _effectItemStats.Texture;
|
|
}
|
|
|
|
public void OnEntered(Node3D body)
|
|
{
|
|
var isAdded = Player.Inventory.TryAdd(this);
|
|
if (isAdded)
|
|
QueueFree();
|
|
}
|
|
|
|
private void TeleportEnemiesToCurrentRoom()
|
|
{
|
|
var currentFloor = Game.CurrentFloor;
|
|
var rooms = currentFloor.Rooms;
|
|
var currentRoom = Player.GetCurrentRoom();
|
|
|
|
if (currentRoom is not MonsterRoom)
|
|
return;
|
|
|
|
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
|
if (currentRoom is MonsterRoom monsterRoom)
|
|
validRooms.Remove(monsterRoom);
|
|
|
|
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
|
|
|
var enemyList = validRooms.SelectMany(x => x.GetEnemiesInCurrentRoom());
|
|
|
|
foreach (var enemy in enemyList)
|
|
{
|
|
var spawnPoints = currentMonsterRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
|
|
var spawnPointsGodotCollection = new Godot.Collections.Array<Marker3D>(spawnPoints);
|
|
var randomSpawnPoint = spawnPointsGodotCollection.PickRandom();
|
|
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
|
|
}
|
|
}
|
|
|
|
private void KillHalfEnemiesInRoom()
|
|
{
|
|
var currentRoom = Player.GetCurrentRoom();
|
|
if (currentRoom is not MonsterRoom)
|
|
return;
|
|
|
|
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
|
var enemyList = currentMonsterRoom.GetEnemiesInCurrentRoom().ToList();
|
|
var enemiesToKill = enemyList.Count / 2;
|
|
for (var i = 0; i < enemiesToKill; i++)
|
|
enemyList[i].Die();
|
|
}
|
|
|
|
private void TurnAllEnemiesInRoomIntoHealingItem()
|
|
{
|
|
var currentRoom = Player.GetCurrentRoom();
|
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
|
foreach (var enemy in currentEnemies)
|
|
{
|
|
enemy.Die();
|
|
DropHealingItem(enemy.GetEnemyGlobalPosition());
|
|
}
|
|
}
|
|
|
|
private 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.SetItemStats(randomFile);
|
|
Game.AddChild(consumable);
|
|
consumable.GlobalPosition = vector;
|
|
}
|
|
|
|
private void HealAllEnemiesAndPlayerInRoomToFull()
|
|
{
|
|
var currentRoom = Player.GetCurrentRoom();
|
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
|
foreach (var enemy in currentEnemies)
|
|
enemy.SetCurrentHP(enemy.GetMaximumHP());
|
|
Player.Stats.SetCurrentHP(Player.Stats.MaximumHP.Value);
|
|
}
|
|
|
|
private void AbsorbHPFromAllEnemiesInRoom()
|
|
{
|
|
var currentRoom = Player.GetCurrentRoom();
|
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
|
var hpToAbsorb = 0.0;
|
|
foreach (var enemy in currentEnemies)
|
|
hpToAbsorb += enemy.CurrentHP * 0.05;
|
|
Player.Stats.SetCurrentHP(Player.Stats.CurrentHP.Value + (int)hpToAbsorb);
|
|
GD.Print("HP to absorb: " + hpToAbsorb);
|
|
}
|
|
|
|
private void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
|
|
{
|
|
var currentRoom = Player.GetCurrentRoom();
|
|
var currentEnemies = currentRoom.EnemiesInRoom;
|
|
foreach (var enemy in currentEnemies)
|
|
enemy.TakeDamage(20, elementType);
|
|
}
|
|
|
|
private void SwapHPandVT()
|
|
{
|
|
var oldHp = Player.Stats.CurrentHP.Value;
|
|
var oldVt = Player.Stats.CurrentVT.Value;
|
|
|
|
Player.Stats.SetCurrentHP(oldVt);
|
|
Player.Stats.SetCurrentVT(oldHp);
|
|
}
|
|
|
|
private void RandomEffect()
|
|
{
|
|
var itemEffects = Enum.GetValues<UsableItemTag>().ToList();
|
|
itemEffects.Remove(UsableItemTag.RandomEffect);
|
|
var randomEffect = new Godot.Collections.Array<UsableItemTag>(itemEffects).PickRandom();
|
|
_effectItemStats.UsableItemTags.Clear();
|
|
_effectItemStats.UsableItemTags.Add(randomEffect);
|
|
Use();
|
|
}
|
|
}
|