Files
Continentis/Assets/Scripts/MainGame/Combat/CombatCharacterController.cs
SoulliesOfficial 40660b41e0 角色死亡
2025-12-12 01:37:30 -05:00

258 lines
9.3 KiB
C#

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<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 = 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<CharacterCombatBuffBase>("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<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 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<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;
}
}
}
}