using Cthangover.Core.Battle;
using Cthangover.Core.Events;
using Cthangover.Core.Scenes;
using Cthangover.Core.Utils;
using Godot;
namespace Cthangover.Mods.Rpg
{
///
/// Starts a battle of the active battle core from the map and brings the
/// player back to the same map cell afterwards. It is a thin layer over the
/// platform ( + the Battle route):
///
/// - the return scene is the current map's scene, and the position is
/// already in , so the world restores it;
/// - the backdrop is the map scene's default background (captured by
/// the platform from the scene), so a map chooses its battle background in
/// scenes/<map>.json;
/// - an optional win flag becomes the story flag "1" on victory — how a
/// map monster disappears after it is beaten (its event's condition).
///
///
public static class RpgBattleService
{
private const string BattleRoute = "Battle";
private const string VictoryResult = "victory";
///
/// Requests the encounter and switches to the battle route on the next
/// frame (deferred like switch_scene, so a running dialog finishes
/// its current command first). Returns false when there is no scene to come back to.
///
public static bool Start(string enemies, string winFlag)
{
var sceneManager = FindSceneManager();
var returnScene = sceneManager?.CurrentSceneName;
if (string.IsNullOrEmpty(returnScene) || string.IsNullOrWhiteSpace(enemies))
{
GameLogger.Log("RPG", $"battle not started: scene='{returnScene}', enemies='{enemies}'", LogLevel.Error);
return false;
}
RpgState.Instance.PendingWinFlag = string.IsNullOrWhiteSpace(winFlag) ? null : winFlag.Trim();
BattleService.Init(returnScene, enemies.Replace(" ", string.Empty));
GameLogger.Log("RPG", $"battle '{enemies}' from '{returnScene}' (win flag: {RpgState.Instance.PendingWinFlag ?? "none"})");
Callable.From(() => sceneManager.SwitchScene(BattleRoute)).CallDeferred();
return true;
}
/// Applies the pending win flag of the battle that just ended.
public static void OnBattleEnded(BattleEndedEvent evt)
{
var flag = RpgState.Instance.PendingWinFlag;
RpgState.Instance.PendingWinFlag = null;
if (flag != null && evt?.Result == VictoryResult)
ScenarioCondition.SetFlag(flag, "1");
}
private static SceneManager FindSceneManager()
{
var tree = Godot.Engine.GetMainLoop() as SceneTree;
return tree?.Root?.GetNodeOrNull("SceneManager");
}
}
}