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