1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

* upgrading creatures

* splitted map loading on several functions
* buttons can call multiple functions when pressed
* minor
This commit is contained in:
Michał W. Urbańczyk 2008-08-15 12:11:42 +00:00
parent 52f6de2877
commit b83b80a71e
19 changed files with 1396 additions and 1196 deletions

View File

@ -16,54 +16,13 @@ AdventureMapButton::AdventureMapButton ()
state=0;
actOnDown = false;
}
AdventureMapButton::AdventureMapButton
( std::string Name, std::string HelpBox, boost::function<void()> Callback, int x, int y, std::string defName, bool activ, std::vector<std::string> * add, bool playerColoredButton )
AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, boost::function<void()> Callback, int x, int y, std::string defName, bool activ, std::vector<std::string> * add, bool playerColoredButton)
{
callback = Callback;
actOnDown = false;
type=2;
abs=true;
active=false;
ourObj=NULL;
state=0;
name=Name;
helpBox=HelpBox;
colorChange = playerColoredButton;
int est = LOCPLINT->playerID;
CDefHandler * temp = CDefHandler::giveDef(defName);
temp->notFreeImgs = true;
for (int i=0;i<temp->ourImages.size();i++)
{
imgs.resize(1);
imgs[0].push_back(temp->ourImages[i].bitmap);
if(playerColoredButton)
graphics->blueToPlayersAdv(imgs[curimg][i],LOCPLINT->playerID);
}
delete temp;
if (add)
{
imgs.resize(imgs.size()+add->size());
for (int i=0; i<add->size();i++)
{
temp = CDefHandler::giveDef((*add)[i]);
temp->notFreeImgs = true;
for (int j=0;j<temp->ourImages.size();j++)
{
imgs[i+1].push_back(temp->ourImages[j].bitmap);
if(playerColoredButton)
graphics->blueToPlayersAdv(imgs[1+i][j],LOCPLINT->playerID);
}
delete temp;
}
delete add;
}
pos.x=x;
pos.y=y;
pos.w = imgs[curimg][0]->w;
pos.h = imgs[curimg][0]->h -1;
if (activ)
activate();
init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
}
AdventureMapButton::AdventureMapButton( std::string Name, std::string HelpBox, CFunctionList<void()> Callback, int x, int y, std::string defName, bool activ, std::vector<std::string> * add, bool playerColoredButton )
{
init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
}
@ -81,13 +40,13 @@ void AdventureMapButton::clickLeft (tribool down)
if (actOnDown && down)
{
pressedL=state;
if(!callback.empty())
//if(!callback.empty())
callback();
}
else if (pressedL && (down==false))
{
pressedL=state;
if(!callback.empty())
//if(!callback.empty())
callback();
}
else
@ -139,6 +98,53 @@ void AdventureMapButton::deactivate()
KeyInterested::deactivate();
}
void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name, std::string HelpBox, bool playerColoredButton, std::string defName, std::vector<std::string> * add, int x, int y, bool activ )
{
callback = Callback;
actOnDown = false;
type=2;
abs=true;
active=false;
ourObj=NULL;
state=0;
name=Name;
helpBox=HelpBox;
colorChange = playerColoredButton;
int est = LOCPLINT->playerID;
CDefHandler * temp = CDefHandler::giveDef(defName);
temp->notFreeImgs = true;
for (int i=0;i<temp->ourImages.size();i++)
{
imgs.resize(1);
imgs[0].push_back(temp->ourImages[i].bitmap);
if(playerColoredButton)
graphics->blueToPlayersAdv(imgs[curimg][i],LOCPLINT->playerID);
}
delete temp;
if (add)
{
imgs.resize(imgs.size()+add->size());
for (int i=0; i<add->size();i++)
{
temp = CDefHandler::giveDef((*add)[i]);
temp->notFreeImgs = true;
for (int j=0;j<temp->ourImages.size();j++)
{
imgs[i+1].push_back(temp->ourImages[j].bitmap);
if(playerColoredButton)
graphics->blueToPlayersAdv(imgs[1+i][j],LOCPLINT->playerID);
}
delete temp;
}
delete add;
}
pos.x=x;
pos.y=y;
pos.w = imgs[curimg][0]->w;
pos.h = imgs[curimg][0]->h -1;
if (activ)
activate();
}
void CSlider::sliderClicked()
{

View File

@ -1,6 +1,6 @@
#pragma once
#include "CPlayerInterface.h"
#include <boost/function.hpp>
#include "client/FunctionList.h"
#include <boost/bind.hpp>
class AdventureMapButton
: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
@ -9,7 +9,7 @@ public:
std::string name; //for status bar
std::string helpBox; //for right-click help
char key; //key shortcut
boost::function<void()> callback;
CFunctionList<void()> callback;
bool colorChange,
actOnDown; //runs when mouse is pressed down over it, not when up
@ -21,7 +21,10 @@ public:
void deactivate(); // makes button inactive (but doesn't delete)
AdventureMapButton(); //c-tor
AdventureMapButton( std::string Name, std::string HelpBox, CFunctionList<void()> Callback, int x, int y, std::string defName, bool activ=false, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
AdventureMapButton( std::string Name, std::string HelpBox, boost::function<void()> Callback, int x, int y, std::string defName, bool activ=false, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
void init( CFunctionList<void()> Callback, std::string Name, std::string HelpBox, bool playerColoredButton, std::string defName, std::vector<std::string> * add, int x, int y, bool activ );
};

View File

@ -124,7 +124,7 @@ bool CCallback::dismissCreature(const CArmedInstance *obj, int stackPos)
}
bool CCallback::upgradeCreature(const CArmedInstance *obj, int stackPos, int newID)
{
//TODO: write
*cl->serv << ui16(507) << obj->id << ui8(stackPos) << ui32(newID);
return false;
}
void CCallback::endTurn()
@ -136,40 +136,7 @@ void CCallback::endTurn()
}
UpgradeInfo CCallback::getUpgradeInfo(const CArmedInstance *obj, int stackPos)
{
UpgradeInfo ret;
CCreature *base = &CGI->creh->creatures[((CArmedInstance *)obj)->army.slots[stackPos].first];
if((obj->ID == 98) || ((obj->ID == 34) && static_cast<const CGHeroInstance*>(obj)->visitedTown))
{
CGTownInstance * t;
if(obj->ID == 98)
t = static_cast<CGTownInstance *>(const_cast<CArmedInstance *>(obj));
else
t = static_cast<const CGHeroInstance*>(obj)->visitedTown;
for(std::set<si32>::iterator i=t->builtBuildings.begin(); i!=t->builtBuildings.end(); i++)
{
if( (*i) >= 37 && (*i) < 44 ) //upgraded creature dwelling
{
int nid = t->town->upgradedCreatures[(*i)-37]; //upgrade offered by that building
if(base->upgrades.find(nid) != base->upgrades.end()) //possible upgrade
{
ret.newID.push_back(nid);
ret.cost.push_back(std::set<std::pair<int,int> >());
for(int j=0;j<RESOURCE_QUANTITY;j++)
{
int dif = CGI->creh->creatures[nid].cost[j] - base->cost[j];
if(dif)
ret.cost[ret.cost.size()-1].insert(std::make_pair(j,dif));
}
}
}
}//end for
}
//TODO: check if hero ability makes some upgrades possible
if(ret.newID.size())
ret.oldID = base->idNumber;
return ret;
return gs->getUpgradeInfo(const_cast<CArmedInstance*>(obj),stackPos);
}
const StartInfo * CCallback::getStartInfo()

