1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Proper initialization of the first turn.

This commit is contained in:
Michał W. Urbańczyk
2008-07-26 13:57:32 +00:00
parent 88c9d8d72d
commit b3c5f19c0d
8 changed files with 125 additions and 49 deletions

View File

@@ -20,7 +20,8 @@
#include "CLua.h" #include "CLua.h"
#include "CCallback.h" #include "CCallback.h"
#include "CLuaHandler.h" #include "CLuaHandler.h"
#include "lib/NetPacks.h"
#include <boost/foreach.hpp>
boost::rand48 ran; boost::rand48 ran;
class CMP_stack class CMP_stack
@@ -36,6 +37,30 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO)
:creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints) :creature(C),amount(A),owner(O), alive(true), position(-1), ID(I), attackerOwned(AO), firstHPleft(C->hitPoints)
{ {
} }
void CGameState::apply(IPack * pack)
{
switch(pack->getType())
{
case 101://NewTurn
{
NewTurn * n = static_cast<NewTurn*>(pack);
day = n->day;
BOOST_FOREACH(NewTurn::Hero h, n->heroes) //give mana/movement point
{
static_cast<CGHeroInstance*>(map->objects[h.id])->movement = h.move;
static_cast<CGHeroInstance*>(map->objects[h.id])->mana = h.mana;
}
BOOST_FOREACH(NewTurn::Resources h, n->res) //give resources
{
for(int i=0;i<RESOURCE_QUANTITY;i++)
players[h.player].resources[i] = h.resources[i];
}
if(n->resetBuilded) //reset amount of structures set in this turn in towns
BOOST_FOREACH(CGTownInstance* t, map->towns)
t->builded = 0;
}
}
}
int CGameState::pickHero(int owner) int CGameState::pickHero(int owner)
{ {
int h=-1; int h=-1;
@@ -279,6 +304,7 @@ int CGameState::getDate(int mode) const
} }
void CGameState::init(StartInfo * si, Mapa * map, int Seed) void CGameState::init(StartInfo * si, Mapa * map, int Seed)
{ {
day = 0;
seed = Seed; seed = Seed;
ran.seed((long)seed); ran.seed((long)seed);
scenarioOps = si; scenarioOps = si;

View File

@@ -23,6 +23,7 @@ struct StartInfo;
struct SDL_Surface; struct SDL_Surface;
class CMapHandler; class CMapHandler;
class CPathfinder; class CPathfinder;
struct IPack;
struct DLL_EXPORT PlayerState struct DLL_EXPORT PlayerState
{ {
@@ -90,6 +91,7 @@ private:
} }
void init(StartInfo * si, Mapa * map, int Seed); void init(StartInfo * si, Mapa * map, int Seed);
void apply(IPack * pack);
void randomizeObject(CGObjectInstance *cur); void randomizeObject(CGObjectInstance *cur);
std::pair<int,int> pickObject(CGObjectInstance *obj); std::pair<int,int> pickObject(CGObjectInstance *obj);
int pickHero(int owner); int pickHero(int owner);

View File

@@ -8,6 +8,7 @@
#include "../CCallback.h" #include "../CCallback.h"
#include "../CPlayerInterface.h" #include "../CPlayerInterface.h"
#include "../CConsoleHandler.h" #include "../CConsoleHandler.h"
#include "../lib/NetPacks.h"
CClient::CClient(void) CClient::CClient(void)
{ {
@@ -74,11 +75,24 @@ void CClient::process(int what)
switch (what) switch (what)
{ {
case 100: //one of our interaces has turn case 100: //one of our interaces has turn
{
ui8 player; ui8 player;
*serv >> player;//who? *serv >> player;//who?
std::cout << "It's turn of "<<(unsigned)player<<" player."<<std::endl;
CGI->playerint[gs->players[player].serial]->yourTurn(); CGI->playerint[gs->players[player].serial]->yourTurn();
*serv << ui16(100); //report that we ended turn *serv << ui16(100); //report that we ended turn
std::cout << "Player "<<(unsigned)player<<" end his turn."<<std::endl;
break; break;
}
case 101:
{
NewTurn n;
*serv >> n;
std::cout << "New day: "<<(unsigned)n.day<<". Applying changes... ";
gs->apply(&n);
std::cout << "done!"<<std::endl;
break;
}
default: default:
throw std::exception("Not supported server message!"); throw std::exception("Not supported server message!");
break; break;

View File

@@ -2,6 +2,7 @@
#pragma warning(disable:4355) #pragma warning(disable:4355)
#include "Connection.h" #include "Connection.h"
#include <boost/asio.hpp> #include <boost/asio.hpp>
#include <boost/thread.hpp>
using namespace boost; using namespace boost;
using namespace boost::asio::ip; using namespace boost::asio::ip;
@@ -31,6 +32,8 @@ void CConnection::init()
(*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves (*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves
(*this) >> pom >> pom >> contactEndianess; (*this) >> pom >> pom >> contactEndianess;
out << "Established connection with "<<pom<<std::endl; out << "Established connection with "<<pom<<std::endl;
wmx = new boost::mutex;
rmx = new boost::mutex;
} }
CConnection::CConnection(std::string host, std::string port, std::string Name, std::ostream & Out) CConnection::CConnection(std::string host, std::string port, std::string Name, std::ostream & Out)
@@ -63,14 +66,14 @@ CConnection::CConnection(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp
} }
int CConnection::write(const void * data, unsigned size) int CConnection::write(const void * data, unsigned size)
{ {
LOG("wysylam dane o rozmiarze " << size << std::endl); LOG("Sending " << size << " byte(s) of data" <<std::endl);
int ret; int ret;
ret = asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size))); ret = asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size)));
return ret; return ret;
} }
int CConnection::read(void * data, unsigned size) int CConnection::read(void * data, unsigned size)
{ {
LOG("odbieram dane o rozmiarze " << size << std::endl); LOG("Receiving " << size << " byte(s) of data" <<std::endl);
int ret = asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size))); int ret = asio::read(*socket,asio::mutable_buffers_1(asio::mutable_buffer(data,size)));
return ret; return ret;
} }
@@ -80,4 +83,6 @@ CConnection::~CConnection(void)
socket->close(); socket->close();
delete socket; delete socket;
delete io_service; delete io_service;
delete wmx;
delete rmx;
} }

