Assets/Scripts/Battle/BattleManager.cs (view raw)
1using System;
2using System.Collections;
3using System.Collections.Generic;
4using UnityEngine;
5using UnityEngine.SceneManagement;
6using UnityEngine.UI;
7
8public class BattleManager : MonoBehaviour
9{
10 #region Private
11 private int currentTurn = 0;
12 private Fighter currentTarget;
13 private Action currentAction;
14 private float lerpStart;
15 private GameObject player;
16 public BattleUIManager ui;
17 private BadGuy tmpbad;
18 private bool action_output = true;
19 #endregion
20
21 public Fighter turn;
22 public BadGuy enemy;
23 public int enemyGold;
24 public Inventory enemyItems;
25
26 public Camera main_camera;
27 public GameMaster gm;
28
29 enum Status
30 {
31 StartTurn = 0,
32 EnableIO = 1,
33 DisableIO = 3,
34 NextTurn = 5,
35 Wait = 69
36 }
37 private Status status = Status.Wait;
38
39
40 [Header("Fighter Prefabs")]
41 public GameObject p_paladin;
42 public GameObject p_archer;
43 public GameObject p_boxer;
44 public GameObject p_mage;
45
46 [Header("Enemy Prefabs")]
47 public GameObject p_orc;
48 public GameObject p_mutant;
49 //public GameObject p_enemy1;
50
51 [Header("Current fighters")]
52 public List<Fighter> fighters;
53
54 // Start is called before the first frame update
55 void Start()
56 {
57 //inizia la battaglia
58 gm = GameMaster.Instance;
59 ui = GetComponent<BattleUIManager>();
60
61 fighters = new List<Fighter>();
62 Fighter tmpfighter;
63 foreach(Stats s in gm.Party)
64 {
65 //instantiate good guy
66 tmpfighter = instantiateFighter(s.Name, s.Name + "Spawn").GetComponent<Fighter>();
67
68 //set current HP and MP
69 tmpfighter.stats = new Stats(s);
70
71 //check if fighter's already dead
72 if (tmpfighter.stats.HP == 0)
73 {
74 tmpfighter.animator.SetTrigger("Corpse");
75 tmpfighter.dead = true;
76 }
77
78 fighters.Add(tmpfighter);
79 }
80 enemy = (BadGuy)instantiateFighter(gm.GetEnemyType(), "EnemySpawn").GetComponent<Fighter>();
81 fighters.Add(enemy);
82
83 enemyGold = enemy.goldDrop;
84 enemyItems = enemy.itemsDrop;
85
86 fighters.Sort(Fighter.SortByAgl);
87
88 //aspetto che finisca l'animazione e poi vado
89 UI.changeText(ui.status, enemy.stats.Name + " approaches!");
90 StartCoroutine(waitThenStatus(UI.BattleSpeed, Status.StartTurn));
91
92 }
93
94 private void Update()
95 {
96 #region State Machine
97 switch (status)
98 {
99 case Status.StartTurn:
100 turn = fighters[currentTurn];
101 //reset defence
102 if (turn.defending)
103 {
104 turn.defending = false;
105 turn.stats.DEF = turn.stats.MaxDEF;
106 }
107
108 if (turn.dead)
109 {
110 status = Status.NextTurn;
111 } else
112 {
113 //step forward
114 if (action_output)
115 {
116 turnEffect(turn, true);
117 }
118 UI.changeText(ui.status, "It's " + turn + "'s turn.");
119
120 if (turn is BadGuy) //load AI
121 {
122 //execute AI
123 tmpbad = (BadGuy)turn;
124 UI.changeText(ui.status, tmpbad.Combat_AI());
125
126 //wait for animation
127 StartCoroutine(waitThenStatus(UI.BattleSpeed * 2, Status.NextTurn));
128 }
129 else
130 {
131 //show input UI
132 ui.showAbilities(true);
133 }
134 status = Status.Wait;
135 }
136 break;
137 case Status.DisableIO:
138 UI.changeText(ui.status, AbilityDB.Process(turn, currentAction, currentTarget, true, out action_output));
139
140 if (action_output)
141 {
142 StartCoroutine(waitThenStatus(UI.BattleSpeed * 2, Status.NextTurn));
143 } else
144 {
145 StartCoroutine(waitThenStatus(UI.BattleSpeed * 2, Status.StartTurn));
146 }
147 status = Status.Wait;
148 break;
149 case Status.NextTurn:
150 if (!turn.dead)
151 {
152 turnEffect(turn, false);
153 }
154 //kill'em
155 foreach (Fighter f in fighters)
156 {
157 if(f.stats.HP == 0 && f.dead == false)
158 {
159 f.animator.SetTrigger("Dead");
160 f.dead = true;
161 }
162 }
163
164 //did i lose?
165 if (countGuys(false) == 0)
166 {
167 StartCoroutine(endBattle(UI.BattleSpeed * 5, false));
168 status = Status.Wait; //wait until scene has changed
169 }
170 else //did i win?
171 if (countGuys(true) == 0)
172 {
173 //start victory animations
174 foreach(Fighter f in getGuys(false))
175 {
176 f.animator.SetTrigger("Victory");
177 }
178 StartCoroutine(endBattle(UI.BattleSpeed * 3, true));
179 status = Status.Wait;
180 } else
181 {
182 //next turn
183 currentTurn++;
184 if (currentTurn == fighters.Count)
185 {
186 currentTurn = 0;
187 }
188 status = Status.StartTurn;
189 }
190 break;
191 }
192 #endregion
193 }
194
195 public void getInput(Action Action, Fighter Target)
196 {
197 if (status == Status.Wait)
198 {
199 currentAction = Action;
200 currentTarget = Target;
201 status = Status.DisableIO;
202 }
203 }
204
205 public Fighter[] getGuys(bool bad)
206 {
207 List<Fighter> tmp = new List<Fighter>();
208 foreach (Fighter figh in fighters)
209 {
210 if ((figh is BadGuy) == bad && !figh.dead)
211 {
212 tmp.Add(figh);
213 }
214 }
215 return tmp.ToArray();
216 }
217
218 public int countGuys(bool bad)
219 {
220 int i = 0;
221 foreach (Fighter figh in fighters)
222 {
223 if ((figh is BadGuy) == bad && !figh.dead)
224 {
225 i++;
226 }
227 }
228 return i;
229 }
230
231 private GameObject instantiateFighter(string type, string spawnPoint)
232 {
233 Transform spot = GameObject.Find(spawnPoint).transform;
234 switch (type)
235 {
236 case "Paladin":
237 if (p_paladin)
238 {
239 return Instantiate(p_paladin, spot.position, spot.rotation);
240 }
241 break;
242 case "Archer":
243 if (p_archer)
244 {
245 return Instantiate(p_archer, spot.position, spot.rotation);
246 }
247 break;
248 case "Boxer":
249 if (p_boxer)
250 {
251 return Instantiate(p_boxer, spot.position, spot.rotation);
252 }
253 break;
254 case "Mage":
255 if (p_mage)
256 {
257 return Instantiate(p_mage, spot.position, spot.rotation);
258 }
259 break;
260
261 case "Orc":
262 return Instantiate(p_orc, spot.position, spot.rotation);
263 case "Mutant":
264 return Instantiate(p_mutant, spot.position, spot.rotation);
265 default:
266 Debug.Log("Wrong name!");
267 return null;
268 }
269 return null;
270 }
271
272 private IEnumerator endBattle(float offset, bool didYouWin)
273 {
274 yield return new WaitForSeconds(offset);
275 if (didYouWin)
276 {
277 ui.showResults(enemy.goldDrop, enemyItems);
278 yield return new WaitForSeconds(offset + 1);
279 gm.EndBattle(true);
280 } else
281 {
282 gm.EndBattle(false);
283 }
284 }
285
286 private IEnumerator waitThenStatus(float seconds, Status nextStatus)
287 {
288 yield return new WaitForSeconds(seconds);
289 status = nextStatus;
290 }
291
292 private IEnumerator MoveFromTo(Transform objectToMove, Vector3 a, Vector3 b, float speed)
293 {
294 float step = (speed / (a - b).magnitude) * Time.fixedDeltaTime;
295 float t = 0;
296 while (t <= 1.0f)
297 {
298 t += step; // Goes from 0 to 1, incrementing by step each time
299 objectToMove.position = Vector3.Lerp(a, b, t); // Move objectToMove closer to b
300 yield return new WaitForFixedUpdate(); // Leave the routine and return here in the next frame
301 }
302 objectToMove.position = b;
303 }
304
305 public void turnEffect(Fighter f, bool onOff)
306 {
307 int distance = 4;
308
309 if(f is BadGuy)
310 {
311 distance *= -1;
312 }
313 if (!onOff)
314 {
315 distance *= -1;
316 }
317
318 StartCoroutine(MoveFromTo(f.transform, f.transform.position, f.transform.position + new Vector3(0, 0, distance), 20));
319 }
320}