ProjectCreep/Assets/TBTK/Scripts/UnitManager.cs

871 lines
27 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
#if UNITY_EDITOR
using UnityEditor;
#endif
namespace TBTK{
[ExecuteInEditMode]
public class UnitManager : MonoBehaviour {
public List<Unit> allUnitList=new List<Unit>();
public static List<Unit> GetAllUnitList(){
if(TurnControl.IsUnitPerTurn()) return instance.allUnitList;
else{
instance.allUnitList=new List<Unit>();
for(int i=0; i<instance.factionList.Count; i++) instance.allUnitList.AddRange(instance.factionList[i].unitList);
return instance.allUnitList;
}
}
public List<Faction> factionList=new List<Faction>();
public static List<Faction> GetFactionList(){ return instance.factionList; }
public static Faction GetFaction(int idx){ return instance.factionList[idx]; }
private bool hasAIInGame=false;
public Unit selectedUnit;
public static Unit GetSelectedUnit(){ return instance.selectedUnit; }
public static Faction GetSelectedFaction(){
if(GetSelectedUnit()==null) return null;
for(int i=0; i<instance.factionList.Count; i++){
if(instance.factionList[i].factionID==GetSelectedUnit().GetFacID()) return instance.factionList[i];
}
return null;
}
private static UnitManager instance;
public static UnitManager GetInstance(){
if(instance==null) instance=(UnitManager)FindObjectOfType(typeof(UnitManager));
return instance;
}
public static void Init(){
if(instance==null) instance=(UnitManager)FindObjectOfType(typeof(UnitManager));
for(int i=0; i<instance.factionList.Count; i++){
instance.factionList[i].Init(i);
instance.hasAIInGame|=instance.factionList[i].playableFaction;
}
instance.DeployAllUnit(); //only applies for AI faction unless enableManualDeployment is left unchecked
instance.deployingFacIdx=instance._RequireManualDeployment();
if(instance.deployingFacIdx>=0) instance.NewFactionDeployment();
instance._Init();
}
public void _Init(){
//~ selectIndicator=GridManager.IsHexGrid() ? selectIndicatorHex : selectIndicatorSq ;
//~ selectIndicator.localScale*=GridManager.GetNodeSize();
//~ if(GridManager.IsHexGrid()) selectIndicatorSq.gameObject.SetActive(false);
//~ if(GridManager.IsSquareGrid()) selectIndicatorHex.gameObject.SetActive(false);
}
public void Start(){
if(!Application.isPlaying && instance==null) instance=this;
}
public void NewFactionDeployment(){
deployingUnitIdx=0;
int deployFacID=instance.factionList[deployingFacIdx].factionID;
List<Node> deploymentNodeList=GridManager.GetDeploymentNode(deployFacID);
GridIndicator.ShowDeployment(deploymentNodeList);
//~ List<Node> addOnList=new List<Node>();
//~ for(int i=0; i<deploymentNodeList.Count; i++){
//~ List<Node> neighbours=deploymentNodeList[i].GetNeighbourList(true);
//~ for(int n=0; n<neighbours.Count; n++){
//~ if(!deploymentNodeList.Contains(neighbours[n])) addOnList.Add(neighbours[n]);
//~ }
//~ }
//~ deploymentNodeList.AddRange(addOnList);
GridManager.SetupFogOfWarForDeployment(deploymentNodeList, deployFacID);
}
public static bool IsDeploymentDone(){
if(instance.factionList[instance.deployingFacIdx].deployingList.Count==0) return true;
bool hasEmptyNode=false;
List<Node> deploymentNodeList=GridManager.GetDeploymentNode(instance.factionList[instance.deployingFacIdx].factionID);
for(int i=0; i<deploymentNodeList.Count; i++){
if(deploymentNodeList[i].unit==null){ hasEmptyNode|=true; break; }
}
return !hasEmptyNode;
}
public static bool CheckDeploymentHasUnitOnGrid(){
return instance.factionList[instance.deployingFacIdx].unitList.Count>0;
}
public static bool DeployUnit(Node node, int idx=0){ return instance._DeployUnit(node, idx); }
public bool _DeployUnit(Node node, int idx=0){
if(node.deployFacID!=factionList[deployingFacIdx].factionID) return false;
if(node.unit!=null){
if(node.unit.GetFacID()!=deployingFacIdx) return false;
factionList[deployingFacIdx].unitList.Remove(node.unit);
factionList[deployingFacIdx].deployingList.Add(node.unit);
node.unit.transform.position=new Vector3(0, 99999, 0);
node.unit=null;
//PrevUnitToDeploy();
}
else{
if(!node.walkable || node.obstacleT!=null) return false;
if(factionList[deployingFacIdx].deployingList.Count==0) return false;
node.unit=factionList[deployingFacIdx].deployingList[idx];
node.unit.transform.position=node.GetPos();
if(!Unit.enableRotation) node.unit.transform.rotation=Quaternion.identity;
else node.unit.transform.rotation=Quaternion.Euler(0, factionList[deployingFacIdx].direction, 0);
node.unit.node=node;
factionList[deployingFacIdx].unitList.Add(node.unit);
factionList[deployingFacIdx].deployingList.RemoveAt(idx);
if(factionList[deployingFacIdx].unitList.Count<=1) deployingUnitIdx=0;
}
return true;
}
public static int EndDeployment(){
GridIndicator.HideDeployment();
instance.deployingFacIdx=instance._RequireManualDeployment(instance.deployingFacIdx+1);
if(instance.deployingFacIdx>=0) instance.NewFactionDeployment();
return instance.deployingFacIdx;
}
public static bool RequireManualDeployment(){ return instance._RequireManualDeployment()>=0; }
public int _RequireManualDeployment(int offset=0){
if(!GameControl.EnableUnitDeployment()) return -1;
//if(unitDeployed) return -1;
for(int i=0+offset; i<factionList.Count; i++){
if(!factionList[i].playableFaction) continue;
if(factionList[i].deployingList.Count>0) return i;
}
return -1;
}
public int deployingFacIdx=-1;
public int deployingUnitIdx=-1;
public static bool DeployingUnit(){ return instance.deployingFacIdx>=0; }
public static int GetDeployingFacIdx(){ return instance.deployingFacIdx; }
public static int GetDeployingUnitIdx(){ return instance.deployingUnitIdx; }
public static void SetDeployingUnitIdx(int idx){ instance.deployingUnitIdx=idx; }
//~ public static void NextUnitToDeploy(){
//~ instance.deployingUnitIdx+=1;
//~ if(instance.deployingUnitIdx>=instance.factionList[deployingFacIdx].deployingList.Count) instance.deployingUnitIdx=0;
//~ }
//~ public static void PrevUnitToDeploy(){
//~ instance.deployingUnitIdx-=1;
//~ if(instance.deployingUnitIdx<0) instance.deployingUnitIdx=instance.factionList[deployingFacIdx].deployingList.Count-1;
//~ }
//private bool unitDeployed=false;
//public static bool UnitDeployed(){ return instance.unitDeployed; }
public void DeployAllUnit(){
//unitDeployed=true;
for(int i=0; i<factionList.Count; i++){
if(GameControl.EnableUnitDeployment() && factionList[i].playableFaction) continue;
factionList[i].factionID=i;
factionList[i].DeployUnit();
}
}
public void InitAITrigger(){
if(!hasAIInGame) return;
for(int i=0; i<factionList.Count; i++){
if(factionList[i].playableFaction) continue;
for(int n=0; n<factionList[i].unitList.Count; n++) CheckAITrigger(factionList[i].unitList[n]);
}
}
public static void CheckAITrigger(Unit unit){ instance._CheckAITrigger(unit); }
public void _CheckAITrigger(Unit unit){
if(!hasAIInGame) return;
for(int i=0; i<factionList.Count; i++){
if(unit.triggered && factionList[i].playableFaction) continue;
if(factionList[i].factionID==unit.GetFacID()) continue;
for(int n=0; n<factionList[i].unitList.Count; n++){
if(unit.triggered && factionList[i].unitList[n].triggered) continue;
float dist=GridManager.GetDistance(unit.node, factionList[i].unitList[n].node);
if(dist<=factionList[i].unitList[n].GetSight()) factionList[i].unitList[n].triggered=true;
if(dist<=unit.GetSight()){
unit.triggered=true;
if(factionList[i].playableFaction) break;
}
}
}
}
public static void StartGame(){ instance._StartGame(); }
public void _StartGame(){
for(int i=0; i<factionList.Count; i++) factionList[i].StartGame(i);
if(TurnControl.IsUnitPerTurn()){
for(int i=0; i<factionList.Count; i++){
for(int n=0; n<factionList[i].unitList.Count; n++){
allUnitList.Add(factionList[i].unitList[n]);
//factionList[i].unitList[n].instanceID=Random.Range(0, 9999);
}
}
allUnitList=SortUnitListByPriority(allUnitList);
}
if(TurnControl.IsFactionPerTurn()){
for(int i=0; i<factionList.Count; i++){
factionList[i].unitList=SortUnitListByPriority(factionList[i].unitList);
}
}
InitAITrigger();
}
public static bool CheckIfNewTurnEndRound(int turnIdx){
if(TurnControl.IsUnitPerTurn()){
return turnIdx>=instance.allUnitList.Count;
}
else if(TurnControl.IsFactionPerTurn()){
return turnIdx>=instance.factionList.Count;
}
return false;
}
public static void EndTurn_UnitPerTurn(int turnIdx){
//if(turnIdx>=instance.allUnitList.Count) turnIdx=0;
if(instance.allUnitList[turnIdx]==null || instance.allUnitList[turnIdx].hp<=0){ //in case the unit is destroy by dot or other effect
TurnControl.EndTurn();
return;
}
instance.allUnitList[turnIdx].NewTurn();
if(instance.allUnitList[turnIdx].playableUnit){
TBSelectUnit(instance.allUnitList[turnIdx]);
for(int i=0; i<instance.factionList.Count; i++){
if(instance.factionList[i].factionID==instance.allUnitList[turnIdx].GetFacID()){
TBTK.OnSelectFaction(instance.factionList[i]); break;
}
}
}
else{
AI.MoveUnit(instance.allUnitList[turnIdx]);
}
//return turnIdx;
}
public static void EndTurn_FactionPerTurn(int turnIdx){
//if(turnIdx>=instance.factionList.Count) turnIdx=0;
instance.factionList[turnIdx].NewTurn();
if(instance.factionList[turnIdx].playableFaction){
TBSelectUnit(instance.factionList[turnIdx].unitList[0]);
TBTK.OnSelectFaction(instance.factionList[turnIdx]);
}
else{
AI.MoveFaction(instance.factionList[turnIdx]);
}
//return turnIdx;
}
//~ private bool aiToMoveNext=false;
//~ private unit unitToMoveNext=false;
//~ public static Unit NextUnitToMove;
//~ public static void MoveAI(int turnIdx){
//~ aiToMoveNext=false;
//~ if(TurnControl.IsUnitPerTurn()){
//~ AI.MoveUnit(instance.allUnitList[turnIdx]);
//~ }
//~ else if(TurnControl.IsFactionPerTurn()){
//~ AI.MoveFaction(instance.factionList[turnIdx]);
//~ }
//~ }
//to iterate unit ability and effect CD
public static IEnumerator EndTurn_IterateCD(){
for(int i=0; i<instance.factionList.Count; i++){
for(int n=0; n<instance.factionList[i].unitList.Count; n++){
instance.factionList[i].unitList[n].IterateCD();
if(TurnControl.WaitForUnitDestroy() && instance.factionList[i].unitList[n].hp<=0)
yield return instance.StartCoroutine(instance.factionList[i].unitList[n].DestroyRoutine());
}
}
}
//~ public static bool CanSwitchUnit(){
//~ if(!TurnControl.AllowUnitSwitching) return false;
//~ if(TurnControl.IsUnitPerTurn()) return false;
//~ return true;
//~ }
[Space(8)] public int currentFacID=-1;
public static int GetCurrentFactionID(){ return instance.currentFacID; }
public static void SelectNextUnit(){
//if(TurnControl.IsUnitPerTurn()){
// GameControl.EndTurn();
//}
if(TurnControl.IsFactionPerTurn()){
if(GetSelectedFaction().GetMoveCount()>=TurnControl.GetUnitLimit()) TBSelectUnit(instance.selectedUnit);
else TBSelectUnit(instance.factionList[instance.currentFacID].GetNextUnitInTurn());
}
}
public static void TBSelectUnit(Unit unit){ instance._SelectUnit(unit); } //by non UI-user event
public static void SelectUnit(Unit unit){
if(!TurnControl.CanSwitchUnit(unit)) return;
instance._SelectUnit(unit);
}
public void _SelectUnit(Unit unit){
selectedUnit=unit;
if(unit!=null && unit.playableUnit){
//selectIndicator.position=selectedUnit.GetPos();
currentFacID=instance.selectedUnit.GetFacID();
factionList[currentFacID].UpdateTurnIdx(selectedUnit);
GridManager.SelectUnit(unit);
GridIndicator.SetSelect(unit.node);
GridIndicator.ShowMovable(GridManager.GetWalkableList());
GridIndicator.ShowHostile(GridManager.GetAttackableList());
selectedUnit.AudioPlaySelect();
}
else{
GridIndicator.HideAll();
GridIndicator.SetSelect(null);
//else selectIndicator.position=new Vector3(0, 9999, 0);
}
TBTK.OnSelectUnit(unit);
}
public static List<Unit> SortUnitListByPriority(List<Unit> list){
List<Unit> newList=new List<Unit>();
while(list.Count>0){
int highestIdx=0;
float highestVal=0;
for(int i=0; i<list.Count; i++){
float turnPriority=list[i].GetTurnPriority();
if(turnPriority>highestVal || turnPriority==highestVal && Random.value<0.5f){
highestVal=turnPriority;
highestIdx=i;
}
}
newList.Add(list[highestIdx]);
list.RemoveAt(highestIdx);
}
return newList;
}
private IEnumerator SelectedUnitDestroyed(){
while(GameControl.ActionInProgress() || AI.ActionInProgress()) yield return null;
if(TurnControl.IsFactionPerTurn()) SelectNextUnit();
else if(TurnControl.IsUnitPerTurn()) GameControl.EndTurn();
}
public static void UnitDestroyed(Unit unit){ instance._UnitDestroyed(unit); }
public void _UnitDestroyed(Unit unit){
if(selectedUnit==unit){
StartCoroutine(SelectedUnitDestroyed());
//~ Debug.Log("selected unit is destroyed");
//~ if(TurnControl.IsFactionPerTurn()) SelectNextUnit();
//~ else if(TurnControl.IsUnitPerTurn()) GameControl.EndTurn();
//if(TurnControl.IsUnitPerTurn())
}
if(TurnControl.IsUnitPerTurn()){
if(allUnitList.IndexOf(unit)<=TurnControl.GetTurn()) TurnControl.RevertTurn();
allUnitList.Remove(unit);
}
TBTK.OnUnitDestroyed(unit);
bool factionCleared=factionList[unit.GetBaseFacID()].RemoveUnit(unit);
if(unit.tempFacID>=0) factionCleared|=factionList[unit.tempFacID].RemoveUnit(unit);
if(!factionCleared) return;
int facWithUnitCount=0;
int facIdxWithUnit=-1;
for(int i=0; i<factionList.Count; i++){
if(factionList[i].unitList.Count>0){
facIdxWithUnit=i;
facWithUnitCount+=1;
}
}
if(facWithUnitCount<=1) GameControl.GameOver(factionList[facIdxWithUnit]);
}
public static void GameOver(){
for(int i=0; i<instance.factionList.Count; i++) instance.factionList[i].CacheUnit_PostGame();
}
public static List<Unit> GetAllHostileUnits(int facID){
List<Unit> list=new List<Unit>();
for(int i=0; i<instance.factionList.Count; i++){
if(instance.factionList[i].factionID==facID) continue;
list.AddRange(instance.factionList[i].unitList);
}
return list;
}
public static List<Unit> GetAllUnits(){
if(TurnControl.IsUnitPerTurn()) return instance.allUnitList;
List<Unit> list=new List<Unit>();
for(int i=0; i<instance.factionList.Count; i++) list.AddRange(instance.factionList[i].unitList);
return list;
}
public static void AddUnit(Unit unit, int facID){
if(TurnControl.IsUnitPerTurn()){
for(int i=0; i<instance.allUnitList.Count; i++){
if(instance.allUnitList[i].GetTurnPriority()>unit.GetTurnPriority()) continue;
instance.allUnitList.Insert(i, unit);
break;
}
if(GetSelectedUnit().GetTurnPriority()<unit.GetTurnPriority()) TurnControl.AddTurn();
TBTK.OnUnitOrderChanged();
}
for(int i=0; i<instance.factionList.Count; i++){
if(instance.factionList[i].factionID!=facID) continue;
instance.factionList[i].AddUnit(unit);
break;
}
}
public static void AddAbilityToPlayerFaction(int abilityPID){
foreach(Faction fac in instance.factionList){
if(!fac.playableFaction) continue;
fac.AddAbility(abilityPID);
}
}
public static void AddAbilityToPlayerUnit(int abilityPID, List<int> unitPIDList){
foreach(Faction fac in instance.factionList){
if(!fac.playableFaction) continue;
foreach(Unit unit in fac.unitList){
if(unitPIDList!=null && !unitPIDList.Contains(unit.prefabID)) continue;
unit.AddAbility(abilityPID);
}
}
}
public static void AddFacSwitchUnit(Unit unit){
for(int i=0; i<instance.factionList.Count; i++){
if(instance.factionList[i].factionID!=unit.tempFacID) continue;
instance.factionList[i].unitList.Add(unit);
//factionList.tempUnitList.Add(unit);
break;
}
}
public static void RemoveFacSwitchUnit(Unit unit){
for(int i=0; i<instance.factionList.Count; i++){
if(instance.factionList[i].factionID!=unit.tempFacID) continue;
instance.factionList[i].unitList.Remove(unit);
//factionList.tempUnitList.Remove(unit);
break;
}
}
//only used in editor
public static Unit PlaceUnit(GameObject unitPrefab, Node node, float dir, bool spawn=true){
//GameObject obj=(GameObject)MonoBehaviour.Instantiate(unitPrefab, nodeList[rand].GetPos(), Quaternion.identity);
GameObject obj;
Quaternion rot=Unit.enableRotation ? Quaternion.Euler(0, dir, 0) : Quaternion.identity ;
if(spawn){
//~ #if UNITY_EDITOR
//~ obj=(GameObject)PrefabUtility.InstantiatePrefab(unitPrefab);
//~ obj.transform.position=node.GetPos();
//~ #else
obj=(GameObject)MonoBehaviour.Instantiate(unitPrefab, node.GetPos(), rot);
//~ #endif
}
else{
obj=unitPrefab;
obj.transform.position=node.GetPos();
obj.transform.rotation=rot;
}
if(GetInstance()!=null) obj.transform.parent=instance.transform;
Unit unit=obj.GetComponent<Unit>();
unit.node=node; node.unit=unit;
return unit;
}
//for gizmo
public static Color GetFacColor(int idx){
if(instance==null) instance=(UnitManager)FindObjectOfType(typeof(UnitManager));
return idx<instance.factionList.Count ? instance.factionList[idx].color : new Color(0, 0, 0, 0);
}
public static List<Faction> cachedFactionList=new List<Faction>();
public static void ClearCache(){ cachedFactionList.Clear(); }
public static void CacheFaction(int factionID, List<Unit> unitList, bool postBattle=false){
List<CachedUnitInfo> unitInfoList=new List<CachedUnitInfo>();
for(int i=0; i<unitList.Count; i++){
unitInfoList.Add(new CachedUnitInfo(unitList[i]));
unitList[i]=UnitDB.GetPrefab(unitList[i].prefabID);
}
int index=CheckCachedFaction(factionID);
if(index>=0){
cachedFactionList[index].unitList=unitList;
cachedFactionList[index].cachedUnitInfoList=unitInfoList;
}
else{
Faction fac=new Faction();
fac.factionID=factionID;
fac.unitList=unitList;
fac.cachedUnitInfoList=unitInfoList;
cachedFactionList.Add(fac);
}
}
public static int CheckCachedFaction(int factionID){
for(int i=0; i<cachedFactionList.Count; i++){
if(cachedFactionList[i].factionID==factionID) return i;
}
return -1;
}
public static List<Unit> GetCachedUnitList(int index){
return ((index>=0 && cachedFactionList.Count>index) ? cachedFactionList[index].unitList : new List<Unit>() );
}
public static List<CachedUnitInfo> GetCachedUnitInfoList(int index){
return ((index>=0 && cachedFactionList.Count>index) ? cachedFactionList[index].cachedUnitInfoList : new List<CachedUnitInfo>() );
}
}
public class CachedUnitInfo{
//public float hp;
public CachedUnitInfo(Unit unit){
//hp=unit.hp;
}
}
[System.Serializable]
public class Faction{
//[HideInInspector]
public int factionID=0;
[HideInInspector] public int factionIdx=-1;
public string name="Faction";
public Color color; //not used in runtime
public float direction;
public int turnIdx; //indicate which unit in the faction is being selected right now, used in FactionPerTurn only
public void UpdateTurnIdx(Unit unit){ turnIdx=unitList.IndexOf(unit); }
[HideInInspector]
public int movedUnitCount=0; //not in used
public bool playableFaction=true;
public List<Unit> unitList=new List<Unit>();
public List<CachedUnitInfo> cachedUnitInfoList=new List<CachedUnitInfo>();
public List<Unit> startingUnitList=new List<Unit>();
public List<Unit> deployingList=new List<Unit>();
public List<SpawnGroup> spawnGroupList=new List<SpawnGroup>();
public bool loadFromData;
public bool saveToData;
public bool saveLoadedUnitOnly;
//public int cachedFacID=0; //the factionID as assigned in editor
[HideInInspector] //for grid regeneration
public List<Vector3> deploymentPointList=new List<Vector3>();
public void CacheUnit_PostGame(){ //called by the faction instance in a game when the game is over
if(!saveToData) return;
if(!saveLoadedUnitOnly){
UnitManager.CacheFaction(factionID, unitList, false);
return;
}
List<Unit> newList=new List<Unit>();
for(int i=0; i<unitList.Count; i++){
if(unitList[i].loadedFromCache) newList.Add(unitList[i]);
}
UnitManager.CacheFaction(factionID, newList, true);
}
public void Init(int facID){
factionIdx=facID;
bool loadedFromCache=false;
if(loadFromData){
int index=UnitManager.CheckCachedFaction(factionID);
if(index>=0){
startingUnitList=UnitManager.GetCachedUnitList(index);
cachedUnitInfoList=UnitManager.GetCachedUnitInfoList(index);
loadedFromCache=true;
}
}
for(int i=0; i<startingUnitList.Count; i++){
if(startingUnitList[i]==null) continue;
GameObject unitObj=(GameObject)MonoBehaviour.Instantiate(startingUnitList[i].gameObject, new Vector3(0, 99999, 0), Quaternion.identity);
deployingList.Add(unitObj.GetComponent<Unit>());
if(loadedFromCache){
deployingList[deployingList.Count-1].loadedFromCache=true;
//deployingList[deployingList.Count-1].hp=cachedUnitInfoList[i].hp;
}
unitObj.transform.parent=UnitManager.GetInstance().transform;
}
for(int i=0; i<deployingList.Count; i++){
deployingList[i].SetFacID(factionID);
deployingList[i].playableUnit=playableFaction;
}
for(int i=0; i<unitList.Count; i++){
unitList[i].SetFacID(factionID);
unitList[i].playableUnit=playableFaction;
}
//abilityIDList=new List<int>{ 0, 1 };
for(int i=0; i<abilityIDList.Count; i++) AddAbility(abilityIDList[i]);
}
public void AddAbility(int abPrefabID){
abilityList.Add(AbilityFDB.GetPrefab(abPrefabID).Clone());
abilityList[abilityList.Count-1].Init(factionID, abilityList.Count-1);
}
public void AddUnit(Unit unit){ //add unit during runtime (mid-game)
unit.SetFacID(factionID);
unit.playableUnit=playableFaction;
unit.NewTurn();
unitList.Add(unit);
TBTK.OnNewUnit(unit, factionIdx);
}
public void DeployUnit(){
List<Node> nodeList=GridManager.GetDeploymentNode(factionID);
int count=deployingList.Count;
for(int i=0; i<count; i++){
if(nodeList.Count==0) break;
int rand=Random.Range(0, nodeList.Count);
Unit unit=UnitManager.PlaceUnit(deployingList[0].gameObject, nodeList[rand], direction, false);
unitList.Add(unit);
nodeList.RemoveAt(rand); deployingList.RemoveAt(0);
}
}
public void StartGame(int facID){
for(int i=0; i<unitList.Count; i++){
unitList[i].NewTurn(true);
}
}
public bool RemoveUnit(Unit unit){
unitList.Remove(unit);
return unitList.Count==0;
}
public void NewTurn(){
turnIdx=0;
for(int i=0; i<unitList.Count; i++) unitList[i].NewTurn();
movedUnitCount=0;
}
public void SelectUnit(Unit unit){
UpdateTurnIdx(unit);
}
public Unit GetNextUnitInTurn(){
if(unitList.Count==0) return null;
int newIdx=(turnIdx+1)%unitList.Count;
return unitList[newIdx];
}
public int GetMoveCount(){ //only used in factionPerTurn
int count=0;
for(int i=0; i<unitList.Count; i++) count+=unitList[i].HasTakenAction() ? 1 : 0 ;
return count;
}
public List<int> abilityIDList=new List<int>();
public List<Ability> abilityList=new List<Ability>(); //runtime attribute
public Ability GetAbility(int idx){ return abilityList[idx]; }
public Ability._AbilityStatus SelectAbility(int idx){
Ability._AbilityStatus abilityStatus=abilityList[idx].IsAvailable();
if(abilityStatus!=Ability._AbilityStatus.Ready) return abilityStatus;
//~ int usable=abilityList[idx].IsAvailable();
//~ if(usable!=0) return usable;
if(!abilityList[idx].requireTarget){
UseAbility(idx, null);
}
else{
AbilityManager.AbilityTargetModeFac(this, abilityList[idx]);
}
return 0;
}
public void UseAbility(int idx, Node target){
GameControl.FactionUseAbility(this, abilityList[idx], target);
//StartCoroutine(_UseAbility(abilityList[idx], target));
}
public IEnumerator UseAbilityRoutine(Ability ability, Node target){
Debug.Log("UseAbilityRoutine "+target);
ability.Activate();
//ap-=ability.apCost;
//~ yield return CRoutine.Get().StartCoroutine(AbilityHit(ability, target));
yield return CRoutine.Get().StartCoroutine(ability.HitTarget(target));
}
//~ public IEnumerator AbilityHit(Ability ability, Node target){
//~ ability.HitTarget(target);
//~ }
}
[System.Serializable]
public class SpawnGroup{
public int ID;
public int countMin=5;
public int countMax=5;
public List<Unit> unitList=new List<Unit>();
public List<int> unitCountMinList=new List<int>();
public List<int> unitCountMaxList=new List<int>();
[HideInInspector] //for grid regeneration
public List<Vector3> spawnPointList=new List<Vector3>();
public void Spawn(Faction fac){
//use a dummy list so the original list wont get altered if this is run in EditMode
List<Unit> cloneUnitList=new List<Unit>( unitList );
List<int> cloneMinList=new List<int>( unitCountMinList );
List<int> cloneMaxList=new List<int>( unitCountMaxList );
List<Unit> spawnedUnitList=new List<Unit>();
List<Node> nodeList=GridManager.GetSpawnGroup(fac.factionID, ID);
int limit=(int)Mathf.Min(nodeList.Count, Rand.Range(countMin, countMax)); int currentCount=0;
//loop through the unitlist, place the limited amount of them
while(nodeList.Count>0 && currentCount<limit){
bool hasMinimum=false;
for(int i=0; i<cloneUnitList.Count; i++){
if(nodeList.Count==0) break;
if(unitCountMinList[i]<=0) continue;
int nodeIdx=Rand.Range(0, nodeList.Count);
spawnedUnitList.Add(UnitManager.PlaceUnit(cloneUnitList[i].gameObject, nodeList[nodeIdx], fac.direction));
nodeList.RemoveAt(nodeIdx); currentCount+=1;
cloneMinList[i]-=1; cloneMaxList[i]-=1;
if(cloneMinList[i]<=0 || cloneMaxList[i]<=0){
cloneUnitList.RemoveAt(i); cloneMinList.RemoveAt(i); cloneMaxList.RemoveAt(i); i-=1;
continue;
}
}
if(!hasMinimum) break;
}
while(currentCount<limit && nodeList.Count>0 && cloneUnitList.Count>0){
int unitIdx=Rand.Range(0, cloneUnitList.Count);
int nodeIdx=Rand.Range(0, nodeList.Count);
spawnedUnitList.Add(UnitManager.PlaceUnit(cloneUnitList[unitIdx].gameObject, nodeList[nodeIdx], fac.direction));
nodeList.RemoveAt(nodeIdx); currentCount+=1;
cloneMaxList[unitIdx]-=1;
if(cloneMaxList[unitIdx]<=0){
cloneUnitList.RemoveAt(unitIdx); cloneMaxList.RemoveAt(unitIdx);
continue;
}
}
for(int i=0; i<spawnedUnitList.Count; i++) fac.unitList.Add(spawnedUnitList[i]);
}
}
}