1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +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 "CCallback.h"
#include "CLuaHandler.h"
#include "lib/NetPacks.h"
#include <boost/foreach.hpp>
boost::rand48 ran;
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)
{
}
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 h=-1;
@ -279,6 +304,7 @@ int CGameState::getDate(int mode) const
}
void CGameState::init(StartInfo * si, Mapa * map, int Seed)
{
day = 0;
seed = Seed;
ran.seed((long)seed);
scenarioOps = si;

View File

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

View File

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

View File

@ -2,6 +2,7 @@
#pragma warning(disable:4355)
#include "Connection.h"
#include <boost/asio.hpp>
#include <boost/thread.hpp>
using namespace boost;
using namespace boost::asio::ip;
@ -31,6 +32,8 @@ void CConnection::init()
(*this) << std::string("Aiya!\n") << name << myEndianess; //identify ourselves
(*this) >> pom >> pom >> contactEndianess;
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)
@ -63,14 +66,14 @@ CConnection::CConnection(boost::asio::basic_socket_acceptor<boost::asio::ip::tcp
}
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;
ret = asio::write(*socket,asio::const_buffers_1(asio::const_buffer(data,size)));
return ret;
}
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)));
return ret;
}
@ -80,4 +83,6 @@ CConnection::~CConnection(void)
socket->close();
delete socket;
delete io_service;
delete wmx;
delete rmx;
}

View File

@ -60,7 +60,7 @@ struct SerializationLevel
//else
typename mpl::eval_if<
boost::is_array<T>,
mpl::int_<Wrong>,
mpl::int_<Primitive>,
//else
typename mpl::eval_if<
boost::is_enum<T>,
@ -91,7 +91,7 @@ public:
}
template<class T>
Serializer & operator&(T & t){
COSer & operator&(T & t){
return * this->This() << t;
}
};
@ -112,7 +112,7 @@ public:
}
template<class T>
Serializer & operator&(T & t){
CISer & operator&(T & t){
return * this->This() >> t;
}
};
@ -176,7 +176,7 @@ class DLL_EXPORT CConnection
std::ostream &out;
CConnection(void);
void init();
boost::mutex *mx;
boost::mutex *rmx, *wmx; // read/write mutexes
public:
template <typename T>
@ -234,9 +234,10 @@ public:
template <typename T>
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;
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;
}
template <typename T>
@ -244,7 +245,6 @@ public:
{
boost::uint32_t length;
*this >> length;
data.resize(length);
T ins;
for(ui32 i=0;i<length;i++)
{
@ -287,8 +287,6 @@ public:
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;
bool logging;
bool connected;

View File

@ -1,14 +1,25 @@
#include "../global.h"
struct NewTurn
struct IPack
{
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
{
ui32 id, move, mana; //id is a general serial id
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
{
@ -16,17 +27,20 @@ struct NewTurn
si32 resources[RESOURCE_QUANTITY];
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<Resources> res;
std::set<Hero> heroes; //updates movement and mana points
std::set<Resources> res;//resource list
ui32 day;
bool resetBuilded;
NewTurn(){type = 101;};
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)
{
gs = NULL;
@ -76,37 +80,46 @@ int valMovePoints(CGHeroInstance * chi)
}
void CGameHandler::newTurn()
{
//std::map<int, PlayerState>::iterator i = gs->players.begin() ;
gs->day++;
NewTurn n;
n.day = gs->day + 1;
for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
{
//handle heroes/////////////////////////////
for (unsigned j=0;j<(*i).second.heroes.size();j++)
if(i->first>=PLAYER_LIMIT) continue;
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);
}
//handle towns/////////////////////////////
for(unsigned j=0;j<i->second.towns.size();j++)
for(unsigned j=0;j<i->second.towns.size();j++)//handle towns
{
i->second.towns[j]->builded=0;
if(gs->getDate(1)==1) //first day of week
{
for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
{
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);
}
}
if((gs->day>1) && i->first<PLAYER_LIMIT)
i->second.resources[6]+=i->second.towns[j]->dailyIncome();
//if(gs->getDate(1)==1) //first day of week
//{
// for(int k=0;k<CREATURES_PER_TOWN;k++) //creature growths
// {
// 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);
// }
//}
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);
}
for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
{
(*i)->newTurn();
}
sendToAllClients(&n);
//for (std::set<CCPPObjectScript *>::iterator i=gs->cppscripts.begin();i!=gs->cppscripts.end();i++)
//{
// (*i)->newTurn();
//}
}
void CGameHandler::run()
{
@ -136,6 +149,7 @@ void CGameHandler::run()
}
while (1)
{
newTurn();
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

View File

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