CGameHandler.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include <boost/foreach.hpp>
  2. #include <boost/thread.hpp>
  3. #include <boost/thread/shared_mutex.hpp>
  4. #include <boost/bind.hpp>
  5. #include "CGameHandler.h"
  6. #include "../CGameState.h"
  7. #include "../StartInfo.h"
  8. #include "../map.h"
  9. #include "../lib/NetPacks.h"
  10. #include "../lib/Connection.h"
  11. #include "../CLua.h"
  12. #include "../hch/CObjectHandler.h"
  13. #include "../hch/CTownHandler.h"
  14. #include "../hch/CHeroHandler.h"
  15. bool makingTurn;
  16. boost::condition_variable cTurn;
  17. boost::mutex mTurn;
  18. boost::shared_mutex gsm;
  19. void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
  20. {
  21. ui16 pom;
  22. while(1)
  23. {
  24. c >> pom;
  25. switch(pom)
  26. {
  27. case 100: //my interface end its turn
  28. mTurn.lock();
  29. makingTurn = false;
  30. mTurn.unlock();
  31. cTurn.notify_all();
  32. break;
  33. default:
  34. throw std::exception("Not supported client message!");
  35. break;
  36. }
  37. }
  38. }
  39. CGameHandler::CGameHandler(void)
  40. {
  41. gs = NULL;
  42. }
  43. CGameHandler::~CGameHandler(void)
  44. {
  45. delete gs;
  46. }
  47. void CGameHandler::init(StartInfo *si, int Seed)
  48. {
  49. Mapa *map = new Mapa(si->mapname);
  50. gs = new CGameState();
  51. gs->init(si,map,Seed);
  52. }
  53. int lowestSpeed(CGHeroInstance * chi)
  54. {
  55. std::map<int,std::pair<CCreature*,int> >::iterator i = chi->army.slots.begin();
  56. int ret = (*i++).second.first->speed;
  57. for (;i!=chi->army.slots.end();i++)
  58. {
  59. ret = min(ret,(*i).second.first->speed);
  60. }
  61. return ret;
  62. }
  63. int valMovePoints(CGHeroInstance * chi)
  64. {
  65. int ret = 1270+70*lowestSpeed(chi);
  66. if (ret>2000)
  67. ret=2000;
  68. //TODO: additional bonuses (but they aren't currently stored in chi)
  69. return ret;
  70. }
  71. void CGameHandler::newTurn()
  72. {
  73. //std::map<int, PlayerState>::iterator i = gs->players.begin() ;
  74. gs->day++;
  75. for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
  76. {
  77. //handle heroes/////////////////////////////
  78. for (unsigned j=0;j<(*i).second.heroes.size();j++)
  79. {
  80. (*i).second.heroes[j]->movement = valMovePoints((*i).second.heroes[j]);
  81. }
  82. //handle towns/////////////////////////////
  83. for(unsigned j=0;j<i->second.towns.size();j++)
  84. {
  85. i->second.towns[j]->builded=0;
  86. if(gs->getDate(1)==1) //first day of week
  87. {
  88. for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
  89. {
  90. if(i->second.towns[j]->creatureDwelling(k))//there is dwelling (k-level)
  91. i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k);
  92. }
  93. }
  94. if((gs->day>1) && i->first<PLAYER_LIMIT)
  95. i->second.resources[6]+=i->second.towns[j]->dailyIncome();
  96. }
  97. }
  98. for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
  99. {
  100. (*i)->newTurn();
  101. }
  102. }
  103. void CGameHandler::run()
  104. {
  105. BOOST_FOREACH(CConnection *cc, conns)
  106. {//init conn.
  107. ui8 quantity, pom;
  108. //ui32 seed;
  109. (*cc) << gs->scenarioOps->mapname << gs->map->checksum << gs->seed;
  110. (*cc) >> quantity;
  111. for(int i=0;i<quantity;i++)
  112. {
  113. (*cc) >> pom;
  114. gsm.lock();
  115. connections[pom] = cc;
  116. gsm.unlock();
  117. }
  118. }
  119. for(std::set<CConnection*>::iterator i = conns.begin(); i!=conns.end();i++)
  120. {
  121. std::set<int> pom;
  122. for(std::map<int,CConnection*>::iterator j = connections.begin(); j!=connections.end();j++)
  123. if(j->second == *i)
  124. pom.insert(j->first);
  125. boost::thread(boost::bind(&CGameHandler::handleConnection,this,pom,boost::ref(**i)));
  126. }
  127. while (1)
  128. {
  129. for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
  130. {
  131. if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser
  132. makingTurn = true;
  133. *connections[i->first] << ui16(100) << i->first;
  134. //wait till turn is done
  135. boost::unique_lock<boost::mutex> lock(mTurn);
  136. while(makingTurn)
  137. {
  138. cTurn.wait(lock);
  139. }
  140. }
  141. }
  142. }