CGameHandler.cpp 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. template <typename T>void CGameHandler::sendToAllClients(CPack<T> * info)
  40. {
  41. BOOST_FOREACH(CConnection* c, conns)
  42. *c << info->getType() << *info->This();
  43. }
  44. CGameHandler::CGameHandler(void)
  45. {
  46. gs = NULL;
  47. }
  48. CGameHandler::~CGameHandler(void)
  49. {
  50. delete gs;
  51. }
  52. void CGameHandler::init(StartInfo *si, int Seed)
  53. {
  54. Mapa *map = new Mapa(si->mapname);
  55. gs = new CGameState();
  56. gs->init(si,map,Seed);
  57. }
  58. int lowestSpeed(CGHeroInstance * chi)
  59. {
  60. std::map<int,std::pair<CCreature*,int> >::iterator i = chi->army.slots.begin();
  61. int ret = (*i++).second.first->speed;
  62. for (;i!=chi->army.slots.end();i++)
  63. {
  64. ret = min(ret,(*i).second.first->speed);
  65. }
  66. return ret;
  67. }
  68. int valMovePoints(CGHeroInstance * chi)
  69. {
  70. int ret = 1270+70*lowestSpeed(chi);
  71. if (ret>2000)
  72. ret=2000;
  73. //TODO: additional bonuses (but they aren't currently stored in chi)
  74. return ret;
  75. }
  76. void CGameHandler::newTurn()
  77. {
  78. NewTurn n;
  79. n.day = gs->day + 1;
  80. for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
  81. {
  82. if(i->first>=PLAYER_LIMIT) continue;
  83. NewTurn::Resources r;
  84. r.player = i->first;
  85. for(int j=0;j<RESOURCE_QUANTITY;j++)
  86. r.resources[j] = i->second.resources[j];
  87. for (unsigned j=0;j<(*i).second.heroes.size();j++) //handle heroes
  88. {
  89. NewTurn::Hero h;
  90. h.id = (*i).second.heroes[j]->id;
  91. h.move = valMovePoints((*i).second.heroes[j]);
  92. h.mana = (*i).second.heroes[j]->mana;
  93. n.heroes.insert(h);
  94. }
  95. for(unsigned j=0;j<i->second.towns.size();j++)//handle towns
  96. {
  97. i->second.towns[j]->builded=0;
  98. //if(gs->getDate(1)==1) //first day of week
  99. //{
  100. // for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
  101. // {
  102. // if(i->second.towns[j]->creatureDwelling(k))//there is dwelling (k-level)
  103. // i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k);
  104. // }
  105. //}
  106. if((gs->day>1) && i->first<PLAYER_LIMIT)//not the first day and town not neutral
  107. r.resources[6] += i->second.towns[j]->dailyIncome();
  108. }
  109. n.res.insert(r);
  110. }
  111. sendToAllClients(&n);
  112. //for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
  113. //{
  114. // (*i)->newTurn();
  115. //}
  116. }
  117. void CGameHandler::run()
  118. {
  119. BOOST_FOREACH(CConnection *cc, conns)
  120. {//init conn.
  121. ui8 quantity, pom;
  122. //ui32 seed;
  123. (*cc) << gs->scenarioOps->mapname << gs->map->checksum << gs->seed;
  124. (*cc) >> quantity;
  125. for(int i=0;i<quantity;i++)
  126. {
  127. (*cc) >> pom;
  128. gsm.lock();
  129. connections[pom] = cc;
  130. gsm.unlock();
  131. }
  132. }
  133. for(std::set<CConnection*>::iterator i = conns.begin(); i!=conns.end();i++)
  134. {
  135. std::set<int> pom;
  136. for(std::map<int,CConnection*>::iterator j = connections.begin(); j!=connections.end();j++)
  137. if(j->second == *i)
  138. pom.insert(j->first);
  139. boost::thread(boost::bind(&CGameHandler::handleConnection,this,pom,boost::ref(**i)));
  140. }
  141. while (1)
  142. {
  143. newTurn();
  144. for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
  145. {
  146. if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser
  147. makingTurn = true;
  148. *connections[i->first] << ui16(100) << i->first;
  149. //wait till turn is done
  150. boost::unique_lock<boost::mutex> lock(mTurn);
  151. while(makingTurn)
  152. {
  153. cTurn.wait(lock);
  154. }
  155. }
  156. }
  157. }