using System.Collections.Generic; using System.Linq; using Continentis.MainGame.Character; using SLSFramework.UModAssistance; using UnityEngine; namespace Continentis.MainGame.Combat { 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 = PlayerHero.GenerateCharacter(data); CombatCharacterViewBase view = hero.GenerateCharacterView(new Vector3(-4.5f, 0, 0)); playerHeroes.Add(hero); characters.Add(hero); combatCharacterViews.Add(view); } foreach (var data in enemyDataList) { CombatNPC enemy = CombatNPC.GenerateCharacter(data, Fraction.Enemy); CombatCharacterViewBase view = enemy.GenerateCharacterView(new Vector3(4.5f, 0, 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 AddCombatNPCs(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 = CombatNPC.GenerateCharacter(data, fraction); npc.InitializeCards(); Vector3 eulerAngles = fraction == Fraction.Enemy ? new Vector3(0, 180, 0) : Vector3.zero; CombatCharacterViewBase view = npc.GenerateCharacterView(Vector3.zero); view.mainView.transform.localEulerAngles = eulerAngles; npcs[fraction].Add(npc); characters.Add(npc); combatCharacterViews.Add(view); } SetViewPositions(); SetViewHUDs(); } public void SetViewPositions() { float playerSideLeftBound = -8f; float playerSideRightBound = -2f; playerHeroes.Sort((x, y) => x.data.combatPositionOrder.CompareTo(y.data.combatPositionOrder)); for (int index = 0; index < playerHeroes.Count; index++) { float xPos = playerHeroes.Count > 1 ? Mathf.Lerp(playerSideLeftBound, playerSideRightBound, (float)index / (playerHeroes.Count - 1)) : (playerSideLeftBound + playerSideRightBound) / 2; Vector3 position = new Vector3(xPos, 0, 0); playerHeroes[index].characterView.transform.position = position; } float enemySideLeftBound = 2f; float enemySideRightBound = 8f; enemies.Sort((x, y) => y.data.combatPositionOrder.CompareTo(x.data.combatPositionOrder)); for (int index = 0; index < enemies.Count; index++) { float xPos = enemies.Count > 1 ? Mathf.Lerp(enemySideLeftBound, enemySideRightBound, (float)index / (enemies.Count - 1)) : (enemySideLeftBound + enemySideRightBound) / 2; Vector3 position = new Vector3(xPos, 0, 0); enemies[index].characterView.transform.position = position; } } 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 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; } } } }