using System; using System.Collections.Generic; using System.Linq; using Continentis.MainGame.Character; using Lean.Pool; using SLSFramework.UModAssistance; using UnityEngine; using Object = UnityEngine.Object; namespace Continentis.MainGame.Combat { [Serializable] public partial class CombatCharacterController { [Header("References")] public List characters; public Dictionary> npcs; public CombatTeam playerTeam; public List playerHeroes; public List allies => npcs[Fraction.Ally]; public CombatTeam enemyTeam; public List enemies => npcs[Fraction.Enemy]; public List neutrals => npcs[Fraction.Neutral]; public List actionOrderList; public List combatCharacterViews; } public partial class CombatCharacterController { public void Initialize(List playerHeroDataList, List enemyDataList) { characters = new List(); npcs = new Dictionary> { { Fraction.Ally, new List() }, { Fraction.Enemy, new List() }, { Fraction.Neutral, new List() } }; playerTeam = new CombatTeam(); playerHeroes = new List(); enemyTeam = new CombatTeam(); actionOrderList = new List(); combatCharacterViews = new List(); foreach (var data in playerHeroDataList) { PlayerHero hero = new PlayerHero(data, Fraction.Player); CombatCharacterViewBase view = hero.GenerateCharacterView(new Vector3(-4.5f, -2, 0)); playerHeroes.Add(hero); characters.Add(hero); combatCharacterViews.Add(view); } foreach (var data in enemyDataList) { CombatNPC enemy = new CombatNPC(data, Fraction.Enemy); CombatCharacterViewBase view = enemy.GenerateCharacterView(new Vector3(4.5f, -2, 0)); view.mainView.transform.localEulerAngles = new Vector3(0, 180, 0); enemies.Add(enemy); characters.Add(enemy); combatCharacterViews.Add(view); } SetViewPositions(); SetViewHUDs(); //ModManager.CreateInstance("Basic.Buffs.Weak", 2).Apply(enemies[0]); } public void AddCombatNPC(params (CharacterData, Fraction)[] dataList) { foreach ((CharacterData, Fraction) npcData in dataList) { CharacterData data = npcData.Item1; Fraction fraction = npcData.Item2; if (fraction == Fraction.Player) { Debug.LogError("Cannot add Player fraction as CombatNPC."); return; } CombatNPC npc = new CombatNPC(data, fraction); npc.InitializeCards(); Vector3 eulerAngles = fraction == Fraction.Enemy ? new Vector3(0, 180, 0) : Vector3.zero; CombatCharacterViewBase view = npc.GenerateCharacterView(new Vector3(0, -2, 0)); view.mainView.transform.localEulerAngles = eulerAngles; npcs[fraction].Add(npc); characters.Add(npc); combatCharacterViews.Add(view); } SetViewPositions(); SetViewHUDs(); } public void SetViewPositions() { float playerSideLeftBound = -7.5f; float playerSideRightBound = -1.5f; float playerBaseInterval = 2f; if (playerHeroes.Count > 4) { playerBaseInterval = (playerSideRightBound - playerSideLeftBound) / (playerHeroes.Count - 1); } playerHeroes.Sort((x, y) => x.data.combatPositionOrder.CompareTo(y.data.combatPositionOrder)); for (int index = 0; index < playerHeroes.Count; index++) { float xPos = playerSideLeftBound + index * playerBaseInterval; Vector3 position = new Vector3(xPos, -1, 0); playerHeroes[index].characterView.transform.position = position; } float enemySideLeftBound = 1.5f; float enemySideRightBound = 7.5f; float enemyBaseInterval = 2f; if (enemies.Count > 4) { enemyBaseInterval = (enemySideRightBound - enemySideLeftBound) / (enemies.Count - 1); } enemies.Sort((x, y) => y.data.combatPositionOrder.CompareTo(x.data.combatPositionOrder)); for (int index = 0; index < enemies.Count; index++) { float xPos = enemySideLeftBound + index * enemyBaseInterval; Vector3 position = new Vector3(xPos, -1, 0); enemies[index].characterView.transform.position = position; } Debug.Log($"Enemy are sorted: {string.Join(", ", enemies.Select(e => e.data.displayName))}"); } public void SetViewHUDs() { CombatUIManager.Instance.hudPage.Initialize(characters); foreach (CharacterBase character in characters) { character.characterView.hudContainer.EnableHUD("MainAttributesBar"); character.characterView.hudContainer.EnableHUD("CharacterBuffCollection"); if (character is CombatNPC) { character.characterView.hudContainer.EnableHUD("Intention"); } } } } public partial class CombatCharacterController { public void SetActionOrder() { Dictionary speeds = new Dictionary(); for (var index = 0; index < characters.Count; index++) { CharacterBase character = characters[index]; float speed = character.GetAttribute("Speed"); if (character.fraction is Fraction.Player) { speed += 0.01f; // 玩家角色微增速度,确保同速度时玩家角色优先 } speeds.Add(index, speed); } actionOrderList.Clear(); foreach (var pair in speeds.OrderByDescending(pair => pair.Value)) { actionOrderList.Add(characters[pair.Key]); } } } public partial class CombatCharacterController { public void RemoveCharacter(CharacterBase character) { characters.Remove(character); actionOrderList.Remove(character); combatCharacterViews.Remove(character.characterView); if (character is PlayerHero playerHero) { playerHeroes.Remove(playerHero); } else if (character is CombatNPC npc) { npcs[character.fraction].Remove(npc); } Object.Destroy(character.characterView.hudContainer.gameObject); Object.Destroy(character.characterView.gameObject); SetViewPositions(); SetViewHUDs(); } } public partial class CombatCharacterController { public List GetAllAllies(CharacterBase character, bool includeSelf = false) { if (character.fraction is Fraction.Player or Fraction.Ally) { List alliesList = new List(playerHeroes); alliesList.AddRange(npcs[Fraction.Ally]); if (!includeSelf) { alliesList.Remove(character); } return alliesList; } else { return npcs[character.fraction].Cast().ToList(); } } public List GetAllEnemies(CharacterBase character) { if (character.fraction is Fraction.Player or Fraction.Ally) { return npcs[Fraction.Enemy].Cast().ToList(); } else if (character.fraction is Fraction.Enemy) { List enemiesList = new List(playerHeroes); enemiesList.AddRange(npcs[Fraction.Ally]); return enemiesList; } else // Neutral { List enemiesList = new List(); enemiesList.AddRange(npcs[Fraction.Player]); enemiesList.AddRange(npcs[Fraction.Ally]); enemiesList.AddRange(npcs[Fraction.Enemy]); return enemiesList; } } } }