View File

@@ -60,7 +60,7 @@ struct SerializationLevel
//else //else
typename mpl::eval_if< typename mpl::eval_if<
boost::is_array<T>, boost::is_array<T>,
mpl::int_<Wrong>, mpl::int_<Primitive>,
//else //else
typename mpl::eval_if< typename mpl::eval_if<
boost::is_enum<T>, boost::is_enum<T>,
@@ -91,7 +91,7 @@ public:
} }
template<class T> template<class T>
Serializer & operator&(T & t){ COSer & operator&(T & t){
return * this->This() << t; return * this->This() << t;
} }
}; };
@@ -112,7 +112,7 @@ public:
} }
template<class T> template<class T>
Serializer & operator&(T & t){ CISer & operator&(T & t){
return * this->This() >> t; return * this->This() >> t;
} }
}; };
@@ -176,7 +176,7 @@ class DLL_EXPORT CConnection
std::ostream &out; std::ostream &out;
CConnection(void); CConnection(void);
void init(); void init();
boost::mutex *mx; boost::mutex *rmx, *wmx; // read/write mutexes
public: public:
template <typename T> template <typename T>
@@ -234,9 +234,10 @@ public:
template <typename T> template <typename T>
void saveSerializable(const std::set<T> &data) void saveSerializable(const std::set<T> &data)
{ {
boost::uint32_t length = data.size(); std::set<T> &d = const_cast<std::set<T> &>(data);
boost::uint32_t length = d.size();
*this << length; *this << length;
for(std::set<T>::iterator i=data.begin();i!=data.end();i++) for(std::set<T>::iterator i=d.begin();i!=d.end();i++)
*this << *i; *this << *i;
} }
template <typename T> template <typename T>
@@ -244,7 +245,6 @@ public:
{ {
boost::uint32_t length; boost::uint32_t length;
*this >> length; *this >> length;
data.resize(length);
T ins; T ins;
for(ui32 i=0;i<length;i++) for(ui32 i=0;i<length;i++)
{ {
@@ -287,8 +287,6 @@ public:
typex::invoke(*this, data); typex::invoke(*this, data);
} }
//CSender send;
//CReceiver rec;
boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * socket; boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * socket;
bool logging; bool logging;
bool connected; bool connected;

View File

@@ -1,14 +1,25 @@
#include "../global.h" #include "../global.h"
struct IPack
struct NewTurn {
virtual ui16 getType()=0;
};
template <typename T> struct CPack
:public IPack
{
ui16 type;
ui16 getType(){return type;}
T* This(){return static_cast<T*>(this);};
};
struct NewTurn : public CPack<NewTurn> //101
{ {
struct Hero struct Hero
{ {
ui32 id, move, mana; //id is a general serial id ui32 id, move, mana; //id is a general serial id
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h -= id -= move -= mana; h & id & move & mana;
} }
bool operator<(const Hero&h)const{return id < h.id;}
}; };
struct Resources struct Resources
{ {
@@ -16,17 +27,20 @@ struct NewTurn
si32 resources[RESOURCE_QUANTITY]; si32 resources[RESOURCE_QUANTITY];
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h -= resources; h & player & resources;
} }
bool operator<(const Resources&h)const{return player < h.player;}
}; };
std::set<Hero> heroes; std::set<Hero> heroes; //updates movement and mana points
std::set<Resources> res; std::set<Resources> res;//resource list
ui32 day;
bool resetBuilded;
NewTurn(){type = 101;};
template <typename Handler> void serialize(Handler &h, const int version) template <typename Handler> void serialize(Handler &h, const int version)
{ {
h += heroes += res; h & heroes & res & day & resetBuilded;
} }
}; };

