SpielKlasse.cpp 34 KB

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