Files
GameJamDungeon/Zennysoft.Game.Ma/src/items/EffectService.cs
2025-03-26 23:13:01 -07:00

242 lines
7.4 KiB
C#

using Godot;
using System.Linq;
using System;
using Zennysoft.Ma.Adapter;
namespace Zennysoft.Game.Ma;
public class EffectService
{
private readonly IGame _game;
private readonly IPlayer _player;
private readonly IMap _map;
public EffectService(IGame game, IPlayer player, IMap map)
{
_game = game;
_player = player;
_map = map;
}
public void TeleportEnemiesToCurrentRoom()
{
var currentFloor = _game.CurrentFloor;
var rooms = currentFloor.Rooms;
var currentRoom = _map.GetPlayersCurrentRoom();
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);
}
}
public void KillHalfEnemiesInRoom()
{
var currentRoom = _map.GetPlayersCurrentRoom();
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();
}
public void TurnAllEnemiesInRoomIntoHealingItem()
{
var currentRoom = _map.GetPlayersCurrentRoom();
if (currentRoom is not MonsterRoom)
return;
var currentEnemies = currentRoom.EnemiesInRoom;
foreach (var enemy in currentEnemies)
{
enemy.Die();
DropHealingItem(enemy.GetEnemyGlobalPosition());
}
}
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;
}
public void HealAllEnemiesAndPlayerInRoomToFull()
{
var currentRoom = _map.GetPlayersCurrentRoom();
if (currentRoom is not MonsterRoom)
return;
var currentEnemies = currentRoom.EnemiesInRoom;
foreach (var enemy in currentEnemies)
enemy.SetCurrentHP(enemy.GetMaximumHP());
_player.Stats.SetCurrentHP(_player.Stats.MaximumHP.Value);
}
public void AbsorbHPFromAllEnemiesInRoom()
{
var currentRoom = _map.GetPlayersCurrentRoom();
if (currentRoom is not MonsterRoom)
return;
var currentEnemies = currentRoom.EnemiesInRoom;
var hpToAbsorb = 0.0;
foreach (var enemy in currentEnemies)
hpToAbsorb += enemy.CurrentHP.Value * 0.05;
_player.Stats.SetCurrentHP(_player.Stats.CurrentHP.Value + (int)hpToAbsorb);
GD.Print("HP to absorb: " + hpToAbsorb);
}
public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
{
var currentRoom = _map.GetPlayersCurrentRoom();
if (currentRoom is not MonsterRoom)
return;
var currentEnemies = currentRoom.EnemiesInRoom;
foreach (var enemy in currentEnemies)
enemy.TakeDamage(20, elementType);
}
public void SwapHPandVT()
{
var oldHp = _player.Stats.CurrentHP.Value;
var oldVt = _player.Stats.CurrentVT.Value;
_player.Stats.SetCurrentHP(oldVt);
_player.Stats.SetCurrentVT(oldHp);
}
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);
}
public void RaiseCurrentWeaponAttack()
{
if (string.IsNullOrEmpty(_player.EquippedWeapon.Value.ItemName))
return;
var currentWeapon = (Weapon)_player.EquippedWeapon.Value;
currentWeapon.IncreaseWeaponAttack(1);
_player.ModifyBonusAttack(1);
}
public void RaiseCurrentArmorDefense()
{
if (string.IsNullOrEmpty(_player.EquippedArmor.Value.ItemName))
return;
var currentArmor = (Armor)_player.EquippedArmor.Value;
currentArmor.IncreaseArmorDefense(1);
_player.ModifyBonusDefense(1);
}
public void RaiseLevel()
{
_player.LevelUp();
}
public void TeleportToRandomRoom(IEnemy enemy)
{
var currentFloor = _game.CurrentFloor;
var rooms = currentFloor.Rooms;
var currentRoom = enemy.GetCurrentRoom();
var validRooms = rooms.OfType<MonsterRoom>().ToList();
if (currentRoom is MonsterRoom currentMonsterRoom)
validRooms.Remove(currentMonsterRoom);
if (validRooms.Count == 0)
return;
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
var randomRoom = roomsGodotCollection.PickRandom();
var spawnPoints = randomRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
var spawnPointsGodotCollection = new Godot.Collections.Array<Marker3D>(spawnPoints);
var randomSpawnPoint = spawnPointsGodotCollection.PickRandom();
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
}
public void TeleportToRandomRoom(IPlayer player)
{
var currentFloor = _game.CurrentFloor;
var rooms = currentFloor.Rooms;
var currentRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
var validRooms = rooms.OfType<MonsterRoom>().ToList();
if (currentRoom is MonsterRoom currentMonsterRoom)
validRooms.Remove(currentMonsterRoom);
if (validRooms.Count == 0)
return;
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
var randomRoom = roomsGodotCollection.PickRandom();
var spawnPoint = randomRoom.PlayerSpawn;
player.TeleportPlayer(spawnPoint.Transform);
}
public void ChangeAffinity(ThrowableItem throwableItem)
{
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.");
throwableItem.SetCount(throwableItem.Count + 1);
}
public void WarpToExit(IPlayer player)
{
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
if (exitRoom.PlayerDiscoveredRoom)
player.TeleportPlayer(exitRoom.PlayerSpawn.Transform);
}
public void WarpToExit(IEnemy enemy)
{
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
enemy.SetEnemyGlobalPosition(exitRoom.PlayerSpawn.GlobalPosition);
}
}