Aufzeichnung.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. #include "Aufzeichnung.h"
  2. #include <MausEreignis.h>
  3. #include <TastaturEreignis.h>
  4. // Inhalt der Aufzeichnung Klasse auf Aufzeichnung.h
  5. // Konstruktor
  6. Aufzeichnung::Aufzeichnung()
  7. {
  8. nMsg = 0;
  9. nMsgVorwärts = 0;
  10. schrift = 0;
  11. screen = 0;
  12. nachrichten = 0;
  13. bestenliste = 0;
  14. chat = 0;
  15. steuerung = 0;
  16. kam = 0;
  17. map = 0;
  18. ende = 0;
  19. spieler = new RCArray< VideoSpieler >();
  20. spielZeit = 0;
  21. rSpielZeit = new Array< double >();
  22. spielPause = 1;
  23. spielerAnzahl = 0;
  24. teamAnzahl = 0;
  25. kamSpielerNummer = -1;
  26. mx = -1;
  27. my = -1;
  28. geladen = 0;
  29. pauseZeit = -1;
  30. time = 0;
  31. ref = 1;
  32. }
  33. // Destruktor
  34. Aufzeichnung::~Aufzeichnung()
  35. {
  36. if( schrift )
  37. schrift->release();
  38. spieler->release();
  39. if( ende )
  40. ende->release();
  41. if( map )
  42. map->release();
  43. if( kam )
  44. kam->release();
  45. if( steuerung )
  46. steuerung->release();
  47. if( chat )
  48. chat->relese();
  49. if( bestenliste )
  50. bestenliste->release();
  51. if( nachrichten )
  52. nachrichten->release();
  53. rSpielZeit->release();
  54. }
  55. // nicht constant
  56. void Aufzeichnung::setSchrift( Schrift *schrift )
  57. {
  58. if( this->schrift )
  59. this->schrift->release();
  60. this->schrift = schrift;
  61. }
  62. void Aufzeichnung::setBildschirm( Bildschirm *zScreen )
  63. {
  64. screen = zScreen;
  65. }
  66. bool Aufzeichnung::ladeSpiel( int id )
  67. {
  68. nachrichten = new SpielNachricht( id );
  69. bestenliste = new VideoBestenliste( dynamic_cast<Schrift *>( schrift->getThis() ) );
  70. chat = new VideoChat( schrift );
  71. steuerung = new VideoSteuerung( schrift, screen );
  72. kam = new VideoKamera();
  73. map = new VideoKarte();
  74. ende = new VideoEnde( schrift );
  75. Text f;
  76. if( nachrichten->hatFehler( &f ) )
  77. {
  78. ende->setText( f );
  79. ende->setSichtbar( 1 );
  80. geladen = 1;
  81. return 1;
  82. }
  83. spielerAnzahl = nachrichten->getSVD()->spielerAnzahl;
  84. teamAnzahl = 0;
  85. for( int i = 0; i < spielerAnzahl; i++ )
  86. {
  87. SpielerVideoDaten *dat = nachrichten->getSPVD( i );
  88. if( !i )
  89. kam->setSize( dat->kamBreite, dat->kamHöhe );
  90. VideoSpieler *tmp = new VideoSpieler( dat );
  91. bestenliste->addSpieler( tmp );
  92. spieler->set( tmp, i );
  93. teamAnzahl = teamAnzahl < dat->team ? dat->team : teamAnzahl;
  94. }
  95. teamAnzahl++;
  96. bestenliste->setTeamAnzahl( teamAnzahl );
  97. for( int i = 0; i < nachrichten->getTeamAnzahl(); i++ )
  98. {
  99. TeamVideoDaten *dat = nachrichten->getTVD( i );
  100. bestenliste->setTeamMaxPunkte( dat->teamNummer, dat->maxPunkte );
  101. bestenliste->setTeamPunkte( dat->teamNummer, dat->punkte );
  102. }
  103. RundeVideoDaten *rDat = nachrichten->getRVD();
  104. map->setSize( rDat->mapBreite, rDat->mapHöhe );
  105. for( int i = 0; i < spielerAnzahl; i++ )
  106. {
  107. RundeSpielerVideoDaten *dat = nachrichten->getRSVD( i );
  108. spieler->z( i )->neuRunde( 1, dat, 1 );
  109. bestenliste->updateSpielerStatus( spieler->z( i ) );
  110. }
  111. pauseZeit = 3;
  112. ende->setText( "Die Aufzeichnung des Spiels wird geladen.\nRunde 1 beginnt in kürze." );
  113. ende->setSichtbar( 1 );
  114. geladen = 1;
  115. return 1;
  116. }
  117. void Aufzeichnung::doPublicMausEreignis( MausEreignis &me )
  118. {
  119. if( !geladen )
  120. return;
  121. if( kam->istMausIn( me.mx, me.my ) )
  122. {
  123. if( me.id == ME_PLinks )
  124. {
  125. for( int i = 0; i < spielerAnzahl; i++ )
  126. {
  127. if( spieler->z( i )->istMausIn( kam->getLinks() + me.mx - kam->getRX( kam->getLinks() ), kam->getOben() + me.my - kam->getRY( kam->getOben() ) ) )
  128. {
  129. kamSpielerNummer = spieler->z( i )->getSpielerNummer();
  130. me.verarbeitet = 1;
  131. break;
  132. }
  133. }
  134. }
  135. if( ( me.id == ME_RLinks || me.id == ME_RRechts ) && mx >= 0 )
  136. {
  137. mx = -1;
  138. my = -1;
  139. }
  140. if( me.id == ME_Bewegung && mx >= 0 )
  141. {
  142. kam->addPosition( mx - me.mx, my - me.my, map );
  143. mx = me.mx;
  144. my = me.my;
  145. }
  146. if( ( me.id == ME_PLinks || me.id == ME_PRechts ) && mx < 0 && !me.verarbeitet )
  147. {
  148. mx = me.mx;
  149. my = me.my;
  150. kamSpielerNummer = -1;
  151. }
  152. me.verarbeitet = 1;
  153. }
  154. else
  155. {
  156. mx = -1;
  157. my = -1;
  158. }
  159. bestenliste->doPublicMausEreignis( me );
  160. steuerung->doPublicMausEreignis( me );
  161. }
  162. void Aufzeichnung::doTastaturEreignis( TastaturEreignis &te )
  163. {
  164. if( !geladen )
  165. return;
  166. if( te.id == TE_Press )
  167. {
  168. switch( te.taste )
  169. {
  170. case T_Links:
  171. kam->addPosition( -2, 0, map );
  172. te.verarbeitet = 1;
  173. break;
  174. case T_Oben:
  175. kam->addPosition( 0, -2, map );
  176. te.verarbeitet = 1;
  177. break;
  178. case T_Rechts:
  179. kam->addPosition( 2, 0, map );
  180. te.verarbeitet = 1;
  181. break;
  182. case T_Unten:
  183. kam->addPosition( 0, 2, map );
  184. te.verarbeitet = 1;
  185. break;
  186. }
  187. if( te.verarbeitet )
  188. kamSpielerNummer = -1;
  189. }
  190. }
  191. bool Aufzeichnung::spielTick( double spielZeit )
  192. {
  193. this->spielZeit += spielZeit;
  194. bool setKam = kamSpielerNummer >= 0;
  195. int x = 0;
  196. int y = 0;
  197. bool rEnd = 0;
  198. for( int i = 0; i < spielerAnzahl; i++ )
  199. {
  200. VideoSpieler *tmp = spieler->z( i );
  201. if( tmp )
  202. {
  203. if( tmp->getSpielerNummer() == kamSpielerNummer )
  204. {
  205. x = (int)( tmp->getX() + 0.5 );
  206. y = (int)( tmp->getY() + 0.5 );
  207. }
  208. bool amLeben = tmp->istAmLeben();
  209. tmp->tick( map->zMap(), spielZeit );
  210. if( amLeben != tmp->istAmLeben() )
  211. {
  212. bestenliste->updateSpielerStatus( tmp );
  213. for( int j = 0; j < spielerAnzahl; j++ )
  214. {
  215. VideoSpieler *s = spieler->z( j );
  216. if( s && s != tmp && s->istAmLeben() )
  217. bestenliste->addPunkt( s->getTeam(), s->getSpielerNummer(), spielZeit > 0 );
  218. }
  219. }
  220. if( amLeben && !tmp->istAmLeben() )
  221. { // gestorben
  222. int team = tmp->getTeam();
  223. bool teamLebt = 0;
  224. for( int k = 0; k < spielerAnzahl; k++ )
  225. {
  226. if( spieler->z( k ) && spieler->z( k )->getTeam() == team )
  227. teamLebt |= spieler->z( k )->istAmLeben();
  228. }
  229. if( !teamLebt )
  230. {
  231. int teamAmLebenAnzahl = 0;
  232. for( int k = 0; k < teamAnzahl; k++ )
  233. {
  234. if( !bestenliste->teamExistiert( k ) )
  235. continue;
  236. bool amLeben = 0;
  237. for( int l = 0; l < spielerAnzahl; l++ )
  238. {
  239. if( spieler->z( l ) && spieler->z( l )->getTeam() == k )
  240. amLeben |= spieler->z( l )->istAmLeben();
  241. }
  242. if( amLeben )
  243. {
  244. teamAmLebenAnzahl++;
  245. bestenliste->addPunkt( k, 1 );
  246. }
  247. else
  248. bestenliste->addPunkt( k, 0 );
  249. if( !bestenliste->getTeamPunkte( k ) )
  250. bestenliste->setTeamStatus( k, "tod", 0xFFFF0000 );
  251. }
  252. if( teamAmLebenAnzahl <= 1 )
  253. rEnd = 1;
  254. }
  255. }
  256. if( !amLeben && tmp->istAmLeben() )
  257. { // Wiederbelebt
  258. int team = tmp->getTeam();
  259. bool teamLebt = 0;
  260. for( int k = 0; k < spielerAnzahl; k++ )
  261. {
  262. if( k != i && spieler->z( k ) && spieler->z( k )->getTeam() == team )
  263. teamLebt |= spieler->z( k )->istAmLeben();
  264. }
  265. if( !teamLebt )
  266. {
  267. for( int k = 0; k < teamAnzahl; k++ )
  268. {
  269. if( !bestenliste->teamExistiert( k ) )
  270. continue;
  271. bool amLeben = 0;
  272. for( int l = 0; l < spielerAnzahl; l++ )
  273. {
  274. if( l != i && spieler->z( l ) && spieler->z( l )->getTeam() == k )
  275. amLeben |= spieler->z( l )->istAmLeben();
  276. }
  277. if( amLeben )
  278. bestenliste->addPunkt( k, 0 );
  279. else
  280. bestenliste->addPunkt( k, 1 );
  281. if( bestenliste->getTeamPunkte( k ) )
  282. bestenliste->setTeamStatus( k, "lebt", 0xFF00FF00 );
  283. }
  284. }
  285. }
  286. }
  287. }
  288. if( setKam )
  289. {
  290. double z = spielZeit < 0 ? -spielZeit : spielZeit;
  291. double px = ( ( x - kam->getX() ) / 100.0 ) * ( 50 * z );
  292. double py = ( ( y - kam->getY() ) / 100.0 ) * ( 50 * z );
  293. kam->addPosition( (int)px, (int)py, map );
  294. }
  295. chat->tick( spielZeit );
  296. steuerung->tick( spielZeit );
  297. if( rEnd && spielZeit > 0 )
  298. { // Runden Ende
  299. int nAnz = 0;
  300. int nAnz2 = 0;
  301. for( int i = 0; i < teamAnzahl; i++ )
  302. {
  303. if( bestenliste->teamExistiert( i ) )
  304. {
  305. nAnz += bestenliste->hatTeamGewonnen( i );
  306. nAnz2 += bestenliste->getTeamPunkte( i ) >= 0;
  307. }
  308. }
  309. if( nAnz || nAnz2 <= 1 || nachrichten->getRunde() >= 9 )
  310. { // Spiel Ende
  311. steuerung->pause( 1 );
  312. return 1;
  313. }
  314. spielPause = 1;
  315. pauseZeit = 2;
  316. ende->setText( "Die nächste Runde beginnt in kürze." );
  317. ende->setSichtbar( 1 );
  318. int r = nachrichten->setRundenEnde( 1 );
  319. rSpielZeit->set( spielZeit, r - 1 );
  320. this->spielZeit = 0;
  321. time = 0;
  322. bestenliste->updatePunkte();
  323. kam->nextRunde( 1 );
  324. map->nextRunde( 1 );
  325. RundeVideoDaten *dat = nachrichten->getRVD();
  326. map->setSize( dat->mapBreite, dat->mapHöhe );
  327. for( int i = 0; i < spielerAnzahl; i++ )
  328. {
  329. spieler->z( i )->neuRunde( 1, nachrichten->getRSVD( i ), bestenliste->getTeamPunkte( spieler->z( i )->getTeam() ) != 0 );
  330. bestenliste->updateSpielerStatus( spieler->z( i ) );
  331. }
  332. return 1;
  333. }
  334. return 0;
  335. }
  336. bool Aufzeichnung::tick( double tickVal )
  337. {
  338. if( !geladen )
  339. return 0;
  340. if( spielPause )
  341. {
  342. if( pauseZeit >= 0 )
  343. {
  344. pauseZeit -= tickVal;
  345. if( pauseZeit < 0 )
  346. {
  347. pauseZeit = 0;
  348. spielPause = 0;
  349. ende->setSichtbar( 0 );
  350. }
  351. }
  352. chat->tick( 0 );
  353. steuerung->tick( 0 );
  354. return 1;
  355. }
  356. if( ( steuerung->istVorwärts() || nMsg && nMsgVorwärts ) && !( nMsg && !nMsgVorwärts ) )
  357. {
  358. if( steuerung->istZeitlupe() )
  359. time += tickVal / steuerung->getSpeed();
  360. else
  361. time += tickVal * steuerung->getSpeed();
  362. while( steuerung->getSpeed() != 0 )
  363. {
  364. while( !nMsg || nMsg->typ && steuerung->getSpeed() != 0 )
  365. {
  366. if( !nMsg )
  367. nMsg = nachrichten->GetNextNachricht();
  368. if( !nMsg )
  369. break;
  370. nMsgVorwärts = 1;
  371. if( !nMsg->typ )
  372. break;
  373. VideoAktionMSG *ak = (VideoAktionMSG *)nMsg;
  374. switch( ak->aktion )
  375. {
  376. case 0: // T_Links Press
  377. for( int i = 0; i < spielerAnzahl; i++ )
  378. {
  379. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  380. {
  381. spieler->z( i )->setLinksKurve( 1 );
  382. break;
  383. }
  384. }
  385. break;
  386. case 1: // T_Links Release
  387. for( int i = 0; i < spielerAnzahl; i++ )
  388. {
  389. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  390. {
  391. spieler->z( i )->setLinksKurve( 0 );
  392. break;
  393. }
  394. }
  395. break;
  396. case 2: // T_Rechts Press
  397. for( int i = 0; i < spielerAnzahl; i++ )
  398. {
  399. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  400. {
  401. spieler->z( i )->setRechtsKurve( 1 );
  402. break;
  403. }
  404. }
  405. break;
  406. case 3: // T_Rechts Release
  407. for( int i = 0; i < spielerAnzahl; i++ )
  408. {
  409. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  410. {
  411. spieler->z( i )->setRechtsKurve( 0 );
  412. break;
  413. }
  414. }
  415. break;
  416. case 4: // Chat Nachricht
  417. if( 1 )
  418. {
  419. VideoChatMSG *msg = (VideoChatMSG *)ak;
  420. for( int i = 0; i < spielerAnzahl; i++ )
  421. {
  422. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  423. {
  424. Text txt = spieler->z( i )->zName()->getText();
  425. txt += ": ";
  426. txt += msg->msg.getText();
  427. chat->addNachricht( txt );
  428. break;
  429. }
  430. }
  431. }
  432. break;
  433. case 5: // Linien Unterbrechung
  434. if( 1 )
  435. {
  436. VideoLinieMSG *lMsg = (VideoLinieMSG *)ak;
  437. for( int i = 0; i < spielerAnzahl; i++ )
  438. {
  439. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  440. {
  441. spieler->z( i )->setLinienUnterbrechung( lMsg->unterbrechung != 0 );
  442. break;
  443. }
  444. }
  445. }
  446. break;
  447. }
  448. nMsg = 0;
  449. }
  450. if( !nMsg )
  451. break;
  452. if( time > spielZeit + TICK )
  453. {
  454. bool end = spielTick( TICK );
  455. nMsg = 0;
  456. if( !steuerung->istVorwärts() || end )
  457. break;
  458. }
  459. else
  460. break;
  461. }
  462. }
  463. else
  464. {
  465. if( steuerung->istZeitlupe() )
  466. time -= tickVal / steuerung->getSpeed();
  467. else
  468. time -= tickVal * steuerung->getSpeed();
  469. while( 1 )
  470. {
  471. while( !nMsg || nMsg->typ )
  472. {
  473. if( !nMsg )
  474. {
  475. nMsg = nachrichten->GetLastNachricht();
  476. nMsgVorwärts = 0;
  477. if( !nMsg )
  478. {
  479. int r = nachrichten->setRundenEnde( 0 );
  480. if( r < 0 )
  481. { // Spiel Beginn
  482. steuerung->pause( 0 );
  483. return 1;
  484. }
  485. bestenliste->updatePunkte( 0 );
  486. kam->nextRunde( 0 );
  487. map->nextRunde( 0 );
  488. for( int i = 0; i < spielerAnzahl; i++ )
  489. spieler->z( i )->neuRunde( 0, 0, 1 );
  490. spielPause = 1;
  491. pauseZeit = 2;
  492. ende->setText( "Vorherige Runde beginnt in kürze." );
  493. ende->setSichtbar( 1 );
  494. spielZeit = rSpielZeit->get( r );
  495. time = spielZeit;
  496. return 1;
  497. }
  498. }
  499. if( !nMsg->typ )
  500. break;
  501. VideoAktionMSG *ak = (VideoAktionMSG *)nMsg;
  502. switch( ak->aktion )
  503. {
  504. case 0: // T_Links Press
  505. for( int i = 0; i < spielerAnzahl; i++ )
  506. {
  507. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  508. {
  509. spieler->z( i )->setLinksKurve( 0 );
  510. break;
  511. }
  512. }
  513. break;
  514. case 1: // T_Links Release
  515. for( int i = 0; i < spielerAnzahl; i++ )
  516. {
  517. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  518. {
  519. spieler->z( i )->setLinksKurve( 1 );
  520. break;
  521. }
  522. }
  523. break;
  524. case 2: // T_Rechts Press
  525. for( int i = 0; i < spielerAnzahl; i++ )
  526. {
  527. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  528. {
  529. spieler->z( i )->setRechtsKurve( 0 );
  530. break;
  531. }
  532. }
  533. break;
  534. case 3: // T_Rechts Release
  535. for( int i = 0; i < spielerAnzahl; i++ )
  536. {
  537. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  538. {
  539. spieler->z( i )->setRechtsKurve( 1 );
  540. break;
  541. }
  542. }
  543. break;
  544. case 4: // Chat Nachricht
  545. if( 1 )
  546. {
  547. VideoChatMSG *msg = (VideoChatMSG *)ak;
  548. for( int i = 0; i < spielerAnzahl; i++ )
  549. {
  550. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  551. {
  552. Text txt = spieler->z( i )->zName()->getText();
  553. txt += ": ";
  554. txt += msg->msg.getText();
  555. chat->removeNachricht( txt );
  556. break;
  557. }
  558. }
  559. }
  560. break;
  561. case 5: // Linien Unterbrechung
  562. if( 1 )
  563. {
  564. VideoLinieMSG *lMsg = (VideoLinieMSG *)ak;
  565. if( 1 )
  566. {
  567. for( int i = 0; i < spielerAnzahl; i++ )
  568. {
  569. if( spieler->z( i )->getSpielerNummer() == ak->spielerNummer )
  570. {
  571. spieler->z( i )->setLinienUnterbrechung( lMsg->unterbrechung == 0 );
  572. break;
  573. }
  574. }
  575. }
  576. }
  577. break;
  578. }
  579. nMsg = 0;
  580. }
  581. if( time <= spielZeit - TICK )
  582. {
  583. spielTick( -TICK );
  584. nMsg = 0;
  585. if( steuerung->istVorwärts() )
  586. break;
  587. }
  588. else
  589. break;
  590. }
  591. }
  592. return 1;
  593. }
  594. void Aufzeichnung::render( Bild &zRObj )
  595. {
  596. if( !geladen )
  597. return;
  598. bestenliste->render( zRObj );
  599. chat->render( zRObj );
  600. steuerung->render( zRObj );
  601. kam->render( zRObj );
  602. int x = kam->getRX( kam->getLinks() ) + 1, y = kam->getRY( kam->getOben() ) + 1;
  603. if( zRObj.setDrawOptions( x, y, kam->getRechts() - kam->getLinks() - 2, kam->getUnten() - kam->getOben() - 2 ) )
  604. {
  605. zRObj.addScrollOffset( x, y );
  606. map->render( kam, zRObj );
  607. for( int i = 0; i < spielerAnzahl; i++ )
  608. spieler->z( i )->render( kam, zRObj );
  609. zRObj.releaseDrawOptions();
  610. }
  611. if( ende )
  612. ende->render( zRObj );
  613. }
  614. // constant
  615. bool Aufzeichnung::hatVerlassen( bool jetzt ) const
  616. {
  617. if( !geladen )
  618. return 0;
  619. return steuerung->istBeendet( jetzt );
  620. }
  621. // Reference Counting
  622. AufzeichnungV *Aufzeichnung::getThis()
  623. {
  624. ref++;
  625. return this;
  626. }
  627. AufzeichnungV *Aufzeichnung::release()
  628. {
  629. ref--;
  630. if( !ref )
  631. delete this;
  632. return 0;
  633. }