SpielKlasse.cpp 34 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171
  1. #include "SpielKlasse.h"
  2. #include <time.h>
  3. #include <Schrift.h>
  4. #include <MausEreignis.h>
  5. #include <TastaturEreignis.h>
  6. #include <M2Datei.h>
  7. #include <DateiSystem.h>
  8. #include "SpielerGUI/SpielerGUI.h"
  9. #include "Define.h"
  10. #include <Animation.h>
  11. // Inhalt der SpielKlasse Klasse aus SpielKlasse.h
  12. // Konstruktor
  13. SpielKlasse::SpielKlasse()
  14. {
  15. spielZeit = -1;
  16. rZeit = 0;
  17. rendern = 0;
  18. stkn = new RCArray< STKNachricht >();
  19. stkna = 0;
  20. schrift = 0;
  21. time_t t;
  22. time( &t );
  23. srand( (unsigned int)t );
  24. infoKlient = 0;
  25. spielKlient = 0;
  26. spieler = new RCArray< Spieler >();
  27. teams = new RCArray< Team >();
  28. objekte = new RCArray< SpielObjekt >();
  29. deads = new RCArray< DeadPlayer >();
  30. screen = 0;
  31. welt = new Welt2D();
  32. welt->setCircular( 1 );
  33. welt->setAirResistance( 0.001f );
  34. kam = new Kamera2D();
  35. kam->setWelt( welt->getThis(), 1 );
  36. minimap = new Kamera2D();
  37. minimap->setSize( 200, 200 );
  38. minimap->setWelt( welt->getThis(), 0 );
  39. minimap->setStyle( ZeichnungHintergrund::Style::Sichtbar | ZeichnungHintergrund::Style::Rahmen );
  40. minimap->setLinienRahmenFarbe( 0xFFFFFFFF );
  41. minimap->setName( "minimap" );
  42. spielerAnzahl = 0;
  43. karteId = 0;
  44. ladenProzent = 0;
  45. spielerNummer = 0;
  46. map = 0;
  47. end = 0;
  48. chat = new SpielChat();
  49. tasten = new char[ 256 ];
  50. for( int i = 0; i < 256; i++ )
  51. tasten[ i ] = 0;
  52. bestenliste = 0;
  53. schüsse = new RCArray< Laser >();
  54. shipGUI = 0;
  55. spielPause = 1;
  56. ref = 1;
  57. save();
  58. }
  59. // Destruktor
  60. SpielKlasse::~SpielKlasse()
  61. {
  62. for( int i = 0; i < map->getMaxTeamAnzahl(); i++ )
  63. {
  64. if( teams->z( i ) )
  65. teams->z( i )->reset();
  66. }
  67. map->release();
  68. minimap->release();
  69. welt->release();
  70. deads->release();
  71. stkn->release();
  72. if( schrift )
  73. schrift->release();
  74. if( infoKlient )
  75. infoKlient->release();
  76. if( spielKlient )
  77. spielKlient->release();
  78. if( kam )
  79. kam->release();
  80. if( end )
  81. end->release();
  82. if( bestenliste )
  83. bestenliste->release();
  84. if( shipGUI )
  85. shipGUI->release();
  86. chat->relese();
  87. spieler->release();
  88. teams->release();
  89. objekte->release();
  90. if( screen )
  91. screen->release();
  92. schüsse->release();
  93. delete[] tasten;
  94. }
  95. // privat
  96. bool SpielKlasse::istAmLeben() const
  97. {
  98. for( int i = 0; i < spielerAnzahl; i++ )
  99. {
  100. if( spieler->z( i )->getSpielerNummer() == spielerNummer )
  101. return spieler->z( i )->istAmLeben();
  102. }
  103. return 0;
  104. }
  105. void SpielKlasse::goBackInTime( int zeit )
  106. {
  107. if( zeit < last.spielZeit )
  108. chat->addNachricht( "Fehler: Es wurde versucht das Spiel auf einen Zeitpunkt zurückzusetzen, welcher nicht mehr erreicht werden kann.", 0xFFFF0000 );
  109. load();
  110. while( spielZeit < zeit )
  111. tick();
  112. }
  113. void SpielKlasse::goToPresence( int zeit )
  114. {
  115. save();
  116. while( spielZeit < zeit )
  117. tick();
  118. }
  119. void SpielKlasse::load()
  120. {
  121. spielZeit = last.spielZeit;
  122. for( auto i = spieler->getIterator(); i; i++ )
  123. i->load();
  124. for( auto i = schüsse->getIterator(); i; i++ )
  125. i->load();
  126. }
  127. void SpielKlasse::save()
  128. {
  129. last.spielZeit = spielZeit;
  130. for( auto i = spieler->getIterator(); i; i++ )
  131. i->save();
  132. for( auto i = schüsse->getIterator(); i; i++ )
  133. i->save();
  134. }
  135. void SpielKlasse::tick()
  136. {
  137. spielZeit++;
  138. kam->tick( TICK );
  139. }
  140. // nicht constant
  141. void SpielKlasse::lock()
  142. {
  143. if( screen )
  144. screen->lock();
  145. }
  146. void SpielKlasse::unlock()
  147. {
  148. if( screen )
  149. screen->unlock();
  150. }
  151. void SpielKlasse::setSchrift( Schrift *schrift )
  152. {
  153. if( this->schrift )
  154. this->schrift->release();
  155. this->schrift = schrift;
  156. chat->setSchrift( schrift );
  157. if( !bestenliste )
  158. bestenliste = new Bestenliste( schrift->getThis() );
  159. if( !shipGUI )
  160. shipGUI = new SpielerGUI( schrift );
  161. }
  162. void SpielKlasse::setBildschirm( Bildschirm *screen )
  163. {
  164. this->screen = screen;
  165. }
  166. void SpielKlasse::nachricht( int län, char *bytes )
  167. {
  168. if( !län )
  169. return;
  170. lock();
  171. stkn->add( new STKNachricht( län, bytes ), stkna );
  172. stkna++;
  173. unlock();
  174. }
  175. void SpielKlasse::setKlients( KSGClient::InformationServerClient *infoKlient, KSGClient::SpielServerClient *spielKlient )
  176. {
  177. if( this->infoKlient )
  178. this->infoKlient->release();
  179. this->infoKlient = infoKlient;
  180. if( this->spielKlient )
  181. this->spielKlient->release();
  182. this->spielKlient = spielKlient;
  183. }
  184. void SpielKlasse::setKarteId( int karteId )
  185. {
  186. this->karteId = karteId;
  187. }
  188. void SpielKlasse::ladeDaten()
  189. {
  190. Text path = "data/log/0.csv";
  191. for( int i = 1; DateiExistiert( path ); i++ )
  192. {
  193. path = "data/log/";
  194. path += i;
  195. path += ".csv";
  196. }
  197. csv.setDatei( path );
  198. csv.erstellen();
  199. csv.open( Datei::Style::schreiben );
  200. csv.schreibe( "Spielernummer;Skill ID\n", 23 );
  201. // load frame annimation
  202. Text *gamePath = infoKlient->getDateiGruppePfad( infoKlient->getDateiGruppeIdVonSpiel( infoKlient->getSpielId( karteId ) ) );
  203. LTDBDatei flammenStartLTDB;
  204. Text *f_start = new Text( gamePath->getText() );
  205. f_start->append( "/bilder/f_start.ltdb" );
  206. flammenStartLTDB.setDatei( f_start );
  207. flammenStartLTDB.leseDaten( 0 );
  208. Animation2DData *flammenStart = new Animation2DData();
  209. flammenStart->ladeAnimation( flammenStartLTDB.getThis() );
  210. flammenStart->setFPS( 75 );
  211. flammenStart->setWiederhohlend( 0 );
  212. spielKlient->setLadenProzent( 7 );
  213. LTDBDatei flammenLTDB;
  214. Text *f_burn = new Text( gamePath->getText() );
  215. f_burn->append( "/bilder/f_burn.ltdb" );
  216. flammenLTDB.setDatei( f_burn );
  217. Animation2DData *flammenBurn = new Animation2DData();
  218. flammenBurn->ladeAnimation( flammenLTDB.getThis() );
  219. flammenBurn->setFPS( 60 );
  220. flammenBurn->setWiederhohlend( 1 );
  221. map = new Karte();
  222. Text *mapPf = new Text( "data/tmp/Karten/" );
  223. mapPf->append( karteId );
  224. mapPf->append( "/spiel/data/data.sts" );
  225. Datei *stsD = new Datei();
  226. stsD->setDatei( mapPf->getText() );
  227. stsD->open( Datei::Style::lesen );
  228. map->ladeSts( stsD );
  229. stsD->close();
  230. stsD->release();
  231. spielKlient->setLadenProzent( 15 );
  232. mapPf->ersetzen( mapPf->getLength() - 3, mapPf->getLength(), "map" );
  233. Datei *mapD = new Datei();
  234. mapD->setDatei( mapPf->getText() );
  235. mapD->open( Datei::Style::lesen );
  236. map->ladeMap( mapD, karteId, spielKlient, gamePath );
  237. mapD->close();
  238. mapD->release();
  239. mapPf->release();
  240. for( int i = 0; i < map->getMaxSpielerAnzahl(); i++ )
  241. {
  242. Spieler *s = map->createSpieler( i, schrift, infoKlient, flammenStart, flammenBurn );
  243. spieler->set( s, i );
  244. }
  245. flammenStart->release();
  246. flammenBurn->release();
  247. spielKlient->setLadenProzent( 95 );
  248. for( int i = 0; i < map->getZeichnungAnzahl(); i++ )
  249. {
  250. SpielObjekt *obj = map->createObjekt( i, schrift );
  251. welt->addObject( obj->getThis() );
  252. objekte->set( obj, i );
  253. }
  254. bestenliste->setTeamAnzahl( map->getMaxTeamAnzahl() );
  255. welt->setSize( map->getSize().x, map->getSize().y );
  256. welt->setSize( 1 );
  257. spielKlient->setLadenProzent( 100 );
  258. }
  259. void SpielKlasse::doMausEreignis( MausEreignis &me )
  260. {
  261. if( end )
  262. {
  263. end->doMausEreignis( me );
  264. return;
  265. }
  266. if( !istAmLeben() )
  267. me.verarbeitet = 1;
  268. int skill = shipGUI->doMausEreignis( me );
  269. if( skill >= 0 )
  270. {
  271. char *bytes = new char[ 2 ];
  272. bytes[ 0 ] = 9;
  273. bytes[ 1 ] = (char)skill;
  274. spielKlient->spielNachricht( 2, bytes );
  275. }
  276. chat->doMausEreignis( me );
  277. if( bestenliste )
  278. bestenliste->doMausEreignis( me );
  279. }
  280. void SpielKlasse::doTastaturEreignis( TastaturEreignis &te )
  281. {
  282. bestenliste->doTastaturEreignis( te );
  283. if( end )
  284. {
  285. end->doTastaturEreignis( te );
  286. return;
  287. }
  288. if( !chat->istAktiv() )
  289. {
  290. if( istAmLeben() )
  291. {
  292. if( te.id == TE_Press )
  293. {
  294. switch( te.taste )
  295. {
  296. case 'w':
  297. case 'W':
  298. case T_Oben:
  299. if( !tasten[ T_Oben ] )
  300. {
  301. tasten[ T_Oben ] = 1;
  302. char byte = 0;
  303. spielKlient->spielNachricht( 1, &byte );
  304. te.verarbeitet = 1;
  305. }
  306. break;
  307. case 'a':
  308. case 'A':
  309. case T_Links:
  310. if( !tasten[ T_Links ] )
  311. {
  312. tasten[ T_Links ] = 1;
  313. char byte = 2;
  314. spielKlient->spielNachricht( 1, &byte );
  315. te.verarbeitet = 1;
  316. }
  317. break;
  318. case 'd':
  319. case 'D':
  320. case T_Rechts:
  321. if( !tasten[ T_Rechts ] )
  322. {
  323. tasten[ T_Rechts ] = 1;
  324. char byte = 4;
  325. spielKlient->spielNachricht( 1, &byte );
  326. te.verarbeitet = 1;
  327. }
  328. break;
  329. case T_Space:
  330. if( !tasten[ T_Space ] )
  331. {
  332. tasten[ T_Space ] = 1;
  333. char byte = 6;
  334. spielKlient->spielNachricht( 1, &byte );
  335. te.verarbeitet = 1;
  336. }
  337. break;
  338. }
  339. }
  340. if( te.id == TE_Release )
  341. {
  342. switch( te.taste )
  343. {
  344. case 'w':
  345. case 'W':
  346. case T_Oben:
  347. if( tasten[ T_Oben ] )
  348. {
  349. tasten[ T_Oben ] = 0;
  350. char byte = 1;
  351. spielKlient->spielNachricht( 1, &byte );
  352. te.verarbeitet = 1;
  353. }
  354. break;
  355. case 'a':
  356. case 'A':
  357. case T_Links:
  358. if( tasten[ T_Links ] )
  359. {
  360. tasten[ T_Links ] = 0;
  361. char byte = 3;
  362. spielKlient->spielNachricht( 1, &byte );
  363. te.verarbeitet = 1;
  364. }
  365. break;
  366. case 'd':
  367. case 'D':
  368. case T_Rechts:
  369. if( tasten[ T_Rechts ] )
  370. {
  371. tasten[ T_Rechts ] = 0;
  372. char byte = 5;
  373. spielKlient->spielNachricht( 1, &byte );
  374. te.verarbeitet = 1;
  375. }
  376. break;
  377. case T_Space:
  378. if( tasten[ T_Space ] )
  379. {
  380. tasten[ T_Space ] = 0;
  381. char byte = 7;
  382. spielKlient->spielNachricht( 1, &byte );
  383. te.verarbeitet = 1;
  384. }
  385. break;
  386. }
  387. }
  388. }
  389. else
  390. {
  391. if( te.id == TE_Press )
  392. {
  393. switch( te.taste )
  394. {
  395. case T_Links:
  396. kam->setPosition( kam->getPosition() + Vertex( -2, 0 ) );
  397. te.verarbeitet = 1;
  398. break;
  399. case T_Oben:
  400. kam->setPosition( kam->getPosition() + Vertex( 0, -2 ) );
  401. te.verarbeitet = 1;
  402. break;
  403. case T_Rechts:
  404. kam->setPosition( kam->getPosition() + Vertex( 2, 0 ) );
  405. te.verarbeitet = 1;
  406. break;
  407. case T_Unten:
  408. kam->setPosition( kam->getPosition() + Vertex( 0, 2 ) );
  409. te.verarbeitet = 1;
  410. break;
  411. }
  412. }
  413. }
  414. }
  415. if( !te.verarbeitet )
  416. chat->doTastaturEreignis( te, spielKlient );
  417. }
  418. void SpielKlasse::stknVerarbeitung()
  419. {
  420. lock();
  421. for( int i = 0; i < stkna; i++ )
  422. {
  423. STKNachricht *n = stkn->z( i );
  424. int zeit = n->getSpielZeit();
  425. while( zeit > spielZeit )
  426. tick();
  427. int län = n->getLength();
  428. char *bytes = n->getNachricht();
  429. län--;
  430. int sNum = 0;
  431. int presence = spielZeit;
  432. Vertex pos;
  433. Vertex speed;
  434. float rot;
  435. float rotS;
  436. if( presence > zeit + 10 )
  437. presence = zeit + 10; // maximale zeitdifferenz von client und server
  438. switch( bytes[ 0 ] )
  439. {
  440. case 0: // spieler drückt gas
  441. bytes++;
  442. sNum = *(int*)bytes;
  443. bytes += 4;
  444. län -= 4;
  445. pos.x = *(float*)bytes;
  446. bytes += 4;
  447. län -= 4;
  448. pos.y = *(float*)bytes;
  449. bytes += 4;
  450. län -= 4;
  451. speed.x = *(float*)bytes;
  452. bytes += 4;
  453. län -= 4;
  454. speed.y = *(float*)bytes;
  455. bytes += 4;
  456. län -= 4;
  457. rot = *(float*)bytes;
  458. bytes += 4;
  459. län -= 4;
  460. rotS = *(float*)bytes;
  461. län -= 4;
  462. goBackInTime( zeit );
  463. for( auto i = spieler->getIterator(); i; i++ )
  464. {
  465. if( i->getSpielerNummer() == sNum )
  466. {
  467. if( i->getPosition() != pos )
  468. chat->addNachricht( Text( "asynchrony detected, position difference: " ) += ( i->getPosition() - pos ).getLength(), 0xFFFF0000 );
  469. if( i->getSpeed() != speed )
  470. chat->addNachricht( Text( "asynchrony detected, speed difference: " ) += ( i->getSpeed() - speed ).getLength(), 0xFFFF0000 );
  471. if( i->getDrehung() != rot )
  472. chat->addNachricht( Text( "asynchrony detected, rot difference: " ) += ( i->getDrehung() - rot ), 0xFFFF0000 );
  473. if( i->getDrehungSpeed() != rotS )
  474. chat->addNachricht( Text( "asynchrony detected, rotS difference: " ) += ( i->getDrehungSpeed() - rotS ), 0xFFFF0000 );
  475. i->setTastataturStatus( T_GAS, 1 );
  476. }
  477. }
  478. goToPresence( presence );
  479. break;
  480. case 1: // spieler lässt gas los
  481. bytes++;
  482. sNum = *(int*)bytes;
  483. bytes += 4;
  484. län -= 4;
  485. pos.x = *(float*)bytes;
  486. bytes += 4;
  487. län -= 4;
  488. pos.y = *(float*)bytes;
  489. bytes += 4;
  490. län -= 4;
  491. speed.x = *(float*)bytes;
  492. bytes += 4;
  493. län -= 4;
  494. speed.y = *(float*)bytes;
  495. bytes += 4;
  496. län -= 4;
  497. rot = *(float*)bytes;
  498. bytes += 4;
  499. län -= 4;
  500. rotS = *(float*)bytes;
  501. län -= 4;
  502. goBackInTime( zeit );
  503. for( auto i = spieler->getIterator(); i; i++ )
  504. {
  505. if( i->getSpielerNummer() == sNum )
  506. {
  507. if( i->getPosition() != pos )
  508. chat->addNachricht( Text( "asynchrony detected, position difference: " ) += ( i->getPosition() - pos ).getLength(), 0xFFFF0000 );
  509. if( i->getSpeed() != speed )
  510. chat->addNachricht( Text( "asynchrony detected, speed difference: " ) += ( i->getSpeed() - speed ).getLength(), 0xFFFF0000 );
  511. if( i->getDrehung() != rot )
  512. chat->addNachricht( Text( "asynchrony detected, rot difference: " ) += ( i->getDrehung() - rot ), 0xFFFF0000 );
  513. if( i->getDrehungSpeed() != rotS )
  514. chat->addNachricht( Text( "asynchrony detected, rotS difference: " ) += ( i->getDrehungSpeed() - rotS ), 0xFFFF0000 );
  515. i->setTastataturStatus( T_GAS, 0 );
  516. }
  517. }
  518. goToPresence( presence );
  519. break;
  520. case 2: // spieler drückt rotl
  521. bytes++;
  522. sNum = *(int*)bytes;
  523. bytes += 4;
  524. län -= 4;
  525. pos.x = *(float*)bytes;
  526. bytes += 4;
  527. län -= 4;
  528. pos.y = *(float*)bytes;
  529. bytes += 4;
  530. län -= 4;
  531. speed.x = *(float*)bytes;
  532. bytes += 4;
  533. län -= 4;
  534. speed.y = *(float*)bytes;
  535. bytes += 4;
  536. län -= 4;
  537. rot = *(float*)bytes;
  538. bytes += 4;
  539. län -= 4;
  540. rotS = *(float*)bytes;
  541. län -= 4;
  542. goBackInTime( zeit );
  543. for( auto i = spieler->getIterator(); i; i++ )
  544. {
  545. if( i->getSpielerNummer() == sNum )
  546. {
  547. if( i->getPosition() != pos )
  548. chat->addNachricht( Text( "asynchrony detected, position difference: " ) += ( i->getPosition() - pos ).getLength(), 0xFFFF0000 );
  549. if( i->getSpeed() != speed )
  550. chat->addNachricht( Text( "asynchrony detected, speed difference: " ) += ( i->getSpeed() - speed ).getLength(), 0xFFFF0000 );
  551. if( i->getDrehung() != rot )
  552. chat->addNachricht( Text( "asynchrony detected, rot difference: " ) += ( i->getDrehung() - rot ), 0xFFFF0000 );
  553. if( i->getDrehungSpeed() != rotS )
  554. chat->addNachricht( Text( "asynchrony detected, rotS difference: " ) += ( i->getDrehungSpeed() - rotS ), 0xFFFF0000 );
  555. i->setTastataturStatus( T_ROT_L, 1 );
  556. }
  557. }
  558. goToPresence( presence );
  559. break;
  560. case 3: // spieler lässt rotl los
  561. bytes++;
  562. sNum = *(int*)bytes;
  563. bytes += 4;
  564. län -= 4;
  565. pos.x = *(float*)bytes;
  566. bytes += 4;
  567. län -= 4;
  568. pos.y = *(float*)bytes;
  569. bytes += 4;
  570. län -= 4;
  571. speed.x = *(float*)bytes;
  572. bytes += 4;
  573. län -= 4;
  574. speed.y = *(float*)bytes;
  575. bytes += 4;
  576. län -= 4;
  577. rot = *(float*)bytes;
  578. bytes += 4;
  579. län -= 4;
  580. rotS = *(float*)bytes;
  581. län -= 4;
  582. goBackInTime( zeit );
  583. for( auto i = spieler->getIterator(); i; i++ )
  584. {
  585. if( i->getSpielerNummer() == sNum )
  586. {
  587. if( i->getPosition() != pos )
  588. chat->addNachricht( Text( "asynchrony detected, position difference: " ) += ( i->getPosition() - pos ).getLength(), 0xFFFF0000 );
  589. if( i->getSpeed() != speed )
  590. chat->addNachricht( Text( "asynchrony detected, speed difference: " ) += ( i->getSpeed() - speed ).getLength(), 0xFFFF0000 );
  591. if( i->getDrehung() != rot )
  592. chat->addNachricht( Text( "asynchrony detected, rot difference: " ) += ( i->getDrehung() - rot ), 0xFFFF0000 );
  593. if( i->getDrehungSpeed() != rotS )
  594. chat->addNachricht( Text( "asynchrony detected, rotS difference: " ) += ( i->getDrehungSpeed() - rotS ), 0xFFFF0000 );
  595. i->setTastataturStatus( T_ROT_L, 0 );
  596. }
  597. }
  598. goToPresence( presence );
  599. break;
  600. case 4: // spieler drückt rotr
  601. bytes++;
  602. sNum = *(int*)bytes;
  603. bytes += 4;
  604. län -= 4;
  605. pos.x = *(float*)bytes;
  606. bytes += 4;
  607. län -= 4;
  608. pos.y = *(float*)bytes;
  609. bytes += 4;
  610. län -= 4;
  611. speed.x = *(float*)bytes;
  612. bytes += 4;
  613. län -= 4;
  614. speed.y = *(float*)bytes;
  615. bytes += 4;
  616. län -= 4;
  617. rot = *(float*)bytes;
  618. bytes += 4;
  619. län -= 4;
  620. rotS = *(float*)bytes;
  621. län -= 4;
  622. goBackInTime( zeit );
  623. for( auto i = spieler->getIterator(); i; i++ )
  624. {
  625. if( i->getSpielerNummer() == sNum )
  626. {
  627. if( i->getPosition() != pos )
  628. chat->addNachricht( Text( "asynchrony detected, position difference: " ) += ( i->getPosition() - pos ).getLength(), 0xFFFF0000 );
  629. if( i->getSpeed() != speed )
  630. chat->addNachricht( Text( "asynchrony detected, speed difference: " ) += ( i->getSpeed() - speed ).getLength(), 0xFFFF0000 );
  631. if( i->getDrehung() != rot )
  632. chat->addNachricht( Text( "asynchrony detected, rot difference: " ) += ( i->getDrehung() - rot ), 0xFFFF0000 );
  633. if( i->getDrehungSpeed() != rotS )
  634. chat->addNachricht( Text( "asynchrony detected, rotS difference: " ) += ( i->getDrehungSpeed() - rotS ), 0xFFFF0000 );
  635. i->setTastataturStatus( T_ROT_R, 1 );
  636. }
  637. }
  638. goToPresence( presence );
  639. break;
  640. case 5: // spieler lässt rotr los
  641. bytes++;
  642. sNum = *(int*)bytes;
  643. bytes += 4;
  644. län -= 4;
  645. pos.x = *(float*)bytes;
  646. bytes += 4;
  647. län -= 4;
  648. pos.y = *(float*)bytes;
  649. bytes += 4;
  650. län -= 4;
  651. speed.x = *(float*)bytes;
  652. bytes += 4;
  653. län -= 4;
  654. speed.y = *(float*)bytes;
  655. bytes += 4;
  656. län -= 4;
  657. rot = *(float*)bytes;
  658. bytes += 4;
  659. län -= 4;
  660. rotS = *(float*)bytes;
  661. län -= 4;
  662. goBackInTime( zeit );
  663. for( auto i = spieler->getIterator(); i; i++ )
  664. {
  665. if( i->getSpielerNummer() == sNum )
  666. {
  667. if( i->getPosition() != pos )
  668. chat->addNachricht( Text( "asynchrony detected, position difference: " ) += ( i->getPosition() - pos ).getLength(), 0xFFFF0000 );
  669. if( i->getSpeed() != speed )
  670. chat->addNachricht( Text( "asynchrony detected, speed difference: " ) += ( i->getSpeed() - speed ).getLength(), 0xFFFF0000 );
  671. if( i->getDrehung() != rot )
  672. chat->addNachricht( Text( "asynchrony detected, rot difference: " ) += ( i->getDrehung() - rot ), 0xFFFF0000 );
  673. if( i->getDrehungSpeed() != rotS )
  674. chat->addNachricht( Text( "asynchrony detected, rotS difference: " ) += ( i->getDrehungSpeed() - rotS ), 0xFFFF0000 );
  675. i->setTastataturStatus( T_ROT_R, 0 );
  676. }
  677. }
  678. goToPresence( presence );
  679. break;
  680. case 6: // Init Spieler
  681. if( 1 )
  682. {
  683. bytes++;
  684. spielerAnzahl = (int)*bytes;
  685. bytes++;
  686. län--;
  687. for( int i = 0; i < spielerAnzahl; i++ )
  688. {
  689. int sNum = *(int*)bytes;
  690. Spieler *tmp = spieler->z( sNum - 1 );
  691. bytes += 4;
  692. län -= 4;
  693. tmp->setAccountId( *(int*)bytes );
  694. bytes += 4;
  695. län -= 4;
  696. if( !teams->z( map->getTeamNummer( sNum ) ) )
  697. teams->set( map->createTeam( map->getTeamNummer( sNum ) ), map->getTeamNummer( sNum ) );
  698. tmp->setTeam( teams->get( map->getTeamNummer( sNum ) ) );
  699. tmp->zTeam()->spieler->add( (Spieler*)tmp->getThis() );
  700. bestenliste->addSpieler( tmp );
  701. bestenliste->updateSpieler( tmp );
  702. bestenliste->updateTeam( tmp->zTeam() );
  703. welt->addObject( tmp->getThis() );
  704. }
  705. int max = map->getMaxSpielerAnzahl();
  706. for( int i = 0; i < max; i++ )
  707. {
  708. if( !spieler->z( i )->zTeam() )
  709. {
  710. spieler->remove( i );
  711. i--;
  712. max--;
  713. }
  714. }
  715. }
  716. break;
  717. case 0x8: // Chat Nachricht
  718. if( 1 )
  719. {
  720. bytes++;
  721. Text *txt = new Text( "" );
  722. txt->append( bytes, län );
  723. chat->addNachricht( txt->getText() );
  724. txt->release();
  725. län = 0;
  726. }
  727. break;
  728. case 0x9: // Spieler Nummer
  729. bytes++;
  730. spielerNummer = *(int*)bytes;
  731. län -= 4;
  732. for( int i = 0; i < spielerAnzahl; i++ )
  733. {
  734. if( spieler->z( i )->getSpielerNummer() == spielerNummer )
  735. {
  736. shipGUI->update( spieler->z( i ) );
  737. break;
  738. }
  739. }
  740. break;
  741. case 0xA: // Start
  742. spielPause = 0;
  743. rendern = 1;
  744. break;
  745. case 0xB: // Ende
  746. //chat->addNachricht( "Spiel beendet", 0xFF909090 );
  747. csv.schreibe( "\n\nSpielernummer;Kills;Tode;Schaden gemacht;Schaden bekommen;Schüsse;Treffer\n", 2 );
  748. for( int i = 0; i < spielerAnzahl; i++ )
  749. {
  750. Spieler *s = spieler->z( i );
  751. Text line = s->getSpielerNummer();
  752. line += ";";
  753. line += s->getKills();
  754. line += ";";
  755. line += s->getTode();
  756. line += ";";
  757. line += s->getSchadenGemacht();
  758. line += ";";
  759. line += s->getSchadenBekommen();
  760. line += ";";
  761. line += s->getSchüsse();
  762. line += ";";
  763. line += s->getTreffer();
  764. line += "\n";
  765. csv.schreibe( line, line.getLength() );
  766. }
  767. csv.close();
  768. end = new Ende( schrift );
  769. bytes++;
  770. län--;
  771. end->setGewonnen( *bytes );
  772. break;
  773. case 0xC: // Skill
  774. if( 1 )
  775. {
  776. bytes++;
  777. sNum = *(int*)bytes;
  778. bytes += 4;
  779. län -= 4;
  780. char art = *bytes;
  781. län--;
  782. Text line = sNum;
  783. line += ";";
  784. line += art;
  785. line += "\n";
  786. csv.schreibe( line, line.getLength() );
  787. goBackInTime( zeit );
  788. for( int i = 0; i < spielerAnzahl; i++ )
  789. {
  790. if( spieler->z( i )->getSpielerNummer() == sNum )
  791. {
  792. Team *tmp = spieler->z( i )->zTeam();
  793. spieler->z( i )->setSkill( art );
  794. tmp->akkuLeistung = tmp->getAkkuLeistungBonus();
  795. tmp->beschleunigung = tmp->getBeschleunigungBonus();
  796. tmp->laserEffizienz = tmp->getLaserEffizienzBonus();
  797. tmp->laserIntensität = tmp->getLaserIntensitätBonus();
  798. tmp->laserTempo = tmp->getLaserTempoBonus();
  799. tmp->maxEnergie = tmp->getMaxEnergieBonus();
  800. tmp->maxStabilität = tmp->getMaxStabilitätBonus();
  801. tmp->reparatur = tmp->getReperaturBonus();
  802. tmp->wendigkeit = tmp->getWendigkeitBonus();
  803. tmp->antriebEffizienz = tmp->getAntriebEffizienzBonus();
  804. tmp->energieSchild = tmp->getEnergieSchildBonus();
  805. tmp->energieSchildEffizienz = tmp->getEnergieSchildEffizienzBonus();
  806. break;
  807. }
  808. }
  809. goToPresence( presence );
  810. for( int i = 0; i < spielerAnzahl; i++ )
  811. {
  812. if( spieler->z( i )->getSpielerNummer() == spielerNummer )
  813. {
  814. shipGUI->update( spieler->z( i ) );
  815. break;
  816. }
  817. }
  818. }
  819. break;
  820. case 0xD: // Schuss
  821. if( 1 )
  822. {
  823. bytes++;
  824. int id = *(int*)bytes;
  825. bytes += 4;
  826. län -= 4;
  827. sNum = *(int*)bytes;
  828. bytes += 4;
  829. län -= 4;
  830. float xPos = *(float*)bytes;
  831. bytes += 4;
  832. län -= 4;
  833. float yPos = *(float*)bytes;
  834. bytes += 4;
  835. län -= 4;
  836. float xSpeed = *(float*)bytes;
  837. bytes += 4;
  838. län -= 4;
  839. float ySpeed = *(float*)bytes;
  840. bytes += 4;
  841. län -= 4;
  842. double intensität = *(double*)bytes;
  843. län -= 8;
  844. int farbe = 0;
  845. goBackInTime( zeit );
  846. for( int i = 0; i < spielerAnzahl; i++ )
  847. {
  848. if( spieler->z( i )->getSpielerNummer() == sNum )
  849. {
  850. if( spieler->z( i )->getPosition() != Vertex( xPos, yPos ) )
  851. chat->addNachricht( Text( "asynchrony detected difference: " ) += ( spieler->z( i )->getPosition() - Vertex( xPos, yPos ) ).getLength(), 0xFFFF0000 );
  852. spieler->z( i )->setPosition( Vertex( xPos, yPos ) );
  853. spieler->z( i )->hatGeschossen();
  854. farbe = spieler->z( i )->zTeam()->farbe;
  855. break;
  856. }
  857. }
  858. Laser *l = new Laser( id, Vertex( xPos, yPos ), Vertex( xSpeed, ySpeed ), sNum, intensität, farbe );
  859. welt->addObject( l->getThis() );
  860. schüsse->add( l );
  861. goToPresence( presence );
  862. if( sNum == spielerNummer )
  863. {
  864. for( int i = 0; i < spielerAnzahl; i++ )
  865. {
  866. if( spieler->z( i )->getSpielerNummer() == spielerNummer )
  867. {
  868. shipGUI->update( spieler->z( i ) );
  869. bestenliste->updateSpieler( spieler->z( i ) );
  870. break;
  871. }
  872. }
  873. }
  874. }
  875. break;
  876. case 0xE: // Treffer
  877. if( 1 )
  878. {
  879. bytes++;
  880. int schuss = *(int*)bytes;
  881. bytes += 4;
  882. län -= 4;
  883. int sNum = *(int*)bytes;
  884. län -= 4;
  885. goBackInTime( zeit );
  886. int sAnz = schüsse->getEintragAnzahl();
  887. for( int i = 0; i < sAnz; i++ )
  888. {
  889. Laser *tmp = schüsse->z( i );
  890. if( tmp && tmp->getId() == schuss )
  891. {
  892. if( sNum >= 0 )
  893. {
  894. double intens = 0;
  895. for( auto s = spieler->getIterator(); s; s++ )
  896. {
  897. if( s->getSpielerNummer() == sNum )
  898. {
  899. intens = tmp->getIntensität( s->getSpeed() );
  900. s->nimmSchaden( intens );
  901. s->impuls( tmp->getPosition() - tmp->getSpeed(), tmp->getSpeed() * 0.3f );
  902. s->calcDeadPlayerObject( schüsse->z( i ) );
  903. bestenliste->updateSpieler( s );
  904. break;
  905. }
  906. }
  907. for( auto s = spieler->getIterator(); s; s++ )
  908. {
  909. if( s->getSpielerNummer() == tmp->getSpieler() )
  910. {
  911. s->machSchaden( intens );
  912. bestenliste->updateSpieler( s );
  913. break;
  914. }
  915. }
  916. }
  917. welt->removeObject( tmp );
  918. schüsse->remove( i );
  919. break;
  920. }
  921. }
  922. goToPresence( presence );
  923. if( sNum == spielerNummer )
  924. {
  925. for( auto s = spieler->getIterator(); s; s++ )
  926. {
  927. if( s->getSpielerNummer() == spielerNummer )
  928. {
  929. shipGUI->update( s );
  930. break;
  931. }
  932. }
  933. }
  934. }
  935. break;
  936. case 0xF: // Wiederbelebung
  937. if( 1 )
  938. {
  939. bytes++;
  940. int sNum = *(int*)bytes;
  941. län -= 4;
  942. goBackInTime( zeit );
  943. for( auto s = spieler->getIterator(); s; s++ )
  944. {
  945. if( s->getSpielerNummer() == sNum )
  946. {
  947. s->wiederbelebung();
  948. break;
  949. }
  950. }
  951. goToPresence( presence );
  952. if( sNum == spielerNummer )
  953. {
  954. for( auto s = spieler->getIterator(); s; s++ )
  955. {
  956. if( s->getSpielerNummer() == spielerNummer )
  957. {
  958. shipGUI->update( s );
  959. break;
  960. }
  961. }
  962. }
  963. }
  964. break;
  965. case 0x10: // Tod
  966. if( 1 )
  967. {
  968. bytes++;
  969. sNum = *(int*)bytes;
  970. bytes += 4;
  971. län -= 4;
  972. int killer = *(int*)bytes;
  973. län -= 4;
  974. goBackInTime( zeit );
  975. for( auto s = spieler->getIterator(); s; s++ )
  976. {
  977. if( s->getSpielerNummer() == sNum )
  978. {
  979. DeadPlayer *dp = s->sterben();
  980. if( dp )
  981. {
  982. welt->addObject( dp->getThis() );
  983. deads->add( dp );
  984. }
  985. bestenliste->updateSpieler( s );
  986. }
  987. if( s->getSpielerNummer() == killer )
  988. {
  989. s->addKill();
  990. s->zTeam()->punkte++;
  991. bestenliste->updateTeam( s->zTeam() );
  992. bestenliste->updateSpieler( s );
  993. }
  994. }
  995. goToPresence( presence );
  996. if( sNum == spielerNummer )
  997. {
  998. for( int i = 0; i < spielerAnzahl; i++ )
  999. {
  1000. if( spieler->z( i )->getSpielerNummer() == spielerNummer )
  1001. {
  1002. shipGUI->update( spieler->z( i ) );
  1003. break;
  1004. }
  1005. }
  1006. }
  1007. }
  1008. break;
  1009. default:
  1010. // Fehler beim verarbeiten
  1011. break;
  1012. }
  1013. if( län != 0 )
  1014. {
  1015. // Fehler beim verarbeiten
  1016. chat->addNachricht( "Es ist ein Fehler beim verarbeiten einer Nachricht aufgetreten.", 0xFFFF0000 );
  1017. }
  1018. n->setVerarbeitet();
  1019. }
  1020. for( int i = stkna; i > 0; i-- )
  1021. {
  1022. if( !stkn->z( 0 ) || !stkn->z( 0 )->istVerarbeitet() )
  1023. break;
  1024. stkna--;
  1025. stkn->remove( 0 );
  1026. }
  1027. unlock();
  1028. }
  1029. bool SpielKlasse::tick( double zeit )
  1030. {
  1031. stknVerarbeitung();
  1032. if( spielPause )
  1033. {
  1034. zeit = 0;
  1035. return 1;
  1036. }
  1037. rZeit += zeit;
  1038. while( TICK <= rZeit )
  1039. {
  1040. rZeit -= TICK;
  1041. if( end )
  1042. return 1;
  1043. lock();
  1044. if( spielZeit == -1 )
  1045. save(); // speichern
  1046. // tote spieler
  1047. int deadsCount = deads->getEintragAnzahl();
  1048. for( int i = 0; i < deadsCount; i++ )
  1049. {
  1050. if( deads->z( i )->isFinished() )
  1051. {
  1052. welt->removeObject( deads->z( i ) );
  1053. deads->remove( i-- );
  1054. deadsCount--;
  1055. }
  1056. }
  1057. // spiel fortschritt
  1058. tick();
  1059. minimap->tick( TICK );
  1060. // Kamera bewegen
  1061. Vertex tPos;
  1062. bool setKam = 0;
  1063. for( int i = 0; i < spielerAnzahl; i++ )
  1064. {
  1065. if( spieler->z( i )->getSpielerNummer() == spielerNummer )
  1066. shipGUI->update( spieler->z( i ) );
  1067. if( spielerNummer == spieler->z( i )->getSpielerNummer() )
  1068. {
  1069. tPos = spieler->z( i )->getPosition();
  1070. setKam = spieler->z( i )->istAmLeben();
  1071. }
  1072. }
  1073. unlock();
  1074. if( setKam )
  1075. {
  1076. Vertex str = ( tPos - kam->getWorldPosition() );
  1077. if( ( tPos + welt->getWorldInfo().size - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1078. str = ( tPos + welt->getWorldInfo().size - kam->getWorldPosition() );
  1079. if( ( tPos - welt->getWorldInfo().size - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1080. str = ( tPos - welt->getWorldInfo().size - kam->getWorldPosition() );
  1081. if( ( tPos + Punkt( welt->getWorldInfo().size.x, 0 ) - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1082. str = ( tPos + Punkt( welt->getWorldInfo().size.x, 0 ) - kam->getWorldPosition() );
  1083. if( ( tPos + Punkt( -welt->getWorldInfo().size.x, 0 ) - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1084. str = ( tPos + Punkt( -welt->getWorldInfo().size.x, 0 ) - kam->getWorldPosition() );
  1085. if( ( tPos + Punkt( 0, welt->getWorldInfo().size.y ) - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1086. str = ( tPos + Punkt( 0, welt->getWorldInfo().size.y ) - kam->getWorldPosition() );
  1087. if( ( tPos + Punkt( 0, -welt->getWorldInfo().size.y ) - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1088. str = ( tPos + Punkt( 0, -welt->getWorldInfo().size.y ) - kam->getWorldPosition() );
  1089. if( ( tPos + Punkt( welt->getWorldInfo().size.x, -welt->getWorldInfo().size.y ) - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1090. str = ( tPos + Punkt( welt->getWorldInfo().size.x, -welt->getWorldInfo().size.y ) - kam->getWorldPosition() );
  1091. if( ( tPos + Punkt( -welt->getWorldInfo().size.x, welt->getWorldInfo().size.y ) - kam->getWorldPosition() ).getLengthSq() < str.getLengthSq() )
  1092. str = ( tPos + Punkt( -welt->getWorldInfo().size.x, welt->getWorldInfo().size.y ) - kam->getWorldPosition() );
  1093. kam->lookAtWorldPos( kam->getWorldPosition() + str / 4.f * (float)TICK );
  1094. }
  1095. chat->tick( !zeit ? 0.05 : zeit );
  1096. if( shipGUI )
  1097. shipGUI->tick( !zeit ? 0.05 : zeit );
  1098. }
  1099. return 1;
  1100. }
  1101. void SpielKlasse::render( Bild &zRObj )
  1102. {
  1103. if( !rendern )
  1104. return;
  1105. lock();
  1106. kam->lookAtWorldArea( zRObj.getBreite(), zRObj.getHeight() );
  1107. kam->setSize( zRObj.getSize() );
  1108. kam->render( zRObj );
  1109. minimap->setPosition( zRObj.getSize() - Punkt( 210, 210 ) );
  1110. minimap->lookAtWorldPos( welt->getWorldInfo().size.x / 2, welt->getWorldInfo().size.y / 2 );
  1111. minimap->lookAtWorldArea( welt->getWorldInfo().size.x, welt->getWorldInfo().size.y );
  1112. minimap->render( zRObj );
  1113. chat->render( zRObj );
  1114. if( bestenliste )
  1115. bestenliste->render( zRObj );
  1116. if( shipGUI )
  1117. shipGUI->render( zRObj );
  1118. if( end )
  1119. end->render( zRObj );
  1120. unlock();
  1121. }
  1122. // constant
  1123. int SpielKlasse::läuft() const
  1124. {
  1125. if( !rendern )
  1126. return 3;
  1127. if( !end )
  1128. return 2;
  1129. if( end && !end->getWeiter() )
  1130. return 1;
  1131. if( end && end->getWeiter() )
  1132. return 0;
  1133. return 0;
  1134. }
  1135. // Reference Counting
  1136. SpielV *SpielKlasse::getThis()
  1137. {
  1138. ref++;
  1139. return this;
  1140. }
  1141. SpielV *SpielKlasse::release()
  1142. {
  1143. ref--;
  1144. if( !ref )
  1145. delete this;
  1146. return 0;
  1147. }