View File

@@ -38,7 +38,11 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
} }
} }
} }
template <typename T>void CGameHandler::sendToAllClients(CPack<T> * info)
{
BOOST_FOREACH(CConnection* c, conns)
*c << info->getType() << *info->This();
}
CGameHandler::CGameHandler(void) CGameHandler::CGameHandler(void)
{ {
gs = NULL; gs = NULL;
@@ -76,37 +80,46 @@ int valMovePoints(CGHeroInstance * chi)
} }
void CGameHandler::newTurn() void CGameHandler::newTurn()
{ {
//std::map<int, PlayerState>::iterator i = gs->players.begin() ; NewTurn n;
gs->day++; n.day = gs->day + 1;
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++) for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
{ {
//handle heroes///////////////////////////// if(i->first>=PLAYER_LIMIT) continue;
for (unsigned j=0;j<(*i).second.heroes.size();j++) NewTurn::Resources r;
r.player = i->first;
for(int j=0;j<RESOURCE_QUANTITY;j++)
r.resources[j] = i->second.resources[j];
for (unsigned j=0;j<(*i).second.heroes.size();j++) //handle heroes
{ {
(*i).second.heroes[j]->movement = valMovePoints((*i).second.heroes[j]); NewTurn::Hero h;
h.id = (*i).second.heroes[j]->id;
h.move = valMovePoints((*i).second.heroes[j]);
h.mana = (*i).second.heroes[j]->mana;
n.heroes.insert(h);
} }
for(unsigned j=0;j<i->second.towns.size();j++)//handle towns
//handle towns/////////////////////////////
for(unsigned j=0;j<i->second.towns.size();j++)
{ {
i->second.towns[j]->builded=0; i->second.towns[j]->builded=0;
if(gs->getDate(1)==1) //first day of week //if(gs->getDate(1)==1) //first day of week
{ //{
for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths // for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
{ // {
if(i->second.towns[j]->creatureDwelling(k))//there is dwelling (k-level) // if(i->second.towns[j]->creatureDwelling(k))//there is dwelling (k-level)
i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k); // i->second.towns[j]->strInfo.creatures[k]+=i->second.towns[j]->creatureGrowth(k);
// }
//}
if((gs->day>1) && i->first<PLAYER_LIMIT)//not the first day and town not neutral
r.resources[6] += i->second.towns[j]->dailyIncome();
} }
n.res.insert(r);
} }
if((gs->day>1) && i->first<PLAYER_LIMIT) sendToAllClients(&n);
i->second.resources[6]+=i->second.towns[j]->dailyIncome(); //for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
} //{
} // (*i)->newTurn();
for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++) //}
{
(*i)->newTurn();
}
} }
void CGameHandler::run() void CGameHandler::run()
{ {
@@ -136,6 +149,7 @@ void CGameHandler::run()
} }
while (1) while (1)
{ {
newTurn();
for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++) for(std::map<ui8,PlayerState>::iterator i = gs->players.begin(); i != gs->players.end(); i++)
{ {
if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser if((i->second.towns.size()==0 && i->second.heroes.size()==0) || i->second.color<0) continue; //players has not towns/castle - loser

View File

@@ -5,6 +5,8 @@ class CVCMIServer;
class CGameState; class CGameState;
class CConnection; class CConnection;
struct StartInfo; struct StartInfo;
template <typename T> struct CPack;
class CGameHandler class CGameHandler
{ {
CGameState *gs; CGameState *gs;
@@ -16,6 +18,7 @@ public:
~CGameHandler(void); ~CGameHandler(void);
void init(StartInfo *si, int Seed); void init(StartInfo *si, int Seed);
void handleConnection(std::set<int> players, CConnection &c); void handleConnection(std::set<int> players, CConnection &c);
template <typename T>void sendToAllClients(CPack<T> * info);
void run(); void run();
void newTurn(); void newTurn();