View File

@ -24,13 +24,6 @@ class CStack;
struct lua_State;
class CClient;
//structure gathering info about upgrade possibilites
struct UpgradeInfo
{
int oldID; //creature to be upgraded
std::vector<int> newID; //possible upgrades
std::vector<std::set<std::pair<int,int> > > cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>
UpgradeInfo(){oldID = -1;};
};
class ICallback
{

View File

@ -3,9 +3,8 @@
#include "global.h"
#include <set>
#include <vector>
#include <boost/function.hpp>
#include "lib/BattleAction.h"
BOOST_TRIBOOL_THIRD_STATE(outOfRange)
#include "client/FunctionList.h"
using namespace boost::logic;
class CCallback;
@ -55,8 +54,8 @@ public:
virtual void tileRevealed(int3 pos){};
virtual void tileHidden(int3 pos){};
virtual void receivedResource(int type, int val){};
virtual void showInfoDialog(std::string text, std::vector<Component*> &components){};
virtual void showSelDialog(std::string text, std::vector<Component*> &components, ui32 askID){};
virtual void showInfoDialog(std::string &text, std::vector<Component*> &components){};
virtual void showSelDialog(std::string &text, std::vector<Component*> &components, ui32 askID){};
virtual void garrisonChanged(const CGObjectInstance * obj){};
virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished
virtual void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback)=0; //pskill is gained primary skill, interface has to choose one of given skills and call callback with selection id

View File

