Files
Continentis/Assets/Scripts/MainGame/Combat/CombatCharacterController.cs
2025-10-31 10:02:30 -04:00

217 lines
8.1 KiB
C#

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<CharacterBase> characters;
public Dictionary<Fraction, List<CombatNPC>> npcs;
public CombatTeam playerTeam;
public List<PlayerHero> playerHeroes;
public List<CombatNPC> allies => npcs[Fraction.Ally];
public CombatTeam enemyTeam;
public List<CombatNPC> enemies => npcs[Fraction.Enemy];
public List<CombatNPC> neutrals => npcs[Fraction.Neutral];
public List<CharacterBase> actionOrderList;
public List<CombatCharacterViewBase> combatCharacterViews;
}
public partial class CombatCharacterController
{
public void Initialize(List<CharacterData> playerHeroDataList, List<CharacterData> enemyDataList)
{
characters = new List<CharacterBase>();
npcs = new Dictionary<Fraction, List<CombatNPC>>
{
{ Fraction.Ally, new List<CombatNPC>() },
{ Fraction.Enemy, new List<CombatNPC>() },
{ Fraction.Neutral, new List<CombatNPC>() }
};
playerTeam = new CombatTeam();
playerHeroes = new List<PlayerHero>();
enemyTeam = new CombatTeam();
actionOrderList = new List<CharacterBase>();
combatCharacterViews = new List<CombatCharacterViewBase>();
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<CharacterCombatBuffBase>("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<int, float> speeds = new Dictionary<int, float>();
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<CharacterBase> GetAllAllies(CharacterBase character, bool includeSelf = false)
{
if (character.fraction is Fraction.Player or Fraction.Ally)
{
List<CharacterBase> alliesList = new List<CharacterBase>(playerHeroes);
alliesList.AddRange(npcs[Fraction.Ally]);
if (!includeSelf)
{
alliesList.Remove(character);
}
return alliesList;
}
else
{
return npcs[character.fraction].Cast<CharacterBase>().ToList();
}
}
public List<CharacterBase> GetAllEnemies(CharacterBase character)
{
if (character.fraction is Fraction.Player or Fraction.Ally)
{
return npcs[Fraction.Enemy].Cast<CharacterBase>().ToList();
}
else if (character.fraction is Fraction.Enemy)
{
List<CharacterBase> enemiesList = new List<CharacterBase>(playerHeroes);
enemiesList.AddRange(npcs[Fraction.Ally]);
return enemiesList;
}
else // Neutral
{
List<CharacterBase> enemiesList = new List<CharacterBase>();
enemiesList.AddRange(npcs[Fraction.Player]);
enemiesList.AddRange(npcs[Fraction.Ally]);
enemiesList.AddRange(npcs[Fraction.Enemy]);
return enemiesList;
}
}
}
}