1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-11-28 08:48:48 +02:00

* battle settings will be remembered between battles

* call-ins for serializing client and playerinterfaces (not used really yet)
This commit is contained in:
Michał W. Urbańczyk 2009-03-28 18:46:20 +00:00
parent 42773e67f2
commit fca28fab10
12 changed files with 166 additions and 47 deletions

View File

@ -33,6 +33,8 @@ extern SDL_Surface * screen;
extern TTF_Font * TNRB16, *TNR, *GEOR13, *GEORXX, *GEORM, *GEOR16;
extern SDL_Color zwykly;
BattleSettings CBattleInterface::settings;
struct CMP_stack2
{
inline bool operator ()(const CStack& a, const CStack& b)
@ -42,9 +44,9 @@ struct CMP_stack2
} cmpst2 ;
CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, CGHeroInstance *hero1, CGHeroInstance *hero2, const SDL_Rect & myRect)
: printCellBorders(true), attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL),
attackingInfo(NULL), myTurn(false), resWindow(NULL), showStackQueue(false), animSpeed(2), printStackRange(true),
printMouseShadow(true), spellDestSelectMode(false), spellToCast(NULL), previouslyHoveredHex(-1), moveStarted(false), mouseHoveredStack(-1)
: attackingHeroInstance(hero1), defendingHeroInstance(hero2), animCount(0), activeStack(-1), givenCommand(NULL),
attackingInfo(NULL), myTurn(false), resWindow(NULL), showStackQueue(false),
spellDestSelectMode(false), spellToCast(NULL), previouslyHoveredHex(-1), moveStarted(false), mouseHoveredStack(-1)
{
pos = myRect;
strongInterest = true;
@ -311,19 +313,19 @@ CBattleInterface::~CBattleInterface()
void CBattleInterface::setPrintCellBorders(bool set)
{
printCellBorders = set;
settings.printCellBorders = set;
redrawBackgroundWithHexes(activeStack);
}
void CBattleInterface::setPrintStackRange(bool set)
{
printStackRange = set;
settings.printStackRange = set;
redrawBackgroundWithHexes(activeStack);
}
void CBattleInterface::setPrintMouseShadow(bool set)
{
printMouseShadow = set;
settings.printMouseShadow = set;
}
void CBattleInterface::activate()
@ -392,7 +394,7 @@ void CBattleInterface::show(SDL_Surface * to)
{
//showing background
blitAt(background, pos.x, pos.y, to);
if(printCellBorders)
if(settings.printCellBorders)
{
CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, NULL, to, &pos);
}
@ -410,7 +412,7 @@ void CBattleInterface::show(SDL_Surface * to)
currentlyHoveredHex = b;
}
//print shade
if(printMouseShadow)
if(settings.printMouseShadow)
{
int x = 14 + ((b/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(b%BFIELD_WIDTH) + pos.x;
int y = 86 + 42 * (b/BFIELD_WIDTH) + pos.y;
@ -448,7 +450,7 @@ void CBattleInterface::show(SDL_Surface * to)
int x = ((obstacles[b].pos/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(obstacles[b].pos%BFIELD_WIDTH);
int y = 86 + 42 * (obstacles[b].pos/BFIELD_WIDTH);
std::vector<Cimage> &images = idToObstacle[obstacles[b].ID]->ourImages;
blitAt(images[((animCount+1)/(4/animSpeed))%images.size()].bitmap, x, y, to);
blitAt(images[((animCount+1)/(4/settings.animSpeed))%images.size()].bitmap, x, y, to);
}
//showing hero animations
@ -488,13 +490,13 @@ void CBattleInterface::show(SDL_Surface * to)
int curStackID = stackAliveByHex[b][v];
const CStack &curStack = stacks[curStackID];
int animType = creAnims[curStackID]->getType();
bool incrementFrame = (animCount%(4/animSpeed)==0) && animType!=5 && animType!=20 && animType!=3 && animType!=2;
bool incrementFrame = (animCount%(4/settings.animSpeed)==0) && animType!=5 && animType!=20 && animType!=3 && animType!=2;
if(animType == 2)
{
if(standingFrame.find(curStackID)!=standingFrame.end())
{
incrementFrame = (animCount%(8/animSpeed)==0);
incrementFrame = (animCount%(8/settings.animSpeed)==0);
if(incrementFrame)
{
++standingFrame[curStackID];
@ -934,7 +936,7 @@ void CBattleInterface::handleStartMoving(int number)
show();
CSDL_Ext::update();
SDL_framerateDelay(LOCPLINT->mainFPSmng);
if((animCount+1)%(4/animSpeed)==0)
if((animCount+1)%(4/settings.animSpeed)==0)
creAnims[number]->incrementFrame();
}
}
@ -1250,7 +1252,7 @@ void CBattleInterface::stacksAreAttacked(std::vector<CBattleInterface::SStackAtt
SDL_framerateDelay(LOCPLINT->mainFPSmng);
for(size_t g=0; g<attackedInfos.size(); ++g)
{
if((animCount+1)%(4/animSpeed)==0 && !creAnims[attackedInfos[g].ID]->onLastFrameInGroup())
if((animCount+1)%(4/settings.animSpeed)==0 && !creAnims[attackedInfos[g].ID]->onLastFrameInGroup())
{
creAnims[attackedInfos[g].ID]->incrementFrame();
}
@ -1851,17 +1853,17 @@ void CBattleInterface::displayEffect(ui32 effect, int destTile)
void CBattleInterface::setAnimSpeed(int set)
{
animSpeed = set;
settings.animSpeed = set;
}
int CBattleInterface::getAnimSpeed() const
{
return animSpeed;
return settings.animSpeed;
}
float CBattleInterface::getAnimSpeedMultiplier() const
{
switch(animSpeed)
switch(settings.animSpeed)
{
case 1:
return 3.5f;
@ -2059,7 +2061,7 @@ void CBattleInterface::attackingShowHelper()
if(attackingInfo)
{
attackingInfo->hitCount++;
if(attackingInfo->hitCount%(4/animSpeed) == 0)
if(attackingInfo->hitCount%(4/settings.animSpeed) == 0)
attackingInfo->frame++;
}
}
@ -2071,10 +2073,10 @@ void CBattleInterface::redrawBackgroundWithHexes(int activeStack)
//preparating background graphic with hexes and shaded hexes
blitAt(background, 0, 0, backgroundWithHexes);
if(printCellBorders)
if(settings.printCellBorders)
CSDL_Ext::blit8bppAlphaTo24bpp(cellBorders, NULL, backgroundWithHexes, NULL);
if(printStackRange)
if(settings.printStackRange)
{
for(size_t m=0; m<shadedHexes.size(); ++m) //rows
{
@ -2688,11 +2690,11 @@ CBattleOptionsWindow::CBattleOptionsWindow(const SDL_Rect & position, CBattleInt
graphics->blueToPlayersAdv(background, LOCPLINT->playerID);
viewGrid = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintCellBorders, owner, true), boost::bind(&CBattleInterface::setPrintCellBorders, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[427].first)(3,CGI->generaltexth->zelp[427].first), CGI->generaltexth->zelp[427].second, false, "sysopchk.def", NULL, 185, 140, false);
viewGrid->select(owner->printCellBorders);
viewGrid->select(owner->settings.printCellBorders);
movementShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintStackRange, owner, true), boost::bind(&CBattleInterface::setPrintStackRange, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[428].first)(3,CGI->generaltexth->zelp[428].first), CGI->generaltexth->zelp[428].second, false, "sysopchk.def", NULL, 185, 173, false);
movementShadow->select(owner->printStackRange);
movementShadow->select(owner->settings.printStackRange);
mouseShadow = new CHighlightableButton(boost::bind(&CBattleInterface::setPrintMouseShadow, owner, true), boost::bind(&CBattleInterface::setPrintMouseShadow, owner, false), boost::assign::map_list_of(0,CGI->generaltexth->zelp[429].first)(3,CGI->generaltexth->zelp[429].first), CGI->generaltexth->zelp[429].second, false, "sysopchk.def", NULL, 185, 207, false);
mouseShadow->select(owner->printMouseShadow);
mouseShadow->select(owner->settings.printMouseShadow);
animSpeeds = new CHighlightableButtonsGroup(0);
animSpeeds->addButton(boost::assign::map_list_of(0,CGI->generaltexth->zelp[422].first),CGI->generaltexth->zelp[422].second, "sysopb9.def",188, 309, 1);

View File

@ -119,6 +119,27 @@ public:
void show(SDL_Surface * to = 0);
};
struct BattleSettings
{
BattleSettings()
{
printCellBorders = true;
printStackRange = true;
animSpeed = 2;
printMouseShadow = true;
}
bool printCellBorders; //if true, cell borders will be printed
bool printStackRange; //if true,range of active stack will be printed
int animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
bool printMouseShadow; //if true, hex under mouse will be shaded
template <typename Handler> void serialize(Handler &h, const int version)
{
h & printCellBorders & printStackRange & printMouseShadow;
}
};
class CBattleInterface : public CMainInterface, public MotionInterested, public KeyInterested
{
private:
@ -140,7 +161,6 @@ private:
std::vector<int> shadedHexes; //hexes available for active stack
int previouslyHoveredHex; //number of hex that was hovered by the cursor a while ago
int currentlyHoveredHex; //number of hex that is supposed to be hovered (for a while it may be inappropriately set, but will be renewed soon)
int animSpeed; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
float getAnimSpeedMultiplier() const; //returns multiplier for number of frames in a group
std::map<int, int> standingFrame; //number of frame in standing animation by stack ID, helps in showing 'random moves'
@ -193,14 +213,12 @@ public:
~CBattleInterface(); //d-tor
//std::vector<TimeInterested*> timeinterested; //animation handling
bool printCellBorders; //if true, cell borders will be printed
void setPrintCellBorders(bool set); //set for above member
bool printStackRange; //if true,range of active stack will be printed
void setPrintStackRange(bool set); //set for above member
bool printMouseShadow; //if true, hex under mouse will be shaded
void setPrintMouseShadow(bool set); //set for above member
void setAnimSpeed(int set); //set for animSpeed
int getAnimSpeed() const; //get for animSpeed
static BattleSettings settings;
void setPrintCellBorders(bool set); //if true, cell borders will be printed
void setPrintStackRange(bool set); //if true,range of active stack will be printed
void setPrintMouseShadow(bool set); //if true, hex under mouse will be shaded
void setAnimSpeed(int set); //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
int getAnimSpeed() const; //speed of animation; 1 - slowest, 2 - medium, 4 - fastest
CBattleHex bfield[BFIELD_SIZE]; //11 lines, 17 hexes on each
std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield

View File

@ -29,11 +29,14 @@ CGlobalAI * CAIHandler::getNewAI(CCallback * cb, std::string dllname)
void *dll = dlopen(dllname.c_str(), RTLD_LOCAL | RTLD_LAZY);
getName = (void(*)(char*))dlsym(dll,"GetAiName");
getAI = (CGlobalAI*(*)())dlsym(dll,"GetNewAI");
; //TODO: handle AI library on Linux
#endif
getName(temp);
tlog0 << "Loaded .dll with AI named " << temp << std::endl;
ret = getAI();
if(!ret)
tlog1 << "Cannot get AI!\n";
ret->dllName = dllname;
return ret;
}

View File

@ -25,6 +25,11 @@ struct BattleStackAttacked;
struct SpellCasted;
struct SetStackEffect;
struct HeroBonus;
class CLoadFile;
class CSaveFile;
template <typename Serializer> class CISer;
template <typename Serializer> class COSer;
class CObstacle
{
int ID;
@ -47,6 +52,7 @@ class CGameInterface
public:
bool human;
int playerID, serialID;
std::string dllName;
virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished
virtual void garrisonChanged(const CGObjectInstance * obj){};
@ -70,6 +76,8 @@ public:
virtual void yourTurn(){};
virtual void availableCreaturesChanged(const CGTownInstance *town){};
virtual void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain){};//if gain hero received bonus, else he lost it
virtual void serialize(COSer<CSaveFile> &h, const int version){}; //saving
virtual void serialize(CISer<CLoadFile> &h, const int version){}; //loading
//battle call-ins
virtual void actionFinished(const BattleAction *action){};//occurs AFTER every action taken by any stack or by the hero

View File

@ -21,6 +21,7 @@
#include "hch/CHeroHandler.h"
#include "hch/CLodHandler.h"
#include "hch/CObjectHandler.h"
#include "lib/Connection.h"
#include "hch/CSpellHandler.h"
#include "hch/CTownHandler.h"
#include "lib/CondSh.h"
@ -2526,6 +2527,23 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const HeroB
redrawHeroWin(hero);
}
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
{
h & playerID & serialID;
h & heroMoveSpeed & mapScrollingSpeed;
h & CBattleInterface::settings;
}
void CPlayerInterface::serialize( COSer<CSaveFile> &h, const int version )
{
serializeTempl(h,version);
}
void CPlayerInterface::serialize( CISer<CLoadFile> &h, const int version )
{
serializeTempl(h,version);
}
void CPlayerInterface::redrawHeroWin(const CGHeroInstance * hero)
{
if(!vstd::contains(graphics->heroWins,hero->subID))

View File

@ -546,6 +546,9 @@ public:
void yourTurn();
void availableCreaturesChanged(const CGTownInstance *town);
void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain);//if gain hero received bonus, else he lost it
void serialize(COSer<CSaveFile> &h, const int version); //saving
void serialize(CISer<CLoadFile> &h, const int version); //loading
//for battles
void actionFinished(const BattleAction* action);//occurs AFTER action taken by active stack or by the hero
void actionStarted(const BattleAction* action);//occurs BEFORE action taken by active stack or by the hero
@ -583,7 +586,12 @@ public:
CPlayerInterface(int Player, int serial);//c-tor
~CPlayerInterface();//d-tor
//////////////////////////////////////////////////////////////////////////
template <typename Handler> void serializeTempl(Handler &h, const int version);
};
class CStatusBar
: public CIntObject, public IStatusBar
{

View File

@ -342,3 +342,42 @@ void CClient::waitForServer()
shared->sr->cond.wait(slock);
}
}
template <typename Handler>
void CClient::serialize( Handler &h, const int version )
{
if(h.saving)
{
ui8 players = playerint.size();
h & players;
for(std::map<ui8,CGameInterface *>::iterator i = playerint.begin(); i != playerint.end(); i++)
{
h & i->first & i->second->dllName;
i->second->serialize(h,version);
}
}
else
{
ui8 players;
h & players;
for(int i=0; i < players; i++)
{
std::string dllname;
ui8 pid;
h & pid & dllname;
if(dllname.length())
{
CCallback *callback = new CCallback(gs,pid,this);
callbacks.insert(callback);
playerint[pid] = CAIHandler::getNewAI(callback,dllname);
playerint[pid]->init(callback);
}
}
}
}
template void CClient::serialize( CISer<CLoadFile> &h, const int version );
template void CClient::serialize( COSer<CSaveFile> &h, const int version );

View File

@ -5,6 +5,7 @@
#include "../global.h"
#include <boost/thread.hpp>
#include "../lib/IGameCallback.h"
struct StartInfo;
class CGameState;
class CGameInterface;
@ -44,6 +45,7 @@ class CClient : public IGameCallback
{
public:
CCallback *cb;
std::set<CCallback*> callbacks; //callbacks given to player interfaces
std::map<ui8,CGameInterface *> playerint;
CConnection *serv;
SharedMem *shared;
@ -100,6 +102,10 @@ public:
static void runServer(const char * portc);
void waitForServer();
//////////////////////////////////////////////////////////////////////////
template <typename Handler> void serialize(Handler &h, const int version);
};
#endif // __CLIENT_H__

View File

@ -3,6 +3,7 @@
#include "../client/Client.h"
#include "../CPlayerInterface.h"
#include "../CGameInfo.h"
#include "../lib/Connection.h"
#include "../hch/CGeneralTextHandler.h"
#include "../hch/CDefObjInfoHandler.h"
#include "../hch/CHeroHandler.h"
@ -411,6 +412,11 @@ void YourTurn::applyCl( CClient *cl )
boost::thread(boost::bind(&CGameInterface::yourTurn,cl->playerint[player]));
}
void SaveGame::applyCl(CClient *cl)
{
CSaveFile save("Games" PATHSEPARATOR + fname + ".vcgm1");
save << *cl;
}
void PlayerMessage::applyCl(CClient *cl)
{

View File

@ -794,19 +794,6 @@ struct ShowInInfobox : public CPackForClient //107
/***********************************************************************************************************/
struct SaveGame : public CPackForServer
{
SaveGame(){};
SaveGame(const std::string &Fname) :fname(Fname){};
std::string fname;
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & fname;
}
};
struct CloseServer : public CPackForServer
{
void applyGh(CGameHandler *gh);
@ -1048,6 +1035,21 @@ struct MakeCustomAction : public CPackForServer
/***********************************************************************************************************/
struct SaveGame : public CPackForClient, public CPackForServer
{
SaveGame(){};
SaveGame(const std::string &Fname) :fname(Fname){};
std::string fname;
void applyCl(CClient *cl);
void applyGs(CGameState *gs){};
void applyGh(CGameHandler *gh);
template <typename Handler> void serialize(Handler &h, const int version)
{
h & fname;
}
};
struct PlayerMessage : public CPackForClient, public CPackForServer //513
{
PlayerMessage(){CPackForClient::type = 513;};

View File

@ -82,6 +82,7 @@ void registerTypes2(Serializer &s)
s.template registerType<SetStackEffect>();
s.template registerType<ShowInInfobox>();
s.template registerType<SaveGame>();
s.template registerType<SetSelection>();
s.template registerType<PlayerMessage>();
}
@ -89,7 +90,6 @@ void registerTypes2(Serializer &s)
template<typename Serializer> DLL_EXPORT
void registerTypes3(Serializer &s)
{
s.template registerType<SaveGame>();
s.template registerType<CloseServer>();
s.template registerType<EndTurn>();
s.template registerType<DismissHero>();
@ -109,6 +109,7 @@ void registerTypes3(Serializer &s)
s.template registerType<MakeAction>();
s.template registerType<MakeCustomAction>();
s.template registerType<SaveGame>();
s.template registerType<SetSelection>();
s.template registerType<PlayerMessage>();
}

View File

@ -1466,6 +1466,14 @@ void CGameHandler::sendAndApply( CPackForClient * info )
void CGameHandler::save( const std::string &fname )
{
{
tlog0 << "Ordering clients to serialize...\n";
SaveGame sg(fname);
//TODO: uncomment when client saving is ready
//sendToAllClients(&sg);
}
{
tlog0 << "Serializing game info...\n";
CSaveFile save(std::string("Games") + PATHSEPARATOR + fname + ".vlgm1");