@ -1056,6 +1056,43 @@ int CGameState::battleGetStack(int pos)
return -1;
}
UpgradeInfo CGameState::getUpgradeInfo(CArmedInstance *obj, int stackPos)
{
UpgradeInfo ret;
CCreature *base = &VLC->creh->creatures[obj->army.slots[stackPos].first];
if((obj->ID == 98) || ((obj->ID == 34) && static_cast<const CGHeroInstance*>(obj)->visitedTown))
{
CGTownInstance * t;
if(obj->ID == 98)
t = static_cast<CGTownInstance *>(const_cast<CArmedInstance *>(obj));
else
t = static_cast<const CGHeroInstance*>(obj)->visitedTown;
for(std::set<si32>::iterator i=t->builtBuildings.begin(); i!=t->builtBuildings.end(); i++)
{
if( (*i) >= 37 && (*i) < 44 ) //upgraded creature dwelling
{
int nid = t->town->upgradedCreatures[(*i)-37]; //upgrade offered by that building
if(base->upgrades.find(nid) != base->upgrades.end()) //possible upgrade
{
ret.newID.push_back(nid);
ret.cost.push_back(std::set<std::pair<int,int> >());
for(int j=0;j<RESOURCE_QUANTITY;j++)
{
int dif = VLC->creh->creatures[nid].cost[j] - base->cost[j];
if(dif)
ret.cost[ret.cost.size()-1].insert(std::make_pair(j,dif));
}
}
}
}//end for
}
//TODO: check if hero ability makes some upgrades possible
if(ret.newID.size())
ret.oldID = base->idNumber;
return ret;
}
int BattleInfo::calculateDmg(const CStack* attacker, const CStack* defender)
{
int attackDefenseBonus = attacker->creature->attack - defender->creature->defence;

View File

@ -111,6 +111,14 @@ public:
}
};
struct UpgradeInfo
{
int oldID; //creature to be upgraded
std::vector<int> newID; //possible upgrades
std::vector<std::set<std::pair<int,int> > > cost; // cost[upgrade_serial] -> set of pairs<resource_ID,resource_amount>
UpgradeInfo(){oldID = -1;};
};
class DLL_EXPORT CGameState
{
private:
@ -141,6 +149,7 @@ private:
bool battleAttackCreatureStack(int ID, int dest);
bool battleShootCreatureStack(int ID, int dest);
int battleGetStack(int pos); //returns ID of stack at given tile
UpgradeInfo getUpgradeInfo(CArmedInstance *obj, int stackPos);
public:
int getDate(int mode=0) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month

View File

@ -1,4 +1,5 @@
#include "stdafx.h"
#include <cstdlib>
#include "global.h"
#include "CHeroWindow.h"
#include "CGameInfo.h"

View File

@ -14,6 +14,7 @@
#include <sstream>
#include "hch/CGeneralTextHandler.h"
#include "client/Graphics.h"
#include "CAdvmapInterface.h"
SDL_Color tytulowy, tlo, zwykly ;
SDL_Rect genRect(int hh, int ww, int xx, int yy);
@ -86,7 +87,7 @@ void CMessage::dispose()
delete ok;
delete cancel;
}
SDL_Surface * CMessage::drawBox1(int w, int h, int playerColor)
SDL_Surface * CMessage::drawBox1(int w, int h, int playerColor) //draws box for window
{
//prepare surface
SDL_Surface * ret = SDL_CreateRGBSurface(screen->flags, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
@ -187,7 +188,7 @@ std::vector<std::string> * CMessage::breakText(std::string text, int line, bool
}
return ret;
}
std::pair<int, int> CMessage::getMaxSizes(std::vector< std::vector<CSelectableComponent*> > * komp)
std::pair<int, int> CMessage::getMaxSizes(std::vector< std::vector<SComponent*> > * komp)
{
std::pair<int,int> ret;
for (int i=0;i<komp->size();i++)
@ -254,7 +255,6 @@ SDL_Surface * CMessage::blitCompsOnSur(std::vector<SComponent*> & comps, int max
brdtext = breakText(comps[0]->subtitle,12,true,true);
else
brdtext = NULL;
curh += 30;
comps[0]->pos.x = (ret->w/2) - ((comps[0]->getImg()->w)/2);
comps[0]->pos.y = curh;
blitAt(comps[0]->getImg(),comps[0]->pos.x,comps[0]->pos.y,ret);
@ -268,7 +268,7 @@ SDL_Surface * CMessage::blitCompsOnSur(std::vector<SComponent*> & comps, int max
}
return ret;
}
SDL_Surface* CMessage::blitCompsOnSur(SDL_Surface * _or, std::vector< std::vector<CSelectableComponent*> > * komp, int inter, int &curh, SDL_Surface *ret)
SDL_Surface* CMessage::blitCompsOnSur(SDL_Surface * _or, std::vector< std::vector<SComponent*> > * komp, int inter, int &curh, SDL_Surface *ret)
{
for (int i=0;i<komp->size();i++)
{
@ -279,7 +279,11 @@ SDL_Surface* CMessage::blitCompsOnSur(SDL_Surface * _or, std::vector< std::vecto
if(maxh<(*komp)[i][j]->getImg()->h)
maxh=(*komp)[i][j]->getImg()->h;
}
if(_or)
totalw += (inter*2+_or->w) * ((*komp)[i].size() - 1);
else
totalw += (inter) * ((*komp)[i].size() - 1);
curh+=maxh/2;
int curw = (ret->w/2)-(totalw/2);
for(int j=0;j<(*komp)[i].size();j++)
@ -290,14 +294,18 @@ SDL_Surface* CMessage::blitCompsOnSur(SDL_Surface * _or, std::vector< std::vecto
CSDL_Ext::printAtMiddle((*komp)[i][j]->subtitle,curw+(*komp)[i][j]->getImg()->w/2,curh+((*komp)[i][j]->getImg()->h/2)+10,GEOR13,zwykly,ret);
curw += (*komp)[i][j]->getImg()->w;
if(j<((*komp)[i].size()-1))
{
if(_or)
{
curw+=inter;
blitAt(_or,curw,curh-(_or->h/2),ret);
curw+=_or->w;
}
curw+=inter;
}
}
curh+=maxh/2;
curh += 20; //todo: check subtitle length
}
return ret;
}
@ -347,79 +355,21 @@ CSimpleWindow * CMessage::genWindow(std::string text, int player, int Lmar, int
ret->bitmap = drawBox1(txts.first+Lmar+Rmar,txts.second+Tmar+Bmar,0);
ret->pos.h=ret->bitmap->h;
ret->pos.w=ret->bitmap->w;
for (int i=0; i<txtg->size();i++)
{
int lw=0;
for (int j=0;j<(*txtg)[i].size();j++)
lw+=(*txtg)[i][j]->w;
int pw = ret->bitmap->w/2, ph = ret->bitmap->h/2;
//int pw = Tmar, ph = Lmar;
pw -= lw/2;
ph -= (19*txtg->size())/2;
int tw = pw;
for (int j=0;j<(*txtg)[i].size();j++)
{
//std::stringstream n;
//n <<"temp_"<<i<<"__"<<j<<".bmp";
blitAt((*txtg)[i][j],tw,ph+i*19,ret->bitmap);
//SDL_SaveBMP(ret->bitmap,n.str().c_str());
tw+=(*txtg)[i][j]->w;
SDL_FreeSurface((*txtg)[i][j]);
}
}
return ret;
}
CInfoWindow * CMessage::genIWindow(std::string text, int player, int charperline, std::vector<SComponent*> & comps)
{
//TODO: support for more than one component
CInfoWindow * ret = new CInfoWindow();
ret->components = comps;
std::vector<std::string> * brtext = breakText(text,charperline,true,true);
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(brtext);
std::pair<int,int> txts = getMaxSizes(txtg);
txts.second = txts.second
+ ok->ourImages[0].bitmap->h //button
+ 15 //after button
+ 20; // space between subtitle and button
if (comps.size())
txts.second = txts.second
+ 30 //space to first component
+ comps[0]->getImg()->h
+ 5 //img <-> subtitle
+ 20; //subtitle //!!!!!!!!!!!!!!!!!!!!
ret->bitmap = drawBox1(txts.first+70,txts.second+70,0);
ret->pos.h=ret->bitmap->h;
ret->pos.w=ret->bitmap->w;
int curh = 30; //gorny margines
int curh = ret->bitmap->h/2 - (19*txtg->size())/2;
blitTextOnSur(txtg,curh,ret->bitmap);
if (comps.size())
{
blitCompsOnSur(comps,200,0,curh,ret->bitmap);
}
curh += 20; //to buttton
ret->okb.posr.x = (ret->bitmap->w/2) - (ret->okb.imgs[0][0]->w/2);
ret->okb.posr.y = curh;
ret->okb.show();
curh+=ret->okb.imgs[0][0]->h;
delete brtext;
delete txtg;
return ret;
}
std::vector< std::vector<CSelectableComponent*> > * CMessage::breakComps(std::vector<CSelectableComponent*> & comps,int maxw, SDL_Surface* _or)
std::vector< std::vector<SComponent*> > * CMessage::breakComps(std::vector<SComponent*> & comps,int maxw, SDL_Surface* _or)
{
std::vector< std::vector<CSelectableComponent*> > * ret = new std::vector< std::vector<CSelectableComponent*> >();
std::vector< std::vector<SComponent*> > * ret = new std::vector< std::vector<SComponent*> >();
ret->resize(1);
bool wywalicOr=false;
if (!_or)
{
_or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
wywalicOr=true;
}
int rvi = 0;
int curw = 0;
for(int i=0;i<comps.size();i++)
{
curw += (comps[i]->getImg()->w + 12 + _or->w);
curw += (comps[i]->getImg()->w + 12 + (_or ? _or->w : 0));
if (curw > maxw)
{
curw = 0;
@ -428,10 +378,6 @@ std::vector< std::vector<CSelectableComponent*> > * CMessage::breakComps(std::ve
}
(*ret)[rvi].push_back(comps[i]);
}
if (wywalicOr)
{
SDL_FreeSurface(_or);
}
return ret;
}
@ -460,44 +406,96 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub(int player, std::string text, SDL_S
return ret;
}
void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline)
{
std::vector<std::string> * brtext = breakText(text,charperline,true,true);
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(brtext);
std::pair<int,int> txts = getMaxSizes(txtg);
if(ret->buttons.size())
txts.second += 20 + //before button
ok->ourImages[0].bitmap->h; //button
if (ret->components.size())
txts.second += 30 //space to first component
+ ret->components[0]->getImg()->h
+ 5 //img <-> subtitle
+ 20; //subtitle //TODO: check how much place will be needed for subtitle
ret->bitmap = drawBox1(txts.first+70,txts.second+70,0);
ret->pos.h=ret->bitmap->h;
ret->pos.w=ret->bitmap->w;
ret->pos.x=300-(ret->pos.w/2);
ret->pos.y=300-(ret->pos.h/2);
int curh = 30; //gorny margines
blitTextOnSur(txtg,curh,ret->bitmap);
if (ret->components.size())
{
curh += 30;
if(ret->components.size()==1)
{
blitCompsOnSur(ret->components,200,0,curh,ret->bitmap);
}
else
{
SDL_Surface * _or = 0;
if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
_or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
std::vector< std::vector<SComponent*> > * komp = breakComps(reinterpret_cast<std::vector<SComponent*>&>(ret->components),500,_or);
blitCompsOnSur(_or,komp,10,curh,ret->bitmap);
delete komp;
}
}
if(ret->buttons.size())
{
curh += 20; //to buttton
int bw = 20*(ret->buttons.size()-1); //total width of buttons - start with distance between them
for(int i=0; i<ret->buttons.size(); i++) //and add buttons width
bw+=ret->buttons[i]->imgs[0][0]->w;
bw = (ret->bitmap->w/2) - (bw/2);
for(int i=0; i<ret->buttons.size(); i++)
{
ret->buttons[i]->pos.x = bw + ret->pos.x;
ret->buttons[i]->pos.y = curh + ret->pos.y;
bw += ret->buttons[i]->imgs[0][0]->w + 20;
}
}
for(int i=0; i<ret->components.size(); i++)
{
ret->components[i]->pos.x += ret->pos.x;
ret->components[i]->pos.y += ret->pos.y;
}
delete brtext;
delete txtg;
}
CSelWindow * CMessage::genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner)
{
CSelWindow * ret = new CSelWindow();
for(unsigned i=0;i<comps.size();i++)
{
ret->components.push_back(comps[i]);
comps[i]->onSelect = boost::bind(&CSelWindow::selectionChange,ret,i);
}
std::vector<std::string> * tekst = breakText(text,charperline);
std::vector<std::vector<SDL_Surface*> > * txtg = drawText(tekst);
std::pair<int,int> txts = getMaxSizes(txtg);
txts.first+=45; //side margins
int curh = 50; //top margin
SDL_Surface * _or = TTF_RenderText_Blended(GEOR13,CGI->generaltexth->allTexts[4].c_str(),zwykly);
std::vector< std::vector<CSelectableComponent*> > * komp = breakComps(comps,500,_or);
std::pair<int,int> txts2 = getMaxSizes(komp);
ret->pos.h = txts.second //wys. tekstu
+ txts2.second //wys komponentow
+ 20 //podpis pod komponentami
+ 55 //gorny margines
+ 60 //text <=> comps
+ 20 //comps <=> button
+ ok->ourImages[0].bitmap->h //button
+ 30; //bottom margin
ret->pos.w = std::max(txts.first,txts.second);
ret->bitmap = drawBox1(ret->pos.w,ret->pos.h,player);
blitTextOnSur(txtg,curh,ret->bitmap);
curh += 50;
blitCompsOnSur(_or,komp,10,curh,ret->bitmap);
curh += 30; //to buttton
ret->okb.posr.x = (ret->bitmap->w/2) - (ret->okb.imgs[0][0]->w/2);
ret->okb.posr.y = curh;
ret->okb.show();
curh+=ret->okb.imgs[0][0]->h;
SDL_FreeSurface(_or);
delete komp;
delete tekst;
return ret;
//CSelWindow * ret = new CSelWindow();
//std::vector<std::string> * tekst = breakText(text,charperline);
//std::vector<std::vector<SDL_Surface*> > * txtg = drawText(tekst);
//std::pair<int,int> txts = getMaxSizes(txtg);
//txts.first+=45; //side margins
//int curh = 50; //top margin
////std::pair<int,int> txts2 = getMaxSizes(komp);
//ret->pos.h = txts.second //wys. tekstu
// //+ txts2.second //wys komponentow
// + 20 //podpis pod komponentami
// + 55 //gorny margines
// + 60 //text <=> comps
// + 20 //comps <=> button
// + ok->ourImages[0].bitmap->h //button
// + 30; //bottom margin
//ret->pos.w = std::max(txts.first,txts.second);
//ret->bitmap = drawBox1(ret->pos.w,ret->pos.h,player);
//blitTextOnSur(txtg,curh,ret->bitmap);
//curh += 50;
//blitCompsOnSur(_or,komp,10,curh,ret->bitmap);
//curh += 30; //to buttton
//ret->buttons[0]->pos.x = (ret->bitmap->w/2) - (ret->buttons[0]->imgs[0][0]->w/2);
//ret->buttons[0]->pos.y = curh;
//ret->buttons[0]->show();
//curh += ret->buttons[0]->imgs[0][0]->h;
//SDL_FreeSurface(_or);
//delete komp;
//delete tekst;
return NULL;
}
SDL_Surface * CMessage::genMessage

View File

@ -27,13 +27,13 @@ class CMessage
public:
static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg);
static std::pair<int, int> getMaxSizes(std::vector< std::vector<CSelectableComponent*> > * komp);
static std::pair<int, int> getMaxSizes(std::vector< std::vector<SComponent*> > * komp);
static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext);
static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int & curh, SDL_Surface * ret);
static SDL_Surface * blitCompsOnSur(std::vector<SComponent*> & comps, int maxw, int inter, int & curh, SDL_Surface * ret);
static SDL_Surface * blitCompsOnSur(SDL_Surface *_or, std::vector< std::vector<CSelectableComponent*> > *komp, int inter, int &curh, SDL_Surface *ret);
static CInfoWindow * genIWindow(std::string text, int player, int charperline, std::vector<SComponent*> &comps);
static std::vector< std::vector<CSelectableComponent*> > * breakComps(std::vector<CSelectableComponent*> &comps, int maxw, SDL_Surface* _or=NULL);
static SDL_Surface * blitCompsOnSur(SDL_Surface *_or, std::vector< std::vector<SComponent*> > *komp, int inter, int &curh, SDL_Surface *ret);
static void drawIWindow(CInfoWindow * ret, std::string text, int player, int charperline);
static std::vector< std::vector<SComponent*> > * breakComps(std::vector<SComponent*> &comps, int maxw, SDL_Surface* _or=NULL);
static CSelWindow * genSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> & comps, int owner);
static CSimpleWindow * genWindow(std::string text, int player, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins
static SDL_Surface * genMessage(std::string title, std::string text, EWindowType type=infoOnly,

View File

@ -157,11 +157,20 @@ void CGarrisonSlot::clickLeft(tribool down)
if(owner->highlighted == this) //view info
{
UpgradeInfo pom = LOCPLINT->cb->getUpgradeInfo(getObj(),ID);
if(pom.oldID>=0)
{
(new CCreInfoWindow
(creature->idNumber,1,NULL,
(pom.oldID>=0)?(boost::bind(&CCallback::upgradeCreature,LOCPLINT->cb,getObj(),ID,-1)):(boost::function<void()>()), //if upgrade is possible we'll bind proper function in callback
boost::bind(&CCallback::upgradeCreature,LOCPLINT->cb,getObj(),ID,pom.newID[0]), //if upgrade is possible we'll bind proper function in callback
boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID)))
->activate();
}
else
{
(new CCreInfoWindow
(creature->idNumber,1,NULL,0, boost::bind(&CCallback::dismissCreature,LOCPLINT->cb,getObj(),ID)) )
->activate();
}
owner->highlighted = NULL;
show();
refr = true;
@ -454,39 +463,57 @@ void CGarrisonInt::deactivate()
deactiveteSlots();
}
CInfoWindow::CInfoWindow(std::string text, int player, int charperline, std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons)
{
for(int i=0;i<Buttons.size();i++)
{
buttons.push_back(new AdventureMapButton("","",Buttons[i].second,0,0,Buttons[i].first));
if(!Buttons[i].second) //if no function, then by default we'll set it to close
buttons[i]->callback += boost::bind(&CInfoWindow::close,this);
}
for(int i=0;i<comps.size();i++)
{
components.push_back(comps[i]);
}
CMessage::drawIWindow(this,text,player,charperline);
}
CInfoWindow::CInfoWindow()
:okb(NMessage::ok,NULL,&CInfoWindow::okClicked)
{
okb.ourObj = this;
okb.delg = this;
okb.notFreeButton=true;
}
void CInfoWindow::okClicked(tribool down)
{
if (!down)
close();
}
void CInfoWindow::close()
{
for (int i=0;i<components.size();i++)
{
components[i]->deactivate();
delete components[i];
}
components.clear();
okb.deactivate();
SDL_FreeSurface(bitmap);
bitmap = NULL;
LOCPLINT->removeObjToBlit(this);
LOCPLINT->curint->activate();
deactivate();
delete this;
}
CInfoWindow::~CInfoWindow()
void CInfoWindow::show(SDL_Surface * to)
{
CSimpleWindow::show();
for(int i=0;i<buttons.size();i++)
buttons[i]->show();
}
CInfoWindow::~CInfoWindow()
{
for (int i=0;i<components.size();i++)
delete components[i];
for(int i=0;i<buttons.size();i++)
delete buttons[i];
}
void CInfoWindow::activate()
{
for (int i=0;i<components.size();i++)
components[i]->activate();
for(int i=0;i<buttons.size();i++)
buttons[i]->activate();
}
void CInfoWindow::deactivate()
{
for (int i=0;i<components.size();i++)
components[i]->deactivate();
for(int i=0;i<buttons.size();i++)
buttons[i]->deactivate();
LOCPLINT->removeObjToBlit(this);
}
void CRClickPopup::clickRight (tribool down)
{
if(down)
@ -733,13 +760,22 @@ void CSelWindow::selectionChange(unsigned to)
blitAt(pom->getImg(),pom->pos.x-pos.x,pom->pos.y-pos.y,bitmap);
}
}
void CSelWindow::okClicked(tribool down)
CSelWindow::CSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> &comps, std::vector<std::pair<std::string,boost::function<void()> > > &Buttons)
{
if(!down)
close();
for(int i=0;i<Buttons.size();i++)
{
buttons.push_back(new AdventureMapButton("","",(Buttons[i].second)?(Buttons[i].second):(boost::bind(&CInfoWindow::close,this)),0,0,Buttons[i].first));
}
for(int i=0;i<comps.size();i++)
{
components.push_back(comps[i]);
comps[i]->onSelect = boost::bind(&CSelWindow::selectionChange,this,i);
}
CMessage::drawIWindow(this,text,player,charperline);
}
void CSelWindow::close()
{
deactivate();
int ret = -1;
for (int i=0;i<components.size();i++)
{
@ -747,14 +783,7 @@ void CSelWindow::close()
{
ret = i;
}
components[i]->deactivate();
delete components[i];
}
components.clear();
okb.deactivate();
SDL_FreeSurface(bitmap);
bitmap = NULL;
LOCPLINT->removeObjToBlit(this);
LOCPLINT->curint->activate();
LOCPLINT->cb->selectionMade(ret,ID);
delete this;
@ -1881,7 +1910,7 @@ void CPlayerInterface::receivedResource(int type, int val)
adventureInt->resdatabar.draw();
}
void CPlayerInterface::showSelDialog(std::string text, std::vector<Component*> &components, ui32 askID)
void CPlayerInterface::showSelDialog(std::string &text, std::vector<Component*> &components, ui32 askID)
//void CPlayerInterface::showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)
{
boost::unique_lock<boost::mutex> un(*pim);
@ -1889,20 +1918,12 @@ void CPlayerInterface::showSelDialog(std::string text, std::vector<Component*> &
std::vector<CSelectableComponent*> intComps;
for(int i=0;i<components.size();i++)
intComps.push_back(new CSelectableComponent(*components[i])); //will be deleted by CSelWindow::close
std::vector<std::pair<std::string,boost::function<void()> > > pom;
pom.push_back(std::pair<std::string,boost::function<void()> >("IOKAY.DEF",0));
CSelWindow * temp = CMessage::genSelWindow(text,LOCPLINT->playerID,35,intComps,playerID);
CSelWindow * temp = new CSelWindow(text,playerID,35,intComps,pom);
LOCPLINT->objsToBlit.push_back(temp);
temp->pos.x=300-(temp->pos.w/2);
temp->pos.y=300-(temp->pos.h/2);
temp->okb.pos.x = temp->okb.posr.x + temp->pos.x;
temp->okb.pos.y = temp->okb.posr.y + temp->pos.y;
temp->okb.activate();
for (int i=0;i<temp->components.size();i++)
{
temp->components[i]->activate();
temp->components[i]->pos.x += temp->pos.x;
temp->components[i]->pos.y += temp->pos.y;
}
temp->activate();
temp->ID = askID;
intComps[0]->clickLeft(true);
}
@ -2068,42 +2089,34 @@ void CPlayerInterface::showComp(SComponent comp)
adventureInt->infoBar.showComp(&comp,4000);
}
void CPlayerInterface::showInfoDialog(std::string text, std::vector<Component*> &components)
void CPlayerInterface::showInfoDialog(std::string &text, std::vector<Component*> &components)
{
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<SComponent*> intComps;
for(int i=0;i<components.size();i++)
intComps.push_back(new SComponent(*components[i]));
CInfoWindow * temp = CMessage::genIWindow(text,LOCPLINT->playerID,32,intComps);
LOCPLINT->objsToBlit.push_back(temp);
temp->pos.x=300-(temp->pos.w/2);
temp->pos.y=300-(temp->pos.h/2);
temp->okb.pos.x = temp->okb.posr.x + temp->pos.x;
temp->okb.pos.y = temp->okb.posr.y + temp->pos.y;
temp->okb.activate();
for (int i=0;i<temp->components.size();i++)
{
temp->components[i]->activate();
temp->components[i]->pos.x += temp->pos.x;
temp->components[i]->pos.y += temp->pos.y;
}
showInfoDialog(text,intComps);
}
void CPlayerInterface::showInfoDialog(std::string text, std::vector<SComponent*> & components)
void CPlayerInterface::showInfoDialog(std::string &text, std::vector<SComponent*> & components)
{
curint->deactivate(); //dezaktywacja starego interfejsu
CInfoWindow * temp = CMessage::genIWindow(text,LOCPLINT->playerID,32,components);
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",0));
CInfoWindow * temp = new CInfoWindow(text,playerID,32,components,pom);
temp->buttons[0]->callback += boost::bind(&IActivable::activate,LOCPLINT->curint);
temp->activate();
LOCPLINT->objsToBlit.push_back(temp);
}
void CPlayerInterface::showYesNoDialog(std::string &text, std::vector<SComponent*> & components, CFunctionList<void()> funcs[2])
{
curint->deactivate(); //dezaktywacja starego interfejsu
std::vector<std::pair<std::string,CFunctionList<void()> > > pom;
pom.push_back(std::pair<std::string,CFunctionList<void()> >("IOKAY.DEF",funcs[0]));
pom.push_back(std::pair<std::string,CFunctionList<void()> >("ICANCEL.DEF",funcs[1]));
CInfoWindow * temp = new CInfoWindow(text,playerID,32,components,pom);
temp->activate();
LOCPLINT->objsToBlit.push_back(temp);
temp->pos.x=300-(temp->pos.w/2);
temp->pos.y=300-(temp->pos.h/2);
temp->okb.pos.x = temp->okb.posr.x + temp->pos.x;
temp->okb.pos.y = temp->okb.posr.y + temp->pos.y;
temp->okb.activate();
for (int i=0;i<temp->components.size();i++)
{
temp->components[i]->activate();
temp->components[i]->pos.x += temp->pos.x;
temp->components[i]->pos.y += temp->pos.y;
}
}
void CPlayerInterface::removeObjToBlit(IShowable* obj)
{
@ -2960,7 +2973,7 @@ void CCreInfoWindow::show(SDL_Surface * to)
CCreInfoWindow::CCreInfoWindow
(int Cid, int Type, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm)
:ok(0),dismiss(0),upgrade(0),type(Type),dsm(Dsm)
:ok(0),dismiss(0),upgrade(0),type(Type),dsm(Dsm),dependant(0)
{
c = &CGI->creh->creatures[Cid];
bitmap = BitmapHandler::loadBitmap("CRSTKPU.bmp");
@ -3045,7 +3058,10 @@ CCreInfoWindow::CCreInfoWindow
if(type)
{
if(Upg)
{
upgrade = new AdventureMapButton("",CGI->preth->zelp[446].second,Upg,pos.x+76,pos.y+237,"IVIEWCR.DEF");
upgrade->callback += boost::bind(&CCreInfoWindow::close,this);
}
if(Dsm)
dismiss = new AdventureMapButton("",CGI->preth->zelp[445].second,boost::bind(&CCreInfoWindow::dismissF,this),pos.x+21,pos.y+237,"IVIEWCR2.DEF");
ok = new AdventureMapButton("",CGI->preth->zelp[445].second,boost::bind(&CCreInfoWindow::close,this),pos.x+216,pos.y+237,"IOKAY.DEF");
@ -3114,6 +3130,19 @@ void CCreInfoWindow::deactivate()
upgrade->deactivate();
}
void CCreInfoWindow::onUpgradeYes()
{
dependant->close();
dependant->deactivate();
delete dependant;
LOCPLINT->curint->activate();
}
void CCreInfoWindow::onUpgradeNo()
{
}
void CLevelWindow::close()
{
deactivate();

View File

@ -23,7 +23,6 @@ class CSelectableComponent;
class CCreatureSet;
class CGObjectInstance;
class CSlider;
namespace boost
{
class mutex;
@ -160,19 +159,22 @@ public:
class CInfoWindow : public CSimpleWindow //text + comp. + ok button
{ //window deletes its components when closed
public:
CSCButton<CInfoWindow> okb;
std::vector<AdventureMapButton *> buttons;
std::vector<SComponent*> components;
virtual void okClicked(boost::logic::tribool down);
virtual void close();
virtual void show(SDL_Surface * to = NULL);
void activate();
void deactivate();
CInfoWindow(std::string text, int player, int charperline, std::vector<SComponent*> &comps, std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons);
CInfoWindow();
virtual ~CInfoWindow();
~CInfoWindow();
};
class CSelWindow : public CInfoWindow //component selection window
{ //uwaga - to okno usuwa swoje komponenty przy zamykaniu
public:
void selectionChange(unsigned to);
void okClicked(boost::logic::tribool down);
void close();
CSelWindow(std::string text, int player, int charperline, std::vector<CSelectableComponent*> &comps, std::vector<std::pair<std::string,boost::function<void()> > > &Buttons);
CSelWindow(){};
};
@ -330,8 +332,8 @@ public:
void heroCreated(const CGHeroInstance* hero);
void heroPrimarySkillChanged(const CGHeroInstance * hero, int which, int val);
void receivedResource(int type, int val);
void showInfoDialog(std::string text, std::vector<Component*> &components);
void showSelDialog(std::string text, std::vector<Component*> &components, ui32 askID);
void showInfoDialog(std::string &text, std::vector<Component*> &components);
void showSelDialog(std::string &text, std::vector<Component*> &components, ui32 askID);
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
void garrisonChanged(const CGObjectInstance * obj);
void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished
@ -363,7 +365,8 @@ public:
void init(ICallback * CB);
int3 repairScreenPos(int3 pos);
void removeObjToBlit(IShowable* obj);
void showInfoDialog(std::string text, std::vector<SComponent*> & components);
void showInfoDialog(std::string &text, std::vector<SComponent*> & components);
void showYesNoDialog(std::string &text, std::vector<SComponent*> & components, CFunctionList<void()> funcs[2]);
CPlayerInterface(int Player, int serial);//c-tor
~CPlayerInterface();//d-tor
@ -524,6 +527,7 @@ public:
boost::function<void()> dsm;
CCreaturePic *anim;
CCreature *c;
CInfoWindow *dependant; //it may be dialog asking whther upgrade/dismiss stack (if opened)
AdventureMapButton *dismiss, *upgrade, *ok;
CCreInfoWindow(int Cid, int Type, StackState *State, boost::function<void()> Upg, boost::function<void()> Dsm);
@ -535,6 +539,8 @@ public:
void keyPressed (SDL_KeyboardEvent & key);
void deactivate();
void show(SDL_Surface * to = NULL);
void onUpgradeYes();
void onUpgradeNo();
};
class CLevelWindow : public IShowable, public CIntObject

36
client/FunctionList.h Normal file
View File

@ -0,0 +1,36 @@
#pragma once
#include <boost/function.hpp>
template<typename Signature, typename Allocator = std::allocator<void> >
class CFunctionList
{
public:
std::vector<boost::function<Signature,Allocator> > funcs;
CFunctionList(int){};
CFunctionList(){};
CFunctionList(const boost::function<Signature,Allocator> &first)
{
funcs.push_back(first);
}
CFunctionList & operator+=(const boost::function<Signature,Allocator> &first)
{
funcs.push_back(first);
return *this;
}
const boost::function<Signature,Allocator> & operator=(const boost::function<Signature,Allocator> &first)
{
funcs.push_back(first);
return first;
}
operator bool() const
{
return funcs.size();
}
void operator()() const
{
std::vector<boost::function<Signature,Allocator> > funcs2 = funcs; //backup
for(int i=0;i<funcs2.size(); i++)
funcs2[i]();
}
};

View File

@ -444,10 +444,6 @@
RelativePath=".\CCreatureAnimation.h"
>
</File>
<File
RelativePath="..\hch\CCreatureHandler.h"
>
</File>
<File
RelativePath="..\CCursorHandler.h"
>
@ -524,6 +520,10 @@
RelativePath="..\CThreadHelper.h"
>
</File>
<File
RelativePath=".\FunctionList.h"
>
</File>
<File
RelativePath="..\global.h"
>

View File

@ -258,10 +258,6 @@
<Filter
Name="Source Files"
>
<File
RelativePath="..\hch\CAmbarCendamo.cpp"
>
</File>
<File
RelativePath="..\hch\CArtHandler.cpp"
>
@ -324,10 +320,6 @@
RelativePath=".\BattleAction.h"
>
</File>
<File
RelativePath="..\hch\CAmbarCendamo.h"
>
</File>
<File
RelativePath="..\hch\CArtHandler.h"
>

2223
map.cpp

File diff suppressed because it is too large Load Diff

13
map.h
View File

@ -485,6 +485,19 @@ struct DLL_EXPORT Mapa
std::vector<CGTownInstance*> towns;
void initFromBytes(unsigned char * bufor); //creates map from decompressed .h3m data
void readEvents( unsigned char * bufor, int &i);
void readObjects( unsigned char * bufor, int &i);
void readDefInfo( unsigned char * bufor, int &i);
void readTerrain( unsigned char * bufor, int &i);
void readPredefinedHeroes( unsigned char * bufor, int &i);
void readHeader( unsigned char * bufor, int &i);
void readRumors( unsigned char * bufor, int &i);
void loadViCLossConditions( unsigned char * bufor, int &i);
void loadPlayerInfo( int &pom, unsigned char * bufor, int &i);
void loadHero( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
void loadTown( CGObjectInstance * &nobj, unsigned char * bufor, int &i);
int loadSeerHut( unsigned char * bufor, int i, CGObjectInstance * nobj);
void addBlockVisTiles(CGObjectInstance * obj);
void removeBlockVisTiles(CGObjectInstance * obj);
Mapa(std::string filename); //creates map structure from .h3m file

View File

@ -10,7 +10,6 @@
#include "../map.h"
#include "../lib/NetPacks.h"
#include "../lib/Connection.h"
#include "../CLua.h"
#include "../hch/CObjectHandler.h"
#include "../hch/CTownHandler.h"
#include "../hch/CBuildingHandler.h"
@ -244,153 +243,9 @@ void CGameHandler::startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile
{
BattleInfo *curB = new BattleInfo;
//battle start
{
battleResult.set(NULL);
std::vector<CStack*> & stacks = (curB->stacks);
curB->tile = tile;
curB->siege = 0; //TODO: add sieges
curB->army1=army1;
curB->army2=army2;
curB->hero1=(hero1)?(hero1->id):(-1);
curB->hero2=(hero2)?(hero2->id):(-1);
curB->side1=(hero1)?(hero1->tempOwner):(-1);
curB->side2=(hero2)?(hero2->tempOwner):(-1);
curB->round = -2;
curB->activeStack = -1;
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army1.slots.begin(); i!=army1.slots.end(); i++)
{
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true));
stacks[stacks.size()-1]->ID = stacks.size()-1;
}
//initialization of positions
switch(army1.slots.size()) //for attacker
{
case 0:
break;
case 1:
stacks[0]->position = 86; //6
break;
case 2:
stacks[0]->position = 35; //3
stacks[1]->position = 137; //9
break;
case 3:
stacks[0]->position = 35; //3
stacks[1]->position = 86; //6
stacks[2]->position = 137; //9
break;
case 4:
stacks[0]->position = 1; //1
stacks[1]->position = 69; //5
stacks[2]->position = 103; //7
stacks[3]->position = 171; //11
break;
case 5:
stacks[0]->position = 1; //1
stacks[1]->position = 35; //3
stacks[2]->position = 86; //6
stacks[3]->position = 137; //9
stacks[4]->position = 171; //11
break;
case 6:
stacks[0]->position = 1; //1
stacks[1]->position = 35; //3
stacks[2]->position = 69; //5
stacks[3]->position = 103; //7
stacks[4]->position = 137; //9
stacks[5]->position = 171; //11
break;
case 7:
stacks[0]->position = 1; //1
stacks[1]->position = 35; //3
stacks[2]->position = 69; //5
stacks[3]->position = 86; //6
stacks[4]->position = 103; //7
stacks[5]->position = 137; //9
stacks[6]->position = 171; //11
break;
default: //fault
break;
}
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army2.slots.begin(); i!=army2.slots.end(); i++)
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false));
switch(army2.slots.size()) //for defender
{
case 0:
break;
case 1:
stacks[0+army1.slots.size()]->position = 100; //6
break;
case 2:
stacks[0+army1.slots.size()]->position = 49; //3
stacks[1+army1.slots.size()]->position = 151; //9
break;
case 3:
stacks[0+army1.slots.size()]->position = 49; //3
stacks[1+army1.slots.size()]->position = 100; //6
stacks[2+army1.slots.size()]->position = 151; //9
break;
case 4:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 83; //5
stacks[2+army1.slots.size()]->position = 117; //7
stacks[3+army1.slots.size()]->position = 185; //11
break;
case 5:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 49; //3
stacks[2+army1.slots.size()]->position = 100; //6
stacks[3+army1.slots.size()]->position = 151; //9
stacks[4+army1.slots.size()]->position = 185; //11
break;
case 6:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 49; //3
stacks[2+army1.slots.size()]->position = 83; //5
stacks[3+army1.slots.size()]->position = 117; //7
stacks[4+army1.slots.size()]->position = 151; //9
stacks[5+army1.slots.size()]->position = 185; //11
break;
case 7:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 49; //3
stacks[2+army1.slots.size()]->position = 83; //5
stacks[3+army1.slots.size()]->position = 100; //6
stacks[4+army1.slots.size()]->position = 117; //7
stacks[5+army1.slots.size()]->position = 151; //9
stacks[6+army1.slots.size()]->position = 185; //11
break;
default: //fault
break;
}
for(unsigned g=0; g<stacks.size(); ++g) //shifting positions of two-hex creatures
{
if((stacks[g]->position%17)==1 && stacks[g]->creature->isDoubleWide())
{
stacks[g]->position += 1;
}
else if((stacks[g]->position%17)==15 && stacks[g]->creature->isDoubleWide())
{
stacks[g]->position -= 1;
}
}
std::stable_sort(stacks.begin(),stacks.end(),cmpst);
//block engaged players
if(hero1->tempOwner<PLAYER_LIMIT)
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,true);
if(hero2 && hero2->tempOwner<PLAYER_LIMIT)
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
//send info about battles
BattleStart bs;
bs.info = curB;
sendAndApply(&bs);
setupBattle(curB, tile, army1, army2, hero1, hero2); //battle start
NEW_ROUND;
}
//tactic round
{
@ -764,6 +619,53 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
sendAndApply(&sg);
break;
}
case 507://upgrade creature
{
ui32 objid, upgID;
ui8 pos;
c >> objid >> pos >> upgID;
CArmedInstance *obj = static_cast<CArmedInstance*>(gs->map->objects[objid]);
UpgradeInfo ui = gs->getUpgradeInfo(obj,pos);
int player = obj->tempOwner;
int crQuantity = obj->army.slots[pos].second;
//check if upgrade is possible
if(ui.oldID<0 || !vstd::contains(ui.newID,upgID))
break;
//check if player has enough resources
for(int i=0;i<ui.cost.size();i++)
{
for (std::set<std::pair<int,int> >::iterator j=ui.cost[i].begin(); j!=ui.cost[i].end(); j++)
{
if(gs->players[player].resources[j->first] < j->second*crQuantity)
goto upgend;
}
}
//take resources
for(int i=0;i<ui.cost.size();i++)
{
for (std::set<std::pair<int,int> >::iterator j=ui.cost[i].begin(); j!=ui.cost[i].end(); j++)
{
SetResource sr;
sr.player = player;
sr.resid = j->first;
sr.val = gs->players[player].resources[j->first] - j->second*crQuantity;
sendAndApply(&sr);
}
}
{
//upgrade creature
SetGarrisons sg;
sg.garrs[objid] = obj->army;
sg.garrs[objid].slots[pos].first = upgID;
sendAndApply(&sg);
}
upgend:
break;
}
case 2001:
{
ui32 qid, answer;
@ -1090,3 +992,149 @@ void CGameHandler::run()
}
}
}
void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 )
{
battleResult.set(NULL);
std::vector<CStack*> & stacks = (curB->stacks);
curB->tile = tile;
curB->siege = 0; //TODO: add sieges
curB->army1=army1;
curB->army2=army2;
curB->hero1=(hero1)?(hero1->id):(-1);
curB->hero2=(hero2)?(hero2->id):(-1);
curB->side1=(hero1)?(hero1->tempOwner):(-1);
curB->side2=(hero2)?(hero2->tempOwner):(-1);
curB->round = -2;
curB->activeStack = -1;
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army1.slots.begin(); i!=army1.slots.end(); i++)
{
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero1->tempOwner, stacks.size(), true));
stacks[stacks.size()-1]->ID = stacks.size()-1;
}
//initialization of positions
switch(army1.slots.size()) //for attacker
{
case 0:
break;
case 1:
stacks[0]->position = 86; //6
break;
case 2:
stacks[0]->position = 35; //3
stacks[1]->position = 137; //9
break;
case 3:
stacks[0]->position = 35; //3
stacks[1]->position = 86; //6
stacks[2]->position = 137; //9
break;
case 4:
stacks[0]->position = 1; //1
stacks[1]->position = 69; //5
stacks[2]->position = 103; //7
stacks[3]->position = 171; //11
break;
case 5:
stacks[0]->position = 1; //1
stacks[1]->position = 35; //3
stacks[2]->position = 86; //6
stacks[3]->position = 137; //9
stacks[4]->position = 171; //11
break;
case 6:
stacks[0]->position = 1; //1
stacks[1]->position = 35; //3
stacks[2]->position = 69; //5
stacks[3]->position = 103; //7
stacks[4]->position = 137; //9
stacks[5]->position = 171; //11
break;
case 7:
stacks[0]->position = 1; //1
stacks[1]->position = 35; //3
stacks[2]->position = 69; //5
stacks[3]->position = 86; //6
stacks[4]->position = 103; //7
stacks[5]->position = 137; //9
stacks[6]->position = 171; //11
break;
default: //fault
break;
}
for(std::map<si32,std::pair<ui32,si32> >::iterator i = army2.slots.begin(); i!=army2.slots.end(); i++)
stacks.push_back(new CStack(&VLC->creh->creatures[i->second.first],i->second.second,hero2 ? hero2->tempOwner : 255, stacks.size(), false));
switch(army2.slots.size()) //for defender
{
case 0:
break;
case 1:
stacks[0+army1.slots.size()]->position = 100; //6
break;
case 2:
stacks[0+army1.slots.size()]->position = 49; //3
stacks[1+army1.slots.size()]->position = 151; //9
break;
case 3:
stacks[0+army1.slots.size()]->position = 49; //3
stacks[1+army1.slots.size()]->position = 100; //6
stacks[2+army1.slots.size()]->position = 151; //9
break;
case 4:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 83; //5
stacks[2+army1.slots.size()]->position = 117; //7
stacks[3+army1.slots.size()]->position = 185; //11
break;
case 5:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 49; //3
stacks[2+army1.slots.size()]->position = 100; //6
stacks[3+army1.slots.size()]->position = 151; //9
stacks[4+army1.slots.size()]->position = 185; //11
break;
case 6:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 49; //3
stacks[2+army1.slots.size()]->position = 83; //5
stacks[3+army1.slots.size()]->position = 117; //7
stacks[4+army1.slots.size()]->position = 151; //9
stacks[5+army1.slots.size()]->position = 185; //11
break;
case 7:
stacks[0+army1.slots.size()]->position = 15; //1
stacks[1+army1.slots.size()]->position = 49; //3
stacks[2+army1.slots.size()]->position = 83; //5
stacks[3+army1.slots.size()]->position = 100; //6
stacks[4+army1.slots.size()]->position = 117; //7
stacks[5+army1.slots.size()]->position = 151; //9
stacks[6+army1.slots.size()]->position = 185; //11
break;
default: //fault
break;
}
for(unsigned g=0; g<stacks.size(); ++g) //shifting positions of two-hex creatures
{
if((stacks[g]->position%17)==1 && stacks[g]->creature->isDoubleWide())
{
stacks[g]->position += 1;
}
else if((stacks[g]->position%17)==15 && stacks[g]->creature->isDoubleWide())
{
stacks[g]->position -= 1;
}
}
std::stable_sort(stacks.begin(),stacks.end(),cmpst);
//block engaged players
if(hero1->tempOwner<PLAYER_LIMIT)
states.setFlag(hero1->tempOwner,&PlayerStatus::engagedIntoBattle,true);
if(hero2 && hero2->tempOwner<PLAYER_LIMIT)
states.setFlag(hero2->tempOwner,&PlayerStatus::engagedIntoBattle,true);
//send info about battles
BattleStart bs;
bs.info = curB;
sendAndApply(&bs);
}

View File

@ -53,7 +53,7 @@ class CGameHandler
void changeSecSkill(int ID, ui16 which, int val, bool abs=false);
void moveStack(int stack, int dest);
void startBattle(CCreatureSet army1, CCreatureSet army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2); //use hero=NULL for no hero
void setupBattle( BattleInfo * curB, int3 tile, CCreatureSet &army1, CCreatureSet &army2, CGHeroInstance * hero1, CGHeroInstance * hero2 );
public:
CGameHandler(void);