Files
Continentis/Assets/Scripts/MainGame/Combat/CombatCharacterController.cs

297 lines
11 KiB
C#
Raw Normal View History

2025-12-12 01:37:30 -05:00
using System;
2025-10-23 00:49:44 -04:00
using System.Collections.Generic;
using System.Linq;
using Continentis.MainGame.Character;
2025-12-13 23:28:23 -05:00
using DG.Tweening;
2025-12-12 01:37:30 -05:00
using Lean.Pool;
2026-04-17 12:01:50 -04:00
using SLSUtilities.General;
using SLSUtilities.UModAssistance;
2025-10-23 00:49:44 -04:00
using UnityEngine;
2025-12-12 01:37:30 -05:00
using Object = UnityEngine.Object;
2025-10-23 00:49:44 -04:00
namespace Continentis.MainGame.Combat
{
2025-12-12 01:37:30 -05:00
[Serializable]
2025-10-23 00:49:44 -04:00
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)
{
2025-11-15 12:17:34 -05:00
PlayerHero hero = new PlayerHero(data, Fraction.Player);
2025-12-03 09:22:57 -05:00
CombatCharacterViewBase view = hero.GenerateCharacterView(new Vector3(-4.5f, -2, 0));
2025-10-23 00:49:44 -04:00
playerHeroes.Add(hero);
characters.Add(hero);
combatCharacterViews.Add(view);
}
foreach (var data in enemyDataList)
{
2025-11-15 12:17:34 -05:00
CombatNPC enemy = new CombatNPC(data, Fraction.Enemy);
2025-12-03 09:22:57 -05:00
CombatCharacterViewBase view = enemy.GenerateCharacterView(new Vector3(4.5f, -2, 0));
2025-10-23 00:49:44 -04:00
view.mainView.transform.localEulerAngles = new Vector3(0, 180, 0);
enemies.Add(enemy);
characters.Add(enemy);
combatCharacterViews.Add(view);
}
2025-12-13 23:28:23 -05:00
SetViewPositions(0);
2025-10-23 00:49:44 -04:00
2025-12-10 18:22:26 -05:00
//ModManager.CreateInstance<CharacterCombatBuffBase>("Basic.Buffs.Weak", 2).Apply(enemies[0]);
2025-10-23 00:49:44 -04:00
}
2025-11-14 01:40:00 -05:00
public void AddCombatNPC(params (CharacterData, Fraction)[] dataList)
2025-10-23 00:49:44 -04:00
{
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;
}
2025-11-15 12:17:34 -05:00
CombatNPC npc = new CombatNPC(data, fraction);
2025-10-23 00:49:44 -04:00
npc.InitializeCards();
Vector3 eulerAngles = fraction == Fraction.Enemy ? new Vector3(0, 180, 0) : Vector3.zero;
2025-12-13 23:28:23 -05:00
CombatCharacterViewBase view = npc.GenerateCharacterView(new Vector3(0, -1, 0));
2025-10-23 00:49:44 -04:00
view.mainView.transform.localEulerAngles = eulerAngles;
npcs[fraction].Add(npc);
characters.Add(npc);
combatCharacterViews.Add(view);
2026-04-01 12:23:27 -04:00
CombatMainManager.Instance.eventCollection.onCharacterJoin.Invoke(npc);
2025-10-23 00:49:44 -04:00
}
SetViewPositions();
}
2025-12-13 23:28:23 -05:00
public void SetViewPositions(float transitionDuration = 0.25f)
2025-10-23 00:49:44 -04:00
{
2025-12-12 01:37:30 -05:00
float playerSideLeftBound = -7.5f;
float playerSideRightBound = -1.5f;
float playerBaseInterval = 2f;
if (playerHeroes.Count > 4)
{
playerBaseInterval = (playerSideRightBound - playerSideLeftBound) / (playerHeroes.Count - 1);
}
2025-10-23 00:49:44 -04:00
playerHeroes.Sort((x, y) => x.data.combatPositionOrder.CompareTo(y.data.combatPositionOrder));
for (int index = 0; index < playerHeroes.Count; index++)
{
2025-12-12 01:37:30 -05:00
float xPos = playerSideLeftBound + index * playerBaseInterval;
2025-12-03 09:22:57 -05:00
Vector3 position = new Vector3(xPos, -1, 0);
2025-12-13 23:28:23 -05:00
if (transitionDuration > 0f)
{
playerHeroes[index].characterView.transform.DOMove(position, transitionDuration)
.SetEase(Ease.InOutSine)
.OnComplete(SetViewHUDs)
.Play();
}
else
{
playerHeroes[index].characterView.transform.position = position;
SetViewHUDs();
}
2025-10-23 00:49:44 -04:00
}
2025-12-12 01:37:30 -05:00
float enemySideLeftBound = 1.5f;
float enemySideRightBound = 7.5f;
float enemyBaseInterval = 2f;
if (enemies.Count > 4)
{
enemyBaseInterval = (enemySideRightBound - enemySideLeftBound) / (enemies.Count - 1);
}
2025-10-23 00:49:44 -04:00
enemies.Sort((x, y) => y.data.combatPositionOrder.CompareTo(x.data.combatPositionOrder));
for (int index = 0; index < enemies.Count; index++)
{
2025-12-12 01:37:30 -05:00
float xPos = enemySideLeftBound + index * enemyBaseInterval;
2025-12-03 09:22:57 -05:00
Vector3 position = new Vector3(xPos, -1, 0);
2025-12-13 23:28:23 -05:00
if (transitionDuration > 0f)
{
enemies[index].characterView.transform.DOMove(position, transitionDuration)
.SetEase(Ease.InOutSine)
.OnComplete(SetViewHUDs)
.Play();
}
else
{
enemies[index].characterView.transform.position = position;
SetViewHUDs();
}
2025-10-23 00:49:44 -04:00
}
2025-12-12 01:37:30 -05:00
Debug.Log($"Enemy are sorted: {string.Join(", ", enemies.Select(e => e.data.displayName))}");
2025-10-23 00:49:44 -04:00
}
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]);
}
}
}
2025-10-31 10:02:30 -04:00
2025-12-12 01:37:30 -05:00
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();
2026-04-01 12:23:27 -04:00
CheckCombatEnd();
}
/// <summary>
/// 检查战斗胜负条件:敌方全灭→胜利,玩家方全灭→失败。
/// </summary>
private void CheckCombatEnd()
{
if (enemies.Count == 0)
{
CombatMainManager.Instance.EndCombat(isVictory: true);
}
else if (playerHeroes.Count == 0)
{
CombatMainManager.Instance.EndCombat(isVictory: false);
}
2025-12-12 01:37:30 -05:00
}
}
2025-10-31 10:02:30 -04:00
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;
}
2026-04-01 12:23:27 -04:00
else // Neutral中立单位视所有非中立方为敌人
2025-10-31 10:02:30 -04:00
{
2026-04-01 12:23:27 -04:00
List<CharacterBase> enemiesList = new List<CharacterBase>(playerHeroes);
2025-10-31 10:02:30 -04:00
enemiesList.AddRange(npcs[Fraction.Ally]);
enemiesList.AddRange(npcs[Fraction.Enemy]);
return enemiesList;
}
}
}
2025-10-23 00:49:44 -04:00
}