Spiel.cpp 27 KB

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