SpielKlasse.cpp 40 KB

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