871 lines
27 KiB
C#
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]);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
} |