Spiel.cpp 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. #include "Spiel.h"
  2. #include <time.h>
  3. #include <DateiSystem.h>
  4. #include "Define.h"
  5. #include "SSKlient.h"
  6. #include "KartenLeser.h"
  7. #include "Statistik.h"
  8. #include "Team.h"
  9. #include "Laser.h"
  10. #include <M2Datei.h>
  11. #include <iostream>
  12. #ifdef WIN32
  13. #include <random>
  14. #else
  15. #include <math.h>
  16. #include <unistd.h>
  17. #include <stdlib.h>
  18. #define Sleep( x ) usleep( (x) * 1000 )
  19. #endif
  20. // Inhalt der Spiel Klasse aus Spiel.h
  21. // Konstruktor
  22. Spiel::Spiel()
  23. {
  24. zAccounts = 0;
  25. zKlients = 0;
  26. asteroids = new RCArray< Asteroid >();
  27. asteroidModels = new RCArray< Model2DData >();
  28. stat = new Statistik();
  29. teams = new RCArray< Team >();
  30. teamAnzahl = 0;
  31. spieler = new RCArray< Spieler >();
  32. shots = new RCArray< Laser >();
  33. objekte = new RCArray< SpielObjekt >();
  34. welt = new Welt2D();
  35. pixel = new RCArray< Pixel >();
  36. welt->setCircular( 1 );
  37. welt->setAirResistance( 0.001f );
  38. psqldb = 0;
  39. spielId = 0;
  40. karteId = 0;
  41. spielerAnzahl = 0;
  42. karte = 0;
  43. InitializeCriticalSection( &cs );
  44. sts = 0;
  45. log = 0;
  46. isRunning = 0;
  47. spielZeit = 0;
  48. ende = 1;
  49. nextSchussId = 1;
  50. nextAsteroid = 30;
  51. asteroidId = 0;
  52. pixelId = 0;
  53. ref = 1;
  54. }
  55. // Destruktor
  56. Spiel::~Spiel()
  57. {
  58. teams->release();
  59. stat->release();
  60. for( auto s = spieler->getIterator(); s; s++ )
  61. s->setTeam( 0 );
  62. spieler->release();
  63. for( auto o = objekte->getIterator(); o; o++ )
  64. o->setTeam( 0 );
  65. objekte->release();
  66. welt->release();
  67. asteroids->release();
  68. asteroidModels->release();
  69. if( psqldb )
  70. psqldb->release();
  71. if( karte )
  72. karte->release();
  73. if( sts )
  74. sts->release();
  75. pixel->release();
  76. DeleteCriticalSection( &cs );
  77. }
  78. // privat
  79. int Spiel::getTeamVonSpieler( int sNum )
  80. {
  81. for( int i = 0; i < spielerAnzahl; i++ )
  82. {
  83. Spieler *tmp = spieler->z( i );
  84. if( tmp && tmp->getSpielerNummer() == sNum )
  85. return tmp->zTeam() ? tmp->zTeam()->id : 0;
  86. }
  87. return 0;
  88. }
  89. // nicht constant
  90. void Spiel::setPSQLK( SSDatenbankV * psqldb )
  91. {
  92. if( this->psqldb )
  93. this->psqldb->release();
  94. this->psqldb = psqldb;
  95. stat->setPSQLDB( psqldb->getThis() );
  96. }
  97. void Spiel::setSpielId( int id )
  98. {
  99. spielId = id;
  100. stat->setSpielId( id );
  101. }
  102. void Spiel::setKarteId( int karteId )
  103. {
  104. this->karteId = karteId;
  105. stat->setKarteId( karteId );
  106. }
  107. void Spiel::setTempPfad( char *pfad )
  108. {
  109. mapPfad = pfad;
  110. mapPfad += "/";
  111. }
  112. void Spiel::setAccounts( int anzahl, Array< int > * zAccounts )
  113. {
  114. this->zAccounts = zAccounts->getThis();
  115. spielerAnzahl = anzahl;
  116. }
  117. void Spiel::setKlients( int anzahl, RCArray< SSKlientV > * zKlients )
  118. {
  119. this->zKlients = zKlients->getThis();
  120. }
  121. void Spiel::setSpielerNummern( int anzahl, Array< int > * spielerNummern )
  122. {
  123. if( !sts )
  124. {
  125. sts = new SpielerTeamStruktur();
  126. KartenLeser *reader = new KartenLeser( karteId, psqldb->getThis(), mapPfad );
  127. reader->ladeSpielerTeamStruktur( sts );
  128. if( karte )
  129. karte->release();
  130. karte = reader->ladeKarte( sts );
  131. reader->release();
  132. for( int i = 0; i < sts->teamAnzahl; i++ )
  133. teams->set( karte->createTeam( i ), i );
  134. stat->setTeamNamen( sts->teamName->getThis() );
  135. for( auto o = karte->getObjekte(); o; o++ )
  136. {
  137. SpielObjekt *obj = karte->createObjekt( o->id );
  138. obj->setTeam( teams->get( o->team - 1 ) );
  139. welt->addObject( obj->getThis() );
  140. objekte->add( obj );
  141. }
  142. welt->setSize( karte->getSize().x, karte->getSize().y );
  143. welt->setSize( 1 );
  144. }
  145. for( int i = 0; i < anzahl; i++ )
  146. {
  147. Spieler *tmp = karte->createSpieler( spielerNummern->get( i ) );
  148. if( tmp )
  149. {
  150. int team = 0;
  151. int von = 0;
  152. int bis = 0;
  153. for( int j = 0; j < sts->teamAnzahl; j++ )
  154. {
  155. bis = von + ( sts->teamSize->hat( j ) ? sts->teamSize->get( j ) : 0 );
  156. if( spielerNummern->get( i ) >= von && spielerNummern->get( i ) < bis )
  157. {
  158. team = j;
  159. break;
  160. }
  161. von = bis;
  162. }
  163. tmp->setTeam( teams->get( team ) );
  164. teams->z( team )->spieler->add( tmp );
  165. }
  166. welt->addObject( tmp->getThis() );
  167. spieler->set( tmp, i );
  168. }
  169. for( int i = 0; i < anzahl; i++ )
  170. spieler->z( i )->setAccountId( zAccounts->hat( i ) ? zAccounts->get( i ) : 0 );
  171. for( int i = 0; i < anzahl; i++ )
  172. spieler->z( i )->setKlient( new Klient( zKlients->get( i ) ) );
  173. stat->setSpieler( spielerAnzahl, spieler );
  174. zAccounts = zAccounts->release();
  175. zKlients = zKlients->release();
  176. teamAnzahl = 0;
  177. for( int i = 0; i < sts->teamAnzahl; i++ )
  178. if( teams->z( i )->spieler->getEintragAnzahl() )
  179. teamAnzahl++;
  180. }
  181. void Spiel::klientOffline( int accountId )
  182. {
  183. for( int i = 0; i < spielerAnzahl; i++ )
  184. {
  185. if( spieler->z( i )->getAccountId() == accountId )
  186. spieler->z( i )->offline();
  187. }
  188. }
  189. void Spiel::klientOnline( int accountId, SSKlientV * zKlient )
  190. {
  191. for( int i = 0; i < spielerAnzahl; i++ )
  192. {
  193. if( spieler->z( i )->getAccountId() == accountId )
  194. {
  195. EnterCriticalSection( &cs );
  196. Spieler *s = spieler->z( i );
  197. s->online( zKlient );
  198. Klient *tmp = spieler->z( i )->zKlient();
  199. tmp->sendeSpielerNummer( s->getSpielerNummer(), 0 );
  200. //--------------------------
  201. LeaveCriticalSection( &cs );
  202. }
  203. }
  204. }
  205. void Spiel::nachricht( int accountId, int len, char *bytes )
  206. {
  207. if( !isRunning || ende )
  208. return;
  209. EnterCriticalSection( &cs );
  210. if( ende )
  211. {
  212. LeaveCriticalSection( &cs );
  213. return;
  214. }
  215. char *msgBeg = bytes;
  216. int msgLen = len;
  217. int msgAccount = accountId;
  218. bool saveMSG = 1;
  219. len--;
  220. switch( *bytes )
  221. {
  222. case 0:
  223. case 1:
  224. case 2:
  225. case 3:
  226. case 4:
  227. case 5:
  228. case 6:
  229. case 7:
  230. for( int i = 0; i < spielerAnzahl; i++ )
  231. {
  232. Spieler *tmp = spieler->z( i );
  233. if( tmp && tmp->getAccountId() == accountId )
  234. {
  235. if( !tmp->istAmLeben() )
  236. break;
  237. if( !tmp->setTastataturStatus( (TastaturStatus)( (int)( *bytes ) / 2 ), ( (int)( *bytes ) % 2 ) == 0 ) )
  238. {
  239. saveMSG = 0;
  240. break;
  241. }
  242. if( *bytes != 6 && *bytes != 7 )
  243. {
  244. for( int j = 0; j < spielerAnzahl; j++ )
  245. {
  246. Spieler *s = spieler->z( j );
  247. if( s && s->zKlient() )
  248. s->zKlient()->sendeTastaturStatus( tmp->getSpielerNummer(), (TastaturStatus)( (int)( *bytes ) / 2 ), ( (int)( *bytes ) % 2 ) == 0, spielZeit );
  249. }
  250. }
  251. break;
  252. }
  253. }
  254. break;
  255. case 8: // chat Nachricht
  256. if( 1 )
  257. {
  258. bytes++;
  259. Text *txt = psqldb->getAccountRufName( accountId );
  260. txt->append( ": " );
  261. txt->append( bytes, len );
  262. for( int i = 0; i < spielerAnzahl; i++ )
  263. {
  264. Spieler *tmp = spieler->z( i );
  265. if( tmp && tmp->zKlient() )
  266. tmp->zKlient()->sendeChatNachricht( txt->getText(), spielZeit );
  267. }
  268. txt->release();
  269. len = 0;
  270. }
  271. break;
  272. case 9: // Skill verwendung
  273. {
  274. bytes++;
  275. char art = *bytes;
  276. len--;
  277. for( int i = 0; i < spielerAnzahl; i++ )
  278. {
  279. Spieler *tmp = spieler->z( i );
  280. if( tmp && tmp->getAccountId() == accountId )
  281. {
  282. if( !tmp->istAmLeben() )
  283. break;
  284. if( !tmp->setSkill( art ) )
  285. {
  286. saveMSG = 0;
  287. break;
  288. }
  289. for( int j = 0; j < spielerAnzahl; j++ )
  290. {
  291. Spieler *s = spieler->z( j );
  292. if( s && s->zKlient() )
  293. s->zKlient()->sendeSkillNachricht( tmp->getSpielerNummer(), art, spielZeit );
  294. }
  295. break;
  296. }
  297. }
  298. break;
  299. }
  300. case 0xA: // Use active skill
  301. {
  302. bytes++;
  303. char id = *bytes;
  304. len--;
  305. for( int i = 0; i < spielerAnzahl; i++ )
  306. {
  307. Spieler *tmp = spieler->z( i );
  308. if( tmp && tmp->getAccountId() == accountId )
  309. {
  310. if( !tmp->istAmLeben() )
  311. break;
  312. tmp->useSkill( id );
  313. for( int j = 0; j < spielerAnzahl; j++ )
  314. {
  315. Spieler *s = spieler->z( j );
  316. if( s && s->zKlient() )
  317. s->zKlient()->sendeUseSkillNachricht( tmp->getSpielerNummer(), id, spielZeit );
  318. }
  319. break;
  320. }
  321. }
  322. break;
  323. }
  324. default:
  325. saveMSG = 0;
  326. }
  327. if( len )
  328. {
  329. // error
  330. }
  331. if( log && log->istOffen() && saveMSG )
  332. {
  333. char c = 1;
  334. log->schreibe( &c, 1 );
  335. int spielerNum = 0;
  336. for( int i = 0; i < spielerAnzahl; i++ )
  337. {
  338. Spieler *tmp = spieler->z( i );
  339. if( tmp && tmp->getAccountId() == msgAccount )
  340. {
  341. spielerNum = tmp->getSpielerNummer();
  342. break;
  343. }
  344. }
  345. log->schreibe( (char *)& spielerNum, 4 );
  346. short l = (short)msgLen;
  347. log->schreibe( (char *)& l, 2 );
  348. log->schreibe( msgBeg, l );
  349. }
  350. LeaveCriticalSection( &cs );
  351. }
  352. void Spiel::tick( double zeit )
  353. {
  354. // Objekte updaten
  355. welt->tick( zeit );
  356. // Spieler Updaten
  357. for( int i = 0; i < spielerAnzahl; i++ )
  358. {
  359. Spieler *tmp = spieler->z( i );
  360. if( tmp )
  361. {
  362. if( tmp->doNeedWiederbelebung() )
  363. { // Wiederbelebung
  364. tmp->wiederbeleben();
  365. for( int j = 0; j < spielerAnzahl; j++ )
  366. {
  367. Spieler *s = spieler->z( j );
  368. if( s )
  369. s->zKlient()->sendeWiederbelebung( tmp->getSpielerNummer(), spielZeit );
  370. }
  371. }
  372. }
  373. }
  374. // Schüsse Collision
  375. int anz = shots->getEintragAnzahl();
  376. for( int i = 0; i < anz; i++ )
  377. {
  378. Laser *tmp = shots->z( i );
  379. if( tmp )
  380. {
  381. if( tmp->getIntensity() <= 0 )
  382. { // Schuss existiert nicht mehr
  383. for( int j = 0; j < spielerAnzahl; j++ )
  384. {
  385. Spieler *s = spieler->z( j );
  386. if( s )
  387. s->zKlient()->sendeTreffer( tmp->getId(), -1, spielZeit, 0, 0 );
  388. }
  389. welt->removeObject( tmp );
  390. shots->remove( i );
  391. anz--;
  392. i--;
  393. }
  394. else
  395. { // Schuss existiert noch
  396. int team = getTeamVonSpieler( tmp->getSpieler() );
  397. for( int j = 0; j < spielerAnzahl; j++ )
  398. {
  399. Spieler *attacked = spieler->z( j );
  400. if( attacked && attacked->zTeam() && attacked->zTeam()->id != team && attacked->istTreffer( tmp->getPosition() ) )
  401. { // Treffer
  402. Spieler *attacker = 0;
  403. for( int k = 0; k < spielerAnzahl; k++ )
  404. {
  405. Spieler *tmpS = spieler->z( k );
  406. if( tmpS && tmpS->getSpielerNummer() == tmp->getSpieler() )
  407. attacker = tmpS;
  408. }
  409. double intens = tmp->getIntensity() * ( ( tmp->getSpeed() - attacked->getSpeed() ).getLength() / 200 );
  410. bool kill = attacked->nimmSchaden( intens, attacker ? attacker->getLevel() : 1 );
  411. if( tmp->getSpeed().getLengthSq() > 0 )
  412. attacked->impuls( tmp->getPosition() - tmp->getSpeed(), tmp->getSpeed() * 0.3f );
  413. int skillP = attacker->getSkillP();
  414. attacker->machSchaden( intens, attacked->getLevel() );
  415. float erf = attacker->getEp();
  416. if( kill )
  417. attacker->addKill( attacked->getLevel() );
  418. for( int k = 0; k < spielerAnzahl; k++ )
  419. {
  420. Spieler *sp = spieler->z( k );
  421. if( sp )
  422. sp->zKlient()->sendeTreffer( tmp->getId(), attacked->getSpielerNummer(), spielZeit, erf, skillP );
  423. if( kill && sp )
  424. sp->zKlient()->sendeTod( attacked->getSpielerNummer(), tmp->getSpieler(), spielZeit );
  425. }
  426. if( kill )
  427. {
  428. if( teams->z( team - 1 ) )
  429. teams->z( team - 1 )->punkte++;
  430. if( teams->z( team - 1 )->punkte == teams->z( team - 1 )->maxPunkte )
  431. ende = 1;
  432. }
  433. welt->removeObject( tmp );
  434. shots->remove( i );
  435. anz--;
  436. i--;
  437. break;
  438. }
  439. }
  440. int objektAnzahl = objekte->getEintragAnzahl();
  441. for( int j = 0; j < objektAnzahl; j++ )
  442. {
  443. SpielObjekt *attacked = objekte->z( j );
  444. if( attacked && ( !attacked->zTeam() || attacked->zTeam()->id != team ) && attacked->doesCollideWithLaser() && attacked->istTreffer( tmp->getPosition() ) )
  445. { // Treffer
  446. Spieler *attacker = 0;
  447. for( int k = 0; k < spielerAnzahl; k++ )
  448. {
  449. Spieler *tmpS = spieler->z( k );
  450. if( tmpS && tmpS->getSpielerNummer() == tmp->getSpieler() )
  451. attacker = tmpS;
  452. }
  453. double intens = tmp->getIntensity() * ( ( tmp->getSpeed() - attacked->getSpeed() ).getLength() / 200 );
  454. bool kill = attacked->nimmSchaden( intens, attacker ? attacker->getLevel() : 1 );
  455. if( tmp->getSpeed().getLengthSq() > 0 )
  456. attacked->impuls( tmp->getPosition() - tmp->getSpeed(), tmp->getSpeed() * 0.3f );
  457. int skillP = attacker->getSkillP();
  458. attacker->machSchaden( intens, attacked->getLevel(), attacked->doesShotAddEp() );
  459. float erf = attacker->getEp();
  460. if( kill )
  461. attacker->addKill( attacked->getLevel(), attacked->doesShotAddEp() );
  462. for( int k = 0; k < spielerAnzahl; k++ )
  463. {
  464. Spieler *sp = spieler->z( k );
  465. if( sp )
  466. sp->zKlient()->sendeObjektTreffer( tmp->getId(), attacked->getObjektId(), spielZeit, erf, skillP );
  467. if( kill && sp )
  468. sp->zKlient()->sendeObjektTod( attacked->getObjektId(), tmp->getSpieler(), spielZeit );
  469. }
  470. if( kill )
  471. {
  472. if( teams->z( team - 1 ) )
  473. teams->z( team - 1 )->punkte++;
  474. if( teams->z( team - 1 )->punkte == teams->z( team - 1 )->maxPunkte )
  475. ende = 1;
  476. }
  477. welt->removeObject( tmp );
  478. shots->remove( i );
  479. anz--;
  480. i--;
  481. break;
  482. }
  483. }
  484. int aAnz = asteroids->getEintragAnzahl();
  485. for( int j = 0; j < aAnz; j++ )
  486. {
  487. Asteroid *a = asteroids->z( j );
  488. Vertex pos;
  489. __int64 seed = randG.getSeed();
  490. double intens = tmp->getIntensity() * ( ( tmp->getSpeed() - a->getSpeed() ).getLength() / 200 );
  491. Asteroid * b = a->istTreffer( tmp, &randG, asteroidId, pos );
  492. if( b )
  493. {
  494. float erf = 0;
  495. int skillP = 0;
  496. for( int k = 0; k < spielerAnzahl; k++ )
  497. {
  498. Spieler *s = spieler->z( k );
  499. if( s && s->getSpielerNummer() == tmp->getSpieler() )
  500. {
  501. s->addTreffer( (float)intens, 0 );
  502. erf = s->getEp();
  503. skillP = s->getSkillP();
  504. }
  505. }
  506. for( int k = 0; k < spielerAnzahl; k++ )
  507. {
  508. Spieler *s = spieler->z( k );
  509. if( s )
  510. s->zKlient()->sendeAsteroidTreffer( a->getId(), b->getId(), tmp->getId(), pos, seed, spielZeit, erf, skillP );
  511. }
  512. welt->removeObject( tmp );
  513. shots->remove( i );
  514. if( b->getMasse() > intens * 50 )
  515. {
  516. asteroids->add( (Asteroid *)b->getThis() );
  517. welt->addObject( b );
  518. }
  519. else
  520. {
  521. Pixel *p = new Pixel( b->getPosition(), b->getSpeed(), b->getMasse() / 50, pixelId++ );
  522. welt->addObject( p->getThis() );
  523. pixel->add( p );
  524. for( int k = 0; k < spielerAnzahl; k++ )
  525. {
  526. Spieler *s = spieler->z( k );
  527. if( s )
  528. s->zKlient()->sendePixel( b->getId(), p->getId(), spielZeit );
  529. }
  530. b->release();
  531. }
  532. if( a->getMasse() < intens * 50 )
  533. {
  534. Pixel *p = new Pixel( a->getPosition(), a->getSpeed(), a->getMasse() / 50, pixelId++ );
  535. welt->addObject( p->getThis() );
  536. pixel->add( p );
  537. for( int k = 0; k < spielerAnzahl; k++ )
  538. {
  539. Spieler *s = spieler->z( k );
  540. if( s )
  541. s->zKlient()->sendePixel( a->getId(), p->getId(), spielZeit );
  542. }
  543. welt->removeObject( a );
  544. asteroids->remove( j-- );
  545. aAnz--;
  546. }
  547. }
  548. }
  549. }
  550. }
  551. }
  552. // Neue Schüsse hinzufügen
  553. for( int i = 0; i < spielerAnzahl; i++ )
  554. {
  555. Spieler *tmp = spieler->z( i );
  556. if( tmp )
  557. {
  558. Laser *nL = tmp->getLaser( nextSchussId );
  559. if( nL )
  560. {
  561. nextSchussId++;
  562. welt->addObject( nL->getThis() );
  563. shots->add( nL );
  564. for( int j = 0; j < spielerAnzahl; j++ )
  565. {
  566. if( spieler->z( j ) && spieler->z( j )->zKlient() )
  567. spieler->z( j )->zKlient()->sendeSchuss( nL->getId(), nL->getSpieler(), nL->getPosition(), nL->getSpeed(), nL->getIntensity(), spielZeit );
  568. }
  569. }
  570. }
  571. }
  572. // Asteroiden
  573. nextAsteroid -= zeit;
  574. if( nextAsteroid <= 0 )
  575. {
  576. nextAsteroid += 30 + (float)randG.rand() * 30;
  577. if( asteroids->getEintragAnzahl() < 30 )
  578. {
  579. Vertex pos = Vertex( (float)randG.rand() * (float)welt->getWorldInfo().size.x, (float)randG.rand() * (float)welt->getWorldInfo().size.y );
  580. Vertex speed = Vertex( (float)randG.rand() * 100, (float)randG.rand() * 100 );
  581. float rot = 2 * (float)PI * (float)randG.rand();
  582. float rotS = (float)randG.rand();
  583. int index = (int)( (float)asteroidModels->getEintragAnzahl() * (float)randG.rand() );
  584. Asteroid *astr = new Asteroid( asteroidId++, pos, speed, rot, rotS, asteroidModels->get( index ) );
  585. asteroids->add( astr );
  586. welt->addObject( astr->getThis() );
  587. for( int j = 0; j < spielerAnzahl; j++ )
  588. {
  589. if( spieler->z( j ) && spieler->z( j )->zKlient() )
  590. spieler->z( j )->zKlient()->sendeAsteroid( astr->getId(), pos, speed, rot, rotS, index, spielZeit );
  591. }
  592. }
  593. }
  594. // Pixel
  595. int pixelAnz = pixel->getEintragAnzahl();
  596. for( int i = 0; i < pixelAnz; i++ )
  597. {
  598. Pixel *p = pixel->z( i );
  599. if( p->getEp() <= 0 )
  600. {
  601. for( int j = 0; j < spielerAnzahl; j++ )
  602. {
  603. if( spieler->z( j ) && spieler->z( j )->zKlient() )
  604. spieler->z( j )->zKlient()->sendeEp( p->getId(), -1, spielZeit );
  605. }
  606. pixel->remove( i-- );
  607. welt->removeObject( p );
  608. pixelAnz--;
  609. }
  610. else
  611. {
  612. for( auto s = spieler->getIterator(); s; s++ )
  613. {
  614. if( s->istTreffer( p->getPosition() ) )
  615. {
  616. s->addEp( p->getEp() );
  617. for( int j = 0; j < spielerAnzahl; j++ )
  618. {
  619. if( spieler->z( j ) && spieler->z( j )->zKlient() )
  620. spieler->z( j )->zKlient()->sendeEp( p->getId(), s->getSpielerNummer(), spielZeit );
  621. }
  622. pixel->remove( i-- );
  623. welt->removeObject( p );
  624. pixelAnz--;
  625. break;
  626. }
  627. }
  628. }
  629. }
  630. }
  631. void Spiel::run()
  632. {
  633. Text *pfad = psqldb->getSpielPfad( karteId );
  634. if( pfad )
  635. pfad->append( "/" );
  636. pfad->append( "models/asteroids.m2" );
  637. M2Datei *aDat = new M2Datei();
  638. aDat->setPfadZ( pfad );
  639. aDat->leseDaten();
  640. int anz = aDat->getModelAnzahl();
  641. for( int i = 0; i < anz; i++ )
  642. {
  643. asteroidModels->add( aDat->ladeModel( aDat->zModelName( i )->getText() ) );
  644. }
  645. log = new Datei();
  646. pfad = new Text( "../spiel log/" );
  647. pfad->append( spielId );
  648. pfad->append( "/verlauf.ksggl" );
  649. log->setDatei( pfad );
  650. log->remove();
  651. log->erstellen();
  652. log->open( Datei::Style::schreiben );
  653. time_t t;
  654. time( &t );
  655. srand( (unsigned int)t );
  656. log->schreibe( (char *)& spielerAnzahl, 4 );
  657. for( int i = 0; i < spielerAnzahl; i++ )
  658. {
  659. Spieler *tmp = spieler->z( i );
  660. if( tmp && tmp->zKlient() )
  661. {
  662. tmp->addSkill( new ShieldBoost() );
  663. tmp->addSkill( new SpeedBoost() );
  664. tmp->zKlient()->sendeInit( spieler, -1 );
  665. log->schreibe( (char *)& i, 4 );
  666. int sNum = tmp->getSpielerNummer();
  667. log->schreibe( (char *)& sNum, 4 );
  668. tmp->zKlient()->sendeSpielerNummer( sNum, -1 );
  669. int team = tmp->zTeam()->id;
  670. log->schreibe( (char *)& team, 4 );
  671. int farbe = tmp->getSpielerFarbe();
  672. log->schreibe( (char *)& farbe, 4 );
  673. farbe = tmp->zTeam()->farbe;
  674. log->schreibe( (char *)& farbe, 4 );
  675. Text * name = psqldb->getAccountRufName( tmp->getAccountId() );
  676. char len = (char)( name ? name->getLength() : 0 );
  677. log->schreibe( &len, 1 );
  678. if( len )
  679. log->schreibe( name->getText(), len );
  680. if( name )
  681. name->release();
  682. name = sts->teamName->z( team );
  683. len = (char)( name ? name->getLength() : 0 );
  684. log->schreibe( &len, 1 );
  685. if( len )
  686. log->schreibe( name->getText(), len );
  687. }
  688. }
  689. __int64 randSeed = randG.getSeed();
  690. log->schreibe( (char *)& randSeed, 8 );
  691. Array< char > spielerStatus;
  692. ZeitMesser * zeit = new ZeitMesser();
  693. zeit->messungStart();
  694. isRunning = 1;
  695. ende = 0;
  696. double ausgleich = 0;
  697. double sZ = 0;
  698. spielZeit = -1;
  699. for( int i = 0; i < spielerAnzahl; i++ )
  700. {
  701. Spieler *tmp = spieler->z( i );
  702. if( tmp && tmp->zKlient() )
  703. tmp->zKlient()->sendeStart( spielZeit );
  704. }
  705. double rZeit = 0;
  706. while( !ende )
  707. {
  708. zeit->messungEnde();
  709. zeit->messungStart();
  710. double z = zeit->getSekunden();
  711. ausgleich += TICK - z;
  712. if( ausgleich > 0 )
  713. Sleep( (int)( ausgleich * 1000 ) );
  714. rZeit += z;
  715. while( sZ + TICK < rZeit && !ende )
  716. {
  717. EnterCriticalSection( &cs );
  718. sZ += TICK;
  719. spielZeit++;
  720. char c = 0;
  721. log->schreibe( &c, 1 );
  722. tick( TICK );
  723. LeaveCriticalSection( &cs );
  724. }
  725. }
  726. zeit->messungEnde();
  727. zeit->release();
  728. for( int i = 0; i < spielerAnzahl; i++ )
  729. {
  730. if( spieler->z( i ) && spieler->z( i )->zKlient() )
  731. {
  732. if( spieler->z( i )->zTeam()->punkte < spieler->z( i )->zTeam()->maxPunkte )
  733. {
  734. spielerStatus.set( 1, i ); // Datenbank Verloren
  735. spieler->z( i )->zKlient()->sendeSpielEnde( 0, 0 );
  736. }
  737. else
  738. {
  739. spielerStatus.set( 2, i ); // Datenbank Gewonnen
  740. spieler->z( i )->zKlient()->sendeSpielEnde( 1, 0 );
  741. }
  742. }
  743. if( spieler->z( i ) && ( !spieler->z( i )->zKlient() || !spieler->z( i )->istOnline() ) )
  744. spielerStatus.set( 3, i );
  745. }
  746. if( teamAnzahl == 1 )
  747. psqldb->setSpielStatusBeendet( spielId, 6 );
  748. else
  749. psqldb->setSpielStatusBeendet( spielId, 5 );
  750. for( int i = 0; i < spielerAnzahl; i++ )
  751. {
  752. Spieler *tmp = spieler->z( i );
  753. if( tmp )
  754. {
  755. psqldb->setSpielSpielerStatus( spielId, tmp->getAccountId(), tmp->getPunkte(), spielerStatus.get( i ) );
  756. if( teamAnzahl > 1 )
  757. psqldb->addSpielerStatistik( tmp->getAccountId(), spielId );
  758. }
  759. }
  760. log->close();
  761. log = log->release();
  762. isRunning = 0;
  763. }
  764. // constant
  765. StatistikV *Spiel::getStatistik() const
  766. {
  767. return stat->getThis();
  768. }
  769. // Reference Counting
  770. SpielKlasse *Spiel::getThis()
  771. {
  772. ref++;
  773. return this;
  774. }
  775. SpielKlasse *Spiel::release()
  776. {
  777. ref--;
  778. if( !ref )
  779. delete this;
  780. return 0;
  781. }