1 #include "stadium.h"
2 #include "image.h"
3 #include "game.h"
4 #include "soccergame.h"
5 #include "actormanager.h"
6 #include "rendermanager.h"
7 #include "collision.h"
8 #include "activecap.h"
9 
10 #include <fstream>
11 #include <string>
12 
13 #define SOCCERGAME SG
14 
15 using namespace std;
16 
Stadium(Game * ag)17 Stadium::Stadium(Game *ag):g(ag),goldengoal(false)
18 {
19 }
20 
~Stadium()21 Stadium::~Stadium()
22 {
23 }
24 
init()25 void Stadium::init()
26 {
27 	theme=new Theme("theme.txt");
28 	cap_pass=NULL;
29 	cap_fault=NULL;
30 	finish=false;
31 
32 	//Los aros alrededor de la chapa
33 	ActiveCap::setFrames(theme->activecap_frames);
34 
35 	//Parte logica de la porteria
36 	int goal_y=theme->stadium_y+(theme->stadium_h-theme->goal_h)/2;
37 
38 	//Porterias
39 	g_left=new Goal(SG::LEFT);
40 	g_left->init();
41 	//Separamos la parte grafica de la logica
42 	g_left->setPos(Vector(theme->stadium_x-g_left->get_w()+theme->poster,
43 				theme->stadium_y+(theme->stadium_h-g_left->get_h())/2));
44 	g->actormanager->activate(g_left);
45 
46 	g_right=new Goal(SG::RIGHT);
47 	g_right->init();
48 	//Separamos la parte grafica de la logica
49 	g_right->setPos(Vector(theme->stadium_x+theme->stadium_w-theme->poster,
50 				theme->stadium_y+(theme->stadium_h-g_right->get_h())/2));
51 	g->actormanager->activate(g_right);
52 
53 	//Banda arriba
54 	Line *l=new Line(SG::NEUTRAL);
55 	l->init();
56 	l->setPos(Vector(theme->stadium_x,theme->stadium_y));
57 	l->setSize(Vector(theme->stadium_w,0));
58 	g->actormanager->activate(l);
59 
60 	//Banda abajo
61 	l=new Line(SG::NEUTRAL);
62 	l->init();
63 	l->setPos(Vector(theme->stadium_x,theme->stadium_y+theme->stadium_h));
64 	l->setSize(Vector(theme->stadium_w,0));
65 	g->actormanager->activate(l);
66 
67 	//fondo izquierda arriba
68 	l=new Line(SG::NEUTRAL);
69 	l->init();
70 	l->setPos(Vector(theme->stadium_x,theme->stadium_y));
71 	l->setSize(Vector(0,goal_y-theme->stadium_y));
72 	g->actormanager->activate(l);
73 
74 	//fondo izquierda abajo
75 	l=new Line(SG::NEUTRAL);
76 	l->init();
77 	l->setPos(Vector(theme->stadium_x,goal_y+theme->goal_h));
78 	l->setSize(Vector(0,goal_y-theme->stadium_y));
79 	g->actormanager->activate(l);
80 
81 	//porteria izquierda
82 	l=new Line(SG::NEUTRAL);
83 	l->init();
84 	l->setPos(Vector(theme->stadium_x-theme->goal_w,goal_y));
85 	l->setSize(Vector(0,theme->goal_h));
86 	g->actormanager->activate(l);
87 
88 	//porteria izquierda lateral arriba
89 	l=new Line(SG::NEUTRAL);
90 	l->init();
91 	l->setPos(Vector(theme->stadium_x-theme->goal_w,goal_y));
92 	l->setSize(Vector(theme->goal_w,0));
93 	g->actormanager->activate(l);
94 
95 	//porteria izquierda lateral de abajo
96 	l=new Line(SG::NEUTRAL);
97 	l->init();
98 	l->setPos(Vector(theme->stadium_x-theme->goal_w,goal_y+theme->goal_h));
99 	l->setSize(Vector(theme->goal_w,0));
100 	g->actormanager->activate(l);
101 
102 	//fondo derecha arriba
103 	l=new Line(SG::NEUTRAL);
104 	l->init();
105 	l->setPos(Vector(theme->stadium_x+theme->stadium_w,theme->stadium_y));
106 	l->setSize(Vector(0,goal_y-theme->stadium_y));
107 	g->actormanager->activate(l);
108 
109 	//fondo derecha abajo
110 	l=new Line(SG::NEUTRAL);
111 	l->init();
112 	l->setPos(Vector(theme->stadium_x+theme->stadium_w,
113 				goal_y+theme->goal_h));
114 	l->setSize(Vector(0,goal_y-theme->stadium_y));
115 	g->actormanager->activate(l);
116 
117 	//porteria derecha
118 	l=new Line(SG::NEUTRAL);
119 	l->init();
120 	l->setPos(Vector(theme->stadium_x+theme->stadium_w+theme->goal_w,goal_y));
121 	l->setSize(Vector(0,theme->goal_h));
122 	g->actormanager->activate(l);
123 
124 	//porteria izquierda lateral arriba
125 	l=new Line(SG::NEUTRAL);
126 	l->init();
127 	l->setPos(Vector(theme->stadium_x+theme->stadium_w,goal_y));
128 	l->setSize(Vector(theme->goal_w,0));
129 	g->actormanager->activate(l);
130 
131 	//porteria izquierda lateral de abajo
132 	l=new Line(SG::NEUTRAL);
133 	l->init();
134 	l->setPos(Vector(theme->stadium_x+theme->stadium_w,
135 				goal_y+theme->goal_h));
136 	l->setSize(Vector(theme->goal_w,0));
137 	g->actormanager->activate(l);
138 
139 	ball=new Ball(zero);
140 	ball->setInitialPos(Vector(theme->stadium_x+theme->stadium_w/2,
141 				theme->stadium_y+theme->stadium_h/2));
142 	ball->returnInitialPos();
143 	ball->setGraze(1.0-theme->graze);
144 	ball->setMass(theme->ball_mass);
145 	ball->init();
146 	g->actormanager->activate(ball);
147 
148 	Team::setGame(g);
149 	teams[SG::LEFT].init(SG::LEFT,theme);
150 	teams[SG::RIGHT].init(SG::RIGHT,theme);
151 
152 	//Minutos
153 	minutes=new TimeBoard(zero);
154 	minutes->setPos(Vector(theme->time_min_x,theme->time_min_y));
155 	minutes->countdown(theme->time);
156 	minutes->setType(TimeBoard::MINUTE);
157 	minutes->init();
158 	g->actormanager->activate(minutes);
159 
160 	//Segundos
161 	seconds=new TimeBoard(zero);
162 	seconds->setPos(Vector(theme->time_sec_x,theme->time_sec_y));
163 	seconds->countdown(theme->time);
164 	seconds->init();
165 	g->actormanager->activate(seconds);
166 
167 	//Tiempo del equipo
168 	time=new TimeBoard(zero);
169 	time->setPos(Vector(theme->time_team_x,theme->time_team_y));
170 	time->countdown(theme->time_team);
171 	time->init();
172 	g->actormanager->activate(time);
173 
174 	//Scores
175 	s_left=new Score(zero);
176 	s_left->setPos(Vector(theme->scoreboard_1_goals_x,theme->scoreboard_1_goals_y));
177 	s_left->init();
178 	g->actormanager->activate(s_left);
179 
180 	s_right=new Score(zero);
181 	s_right->setPos(Vector(theme->scoreboard_2_goals_x,theme->scoreboard_2_goals_y));
182 	s_right->init();
183 	g->actormanager->activate(s_right);
184 
185 	//Select
186 	s=new Select(zero);
187 	s->setLeft(Vector(theme->select_left_x,theme->select_left_y));
188 	s->setRight(Vector(theme->select_right_x,theme->select_right_y));
189 	s->init();
190 	g->actormanager->activate(s);
191 
192 	//Messenger
193 	messenger=new Messenger(g);
194 	messenger->init();
195 
196 	//Pase
197 	pass=new Pass(zero);
198 	pass->init();
199 
200 	changeTeam(SG::LEFT);
201 	startTurn();
202 }
203 
shutdown()204 void Stadium::shutdown()
205 {
206 	teams[SG::LEFT].shutdown();
207 	teams[SG::RIGHT].shutdown();
208 	messenger->shutdown();
209 	g->actormanager->clear();
210 }
211 
startTurn()212 void Stadium::startTurn()
213 {
214 	turn=1;
215 	time->setTime(theme->time_team);
216 	teams[s->getTeam()].throwCap();
217 	state=WAITING;
218 }
219 
update()220 bool Stadium::update()
221 {
222 	//Si se acaba el tiempo
223 	if(seconds->isEnd())
224 	{
225 		if(!goldengoal)
226 		{
227 			if(s_right->getNum()==s_left->getNum())
228 			{
229 				goldengoal=true;
230 				messenger->send(Messenger::GOLDEN);
231 			}
232 			else
233 				finish=true;
234 		}
235 	}
236 	if(teams[SG::LEFT].getNumCaps()==0)
237 		finish=true;
238 	if(teams[SG::RIGHT].getNumCaps()==0)
239 		finish=true;
240 
241 	switch(state)
242 	{
243 		case WAITING:
244 			if(teams[s->getTeam()].isOver())
245 				state=MOVING;
246 			//Si se le ha acabado el tiempo al equipo
247 			else if(time->isEnd())
248 			{
249 				messenger->send(Messenger::TIME);
250 				teams[s->getTeam()].stop();
251 				changeTeam();
252 				startTurn();
253 			}
254 			break;
255 
256 		case MOVING:
257 			//Si se han dejado de mover y no ha habido gol
258 			if(!isMoving())
259 			{
260 				//Si el equipo no ha gastado todos sus movimientos
261 				//le damos otro turno
262 				if(turn<theme->movements)
263 				{
264 					turn++;
265 					teams[s->getTeam()].throwCap();
266 					state=WAITING;
267 				}
268 				else
269 				{
270 					changeTeam();
271 					startTurn();
272 				}
273 			}
274 			break;
275 		case BALL:
276 			Cap *aux;
277 			if(isMoving())
278 			{
279 				//Comprobamos que no haya gol del left team
280 				if(ball->getPos().scale_x()-ball->getRadio()>
281 						theme->stadium_x+theme->stadium_w)
282 				{
283 					changeTeam(SG::RIGHT);
284 					s_left->goal();
285 					state=GOAL;
286 					messenger->send(Messenger::GOAL);
287 				}
288 				//Comprobamos que no haya gol del right team
289 				else if(ball->getPos().scale_x()+ball->getRadio()<theme->stadium_x)
290 				{
291 					changeTeam(SG::LEFT);
292 					s_right->goal();
293 					state=GOAL;
294 					messenger->send(Messenger::GOAL);
295 				}
296 			}
297 			//Comprobamos si ha habido pase
298 			else if((aux=isAPass()) !=NULL)
299 			{
300 				messenger->send(Messenger::PASS);
301 				teams[s->getTeam()].oneMore(aux);
302 				cap_pass=NULL;
303 				state=WAITING;
304 			}
305 			else
306 			{
307 				changeTeam();
308 				startTurn();
309 			}
310 			break;
311 		case GOAL:
312 			//Si ha habido gol esperamos a que todo se quede quieto
313 			if(!isMoving())
314 			{
315 				startTurn();
316 				//Colocamos todo de nuevo empezamos turno
317 				teams[SG::LEFT].collocateCaps();
318 				teams[SG::RIGHT].collocateCaps();
319 				ball->returnInitialPos();
320 				if(goldengoal==true)
321 					finish=true;
322 			}
323 			break;
324 		case FAULT:
325 			//Esperamos a que todo este quieto
326 			if(!isMoving())
327 			{
328 				//Si tiene amarilla
329 				if(cap_fault->getYellow())
330 				{
331 					teams[cap_fault->getTeam()].delCap(cap_fault);
332 					//Crear animacion tarjeta roja
333 					messenger->send(Messenger::RED);
334 				}
335 				else
336 				{
337 					cap_fault->setYellow();
338 					//Crear animacion tarjeta amarilla
339 					messenger->send(Messenger::YELLOW);
340 				}
341 
342 				cap_fault=NULL;
343 
344 				startTurn();
345 				teams[SG::LEFT].collocateCaps();
346 				teams[SG::RIGHT].collocateCaps();
347 				ball->returnInitialPos();
348 			}
349 			break;
350 	}
351 	//Reseteamos la variable de las chapas
352 	Cap::setAnyMoving();
353 	return finish;
354 }
355 
getCollision(Collision & c)356 void Stadium::getCollision(Collision &c)
357 {
358 	//Comprobamos que el que se esta moviendo sea del equipo del turno
359 	if(c.a->getTeam()!=s->getTeam())
360 		return;
361 
362 	if(c.b->getTeam()!=SG::NEUTRAL)
363 	{
364 		if(c.a->getTeam()!=c.b->getTeam())
365 		{
366 			if(state==MOVING)
367 			{
368 				cap_fault=(Cap*)c.a;
369 				changeTeam();
370 				state=FAULT;
371 			}
372 		}
373 	}
374 	//Si es neutral contra lo que ha chocado
375 	else
376 	{
377 		//Si es redondo es la pelota
378 		if(c.b->getType()==Actor::CIRCLE)
379 		{
380 			if(state==MOVING)
381 			{
382 				cap_pass=(Cap*)c.a;
383 				state=BALL;
384 				turn=theme->movements;
385 			}
386 		}
387 	}
388 }
389 
isAPass()390 Cap* Stadium::isAPass()
391 {
392 	Cap *near=NULL;
393 	float distance=1024.0;
394 	for(int i=0;i<theme->caps;i++)
395 	{
396 		Cap *c;
397 		if((c=teams[cap_pass->getTeam()].getCap(i))!=NULL)
398 		{
399 			Vector d=Vector(c->getPos()-ball->getPos());
400 			if(d.module()<distance && cap_pass!=c)
401 			{
402 				near=c;
403 				distance=d.module();
404 			}
405 		}
406 	}
407 	if(near!=NULL)
408 	{
409 		pass->setPos(near->getPos());
410 		g->actormanager->activate(pass);
411 		if(isCollision(pass,ball)!=NO_COLLISION)
412 			return near;
413 	}
414 	return NULL;
415 }
416