mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
* refactorings and comment coverage improvements
This commit is contained in:
parent
4f30bde636
commit
b5ae7d5cbe
@ -216,15 +216,15 @@ bool CCallback::verifyPath(CPath * path, bool blockSea) const
|
||||
continue;
|
||||
|
||||
if (
|
||||
((CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].tileInfo->tertype==water)
|
||||
((CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].tileInfo->tertype==TerrainTile::water)
|
||||
&&
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tileInfo->tertype!=water))
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tileInfo->tertype!=TerrainTile::water))
|
||||
||
|
||||
((CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].tileInfo->tertype!=water)
|
||||
((CGI->mh->ttiles[path->nodes[i].coord.x][path->nodes[i].coord.y][path->nodes[i].coord.z].tileInfo->tertype!=TerrainTile::water)
|
||||
&&
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tileInfo->tertype==water))
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tileInfo->tertype==TerrainTile::water))
|
||||
||
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tileInfo->tertype==rock)
|
||||
(CGI->mh->ttiles[path->nodes[i-1].coord.x][path->nodes[i-1].coord.y][path->nodes[i-1].coord.z].tileInfo->tertype==TerrainTile::rock)
|
||||
|
||||
)
|
||||
return false;
|
||||
@ -597,14 +597,14 @@ void CCallback::getMarketOffer( int t1, int t2, int &give, int &rec, int mode/*=
|
||||
if(mode) return; //TODO - support
|
||||
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
|
||||
//if(gs->resVals[t1] >= gs->resVals[t2])
|
||||
float r = gs->resVals[t1],
|
||||
g = gs->resVals[t2] / gs->getMarketEfficiency(player,mode);
|
||||
if(r>g)
|
||||
float r = gs->resVals[t1], //price of given resource
|
||||
g = gs->resVals[t2] / gs->getMarketEfficiency(player,mode); //price of wanted resource
|
||||
if(r>g) //if given resource is more expensive than wanted
|
||||
{
|
||||
rec = ceil(r / g);
|
||||
give = 1;
|
||||
}
|
||||
else
|
||||
else //if wanted resource is more expensive
|
||||
{
|
||||
give = ceil(g / r);
|
||||
rec = 1;
|
||||
|
@ -81,7 +81,7 @@ public:
|
||||
virtual const StartInfo * getStartInfo()const =0;
|
||||
virtual std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos)const =0;
|
||||
virtual std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos)const =0;
|
||||
virtual void getMarketOffer(int t1, int t2, int &give, int &rec, int mode=0)const =0;
|
||||
virtual void getMarketOffer(int t1, int t2, int &give, int &rec, int mode=0)const =0; //t1 - type of given resource, t2 - type of received resource; give is the amount of resource t1 that can be traded for amount rec of resource t2 (one of them is 1)
|
||||
virtual std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const =0;
|
||||
virtual int3 getMapSize() const =0; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||
virtual std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const =0; //heroes that can be recruited
|
||||
@ -175,7 +175,7 @@ public:
|
||||
const StartInfo * getStartInfo() const;
|
||||
std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos) const;
|
||||
std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos) const;
|
||||
void getMarketOffer(int t1, int t2, int &give, int &rec, int mode=0) const;
|
||||
void getMarketOffer(int t1, int t2, int &give, int &rec, int mode=0) const; //t1 - type of given resource, t2 - type of received resource; give is the amount of resource t1 that can be traded for amount rec of resource t2 (one of them is 1)
|
||||
std::vector < const CGObjectInstance * > getFlaggableObjects(int3 pos) const;
|
||||
int3 getMapSize() const; //returns size of map - z is 1 for one - level map and 2 for two level map
|
||||
std::vector<const CGHeroInstance *> getAvailableHeroes(const CGTownInstance * town) const; //heroes that can be recruited
|
||||
|
@ -1599,6 +1599,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i
|
||||
bg2 = BitmapHandler::loadBitmap("TPSMITBK.bmp");
|
||||
blitAt(bg2,64,50,bmp);
|
||||
SDL_FreeSurface(bg2);
|
||||
|
||||
CCreatureAnimation cra(CGI->creh->creatures[creMachineID].animDefName);
|
||||
cra.nextFrameMiddle(bmp,170,120,true,0,false);
|
||||
char pom[75];
|
||||
@ -1607,16 +1608,20 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i
|
||||
printAtMiddle(CGI->generaltexth->jktexts[43],165,218,GEOR16,zwykly,bmp); //resource cost
|
||||
SDL_itoa(CGI->arth->artifacts[aid].price,pom,10);
|
||||
printAtMiddle(pom,165,290,GEOR13,zwykly,bmp);
|
||||
|
||||
pos.w = bmp->w;
|
||||
pos.h = bmp->h;
|
||||
pos.x = screen->w/2 - pos.w/2;
|
||||
pos.y = screen->h/2 - pos.h/2;
|
||||
|
||||
buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 42,pos.y + 312,"IBUY30.DEF",SDLK_RETURN);
|
||||
cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 224,pos.y + 312,"ICANCEL.DEF",SDLK_ESCAPE);
|
||||
|
||||
if(possible)
|
||||
buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid);
|
||||
else
|
||||
buy->bitmapOffset = 2;
|
||||
|
||||
blitAt(graphics->resources32->ourImages[6].bitmap,148,244,bmp);
|
||||
}
|
||||
|
||||
|
@ -34,8 +34,8 @@ public:
|
||||
CDefHandler* def;
|
||||
SDL_Surface* border;
|
||||
SDL_Surface* area;
|
||||
CBuildingRect(Structure *Str);
|
||||
~CBuildingRect();
|
||||
CBuildingRect(Structure *Str); //c-tor
|
||||
~CBuildingRect(); //d-tor
|
||||
void activate();
|
||||
void deactivate();
|
||||
bool operator<(const CBuildingRect & p2) const;
|
||||
@ -58,8 +58,8 @@ public:
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show(SDL_Surface * to);
|
||||
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner);
|
||||
~CHeroGSlot();
|
||||
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner); //c-tor
|
||||
~CHeroGSlot(); //d-tor
|
||||
};
|
||||
|
||||
class CCastleInterface : public CWindowWithGarrison
|
||||
@ -89,8 +89,8 @@ public:
|
||||
|
||||
std::vector<CBuildingRect*> buildings; //building id, building def, structure struct, border, filling
|
||||
|
||||
CCastleInterface(const CGTownInstance * Town);
|
||||
~CCastleInterface();
|
||||
CCastleInterface(const CGTownInstance * Town); //c-tor
|
||||
~CCastleInterface(); //d-tor
|
||||
void townChange();
|
||||
void show(SDL_Surface * to);
|
||||
void showAll(SDL_Surface * to);
|
||||
@ -124,9 +124,9 @@ public:
|
||||
void show(SDL_Surface * to);
|
||||
void activate();
|
||||
void deactivate();
|
||||
CBuildingBox(int id);
|
||||
CBuildingBox(int id, int x, int y);
|
||||
~CBuildingBox();
|
||||
CBuildingBox(int id); //c-tor
|
||||
CBuildingBox(int id, int x, int y); //c-tor
|
||||
~CBuildingBox(); //d-tor
|
||||
};
|
||||
|
||||
class CBuildWindow: public IShowActivable, public ClickableR
|
||||
@ -144,19 +144,19 @@ public:
|
||||
void show(SDL_Surface * to);
|
||||
void Buy();
|
||||
void close();
|
||||
CBuildWindow(int Tid, int Bid, int State, bool Mode);
|
||||
~CBuildWindow();
|
||||
CBuildWindow(int Tid, int Bid, int State, bool Mode); //c-tor
|
||||
~CBuildWindow(); //d-tor
|
||||
};
|
||||
|
||||
std::vector< std::vector<CBuildingBox*> >boxes;
|
||||
|
||||
AdventureMapButton *exit;
|
||||
|
||||
SDL_Surface * bg;
|
||||
SDL_Surface * bg; //background
|
||||
|
||||
|
||||
CHallInterface(CCastleInterface * owner);
|
||||
~CHallInterface();
|
||||
CHallInterface(CCastleInterface * owner); //c-tor
|
||||
~CHallInterface(); //d-tor
|
||||
void close();
|
||||
void show(SDL_Surface * to);
|
||||
void activate();
|
||||
@ -217,8 +217,8 @@ public:
|
||||
CMinorResDataBar resdatabar;
|
||||
|
||||
|
||||
CMageGuildScreen(CCastleInterface * owner);
|
||||
~CMageGuildScreen();
|
||||
CMageGuildScreen(CCastleInterface * owner); //c-tor
|
||||
~CMageGuildScreen(); //d-tor
|
||||
void close();
|
||||
void show(SDL_Surface * to);
|
||||
void activate();
|
||||
@ -229,10 +229,10 @@ class CBlacksmithDialog : public IShowActivable, public CIntObject
|
||||
{
|
||||
public:
|
||||
AdventureMapButton *buy, *cancel;
|
||||
SDL_Surface *bmp;
|
||||
SDL_Surface *bmp; //background
|
||||
|
||||
CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid);
|
||||
~CBlacksmithDialog();
|
||||
CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid); //c-tor
|
||||
~CBlacksmithDialog(); //d-tor
|
||||
void close();
|
||||
void show(SDL_Surface * to);
|
||||
void activate();
|
||||
|
@ -29,12 +29,12 @@ namespace boost
|
||||
class DLL_EXPORT CConsoleHandler
|
||||
{
|
||||
public:
|
||||
boost::function<void(const std::string &)> *cb;
|
||||
int curLvl;
|
||||
boost::function<void(const std::string &)> *cb; //function to be called when message is received
|
||||
int curLvl; //logging level
|
||||
int run();
|
||||
void setColor(int level);
|
||||
CConsoleHandler();
|
||||
~CConsoleHandler();
|
||||
void setColor(int level); //sets color of text appropriate for given logging level
|
||||
CConsoleHandler(); //c-tor
|
||||
~CConsoleHandler(); //d-tor
|
||||
#ifndef _WIN32
|
||||
static void killConsole(pthread_t hThread); //for windows only, use native handle to the thread
|
||||
#else
|
||||
|
@ -963,7 +963,7 @@ void CGameState::init(StartInfo * si, Mapa * map, int Seed)
|
||||
/*********give starting hero****************************************/
|
||||
for(int i=0;i<PLAYER_LIMIT;i++)
|
||||
{
|
||||
if((map->players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==RoE))
|
||||
if((map->players[i].generateHeroAtMainTown && map->players[i].hasMainTown) || (map->players[i].hasMainTown && map->version==CMapHeader::RoE))
|
||||
{
|
||||
int3 hpos = map->players[i].posOfMainTown;
|
||||
hpos.x+=1;// hpos.y+=1;
|
||||
@ -1343,25 +1343,25 @@ int CGameState::battleGetBattlefieldType(int3 tile)
|
||||
|
||||
switch(map->terrain[tile.x][tile.y][tile.z].tertype)
|
||||
{
|
||||
case dirt:
|
||||
case TerrainTile::dirt:
|
||||
return rand()%3+3;
|
||||
case sand:
|
||||
case TerrainTile::sand:
|
||||
return 2; //TODO: coast support
|
||||
case grass:
|
||||
case TerrainTile::grass:
|
||||
return rand()%2+6;
|
||||
case snow:
|
||||
case TerrainTile::snow:
|
||||
return rand()%2+10;
|
||||
case swamp:
|
||||
case TerrainTile::swamp:
|
||||
return 13;
|
||||
case rough:
|
||||
case TerrainTile::rough:
|
||||
return 23;
|
||||
case subterranean:
|
||||
case TerrainTile::subterranean:
|
||||
return 12;
|
||||
case lava:
|
||||
case TerrainTile::lava:
|
||||
return 8;
|
||||
case water:
|
||||
case TerrainTile::water:
|
||||
return 25;
|
||||
case rock:
|
||||
case TerrainTile::rock:
|
||||
return 15;
|
||||
default:
|
||||
return -1;
|
||||
@ -1564,7 +1564,7 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
|
||||
}
|
||||
else if(ID == 6) //shipyard
|
||||
{
|
||||
if(map->getTile(t->pos + int3(-1,3,0)).tertype != water && map->getTile(t->pos + int3(-3,3,0)).tertype != water)
|
||||
if(map->getTile(t->pos + int3(-1,3,0)).tertype != TerrainTile::water && map->getTile(t->pos + int3(-3,3,0)).tertype != TerrainTile::water)
|
||||
ret = 1; //lack of water
|
||||
}
|
||||
|
||||
@ -1598,7 +1598,7 @@ CPath * CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero)
|
||||
tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
|
||||
|
||||
if (!hero->canWalkOnSea())
|
||||
blockLandSea = (map->getTile(hpos).tertype != water); //block land if hero is on water and vice versa
|
||||
blockLandSea = (map->getTile(hpos).tertype != TerrainTile::water); //block land if hero is on water and vice versa
|
||||
else
|
||||
blockLandSea = boost::logic::indeterminate;
|
||||
|
||||
@ -1625,9 +1625,9 @@ CPath * CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero)
|
||||
node.coord.y = j;
|
||||
node.coord.z = dest.z;
|
||||
|
||||
if ((tinfo->tertype == rock) //it's rock
|
||||
|| ((blockLandSea) && (tinfo->tertype == water)) //it's sea and we cannot walk on sea
|
||||
|| ((!blockLandSea) && (tinfo->tertype != water)) //it's land and we cannot walk on land
|
||||
if ((tinfo->tertype == TerrainTile::rock) //it's rock
|
||||
|| ((blockLandSea) && (tinfo->tertype == TerrainTile::water)) //it's sea and we cannot walk on sea
|
||||
|| ((!blockLandSea) && (tinfo->tertype != TerrainTile::water)) //it's land and we cannot walk on land
|
||||
|| !getPlayer(hero->tempOwner)->fogOfWarMap[i][j][src.z] //tile is covered by the FoW
|
||||
)
|
||||
{
|
||||
|
@ -245,7 +245,7 @@ public:
|
||||
Mapa * map;
|
||||
std::map<ui8,PlayerState> players; //ID <-> player state
|
||||
std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
|
||||
std::vector<ui32> resVals;
|
||||
std::vector<ui32> resVals; //default values of resources in gold
|
||||
|
||||
struct DLL_EXPORT HeroesPool
|
||||
{
|
||||
@ -282,8 +282,8 @@ public:
|
||||
bool checkForVisitableDir(const int3 & src, const int3 & dst) const; //check if dst tile is visitable from dst tile
|
||||
CPath * getPath(int3 src, int3 dest, const CGHeroInstance * hero); //calculates path between src and dest; returns pointer to newly allocated CPath or NULL if path does not exists
|
||||
|
||||
CGameState();
|
||||
~CGameState();
|
||||
CGameState(); //c-tor
|
||||
~CGameState(); //d-tor
|
||||
void getNeighbours(int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand);
|
||||
int getMovementCost(const CGHeroInstance *h, int3 src, int3 dest, int remainingMovePoints=-1, bool checkLast=true);
|
||||
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
|
||||
|
@ -82,14 +82,14 @@ public:
|
||||
bool clicked;
|
||||
CHeroWindow * ourWindow;
|
||||
const CArtifact * ourArt;
|
||||
CArtPlace(const CArtifact * Art);
|
||||
CArtPlace(const CArtifact * Art); //c-tor
|
||||
void clickLeft (tribool down);
|
||||
void clickRight (tribool down);
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show(SDL_Surface * to);
|
||||
bool fitsHere(const CArtifact * art); //returns true if given artifact can be placed here
|
||||
~CArtPlace();
|
||||
~CArtPlace(); //d-tor
|
||||
};
|
||||
|
||||
class CHeroWindow: public CWindowWithGarrison, public virtual CIntObject
|
||||
|
10
CMessage.h
10
CMessage.h
@ -38,9 +38,9 @@ struct ComponentResolved
|
||||
SDL_Surface *img;
|
||||
std::vector<std::vector<SDL_Surface*> > * txt;
|
||||
|
||||
ComponentResolved();
|
||||
ComponentResolved(SComponent *Comp);
|
||||
~ComponentResolved();
|
||||
ComponentResolved(); //c-tor
|
||||
ComponentResolved(SComponent *Comp); //c-tor
|
||||
~ComponentResolved(); //d-tor
|
||||
};
|
||||
|
||||
struct ComponentsToBlit
|
||||
@ -49,8 +49,8 @@ struct ComponentsToBlit
|
||||
int w, h;
|
||||
|
||||
void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret);
|
||||
ComponentsToBlit(std::vector<SComponent*> & SComps, int maxw, SDL_Surface* _or);
|
||||
~ComponentsToBlit();
|
||||
ComponentsToBlit(std::vector<SComponent*> & SComps, int maxw, SDL_Surface* _or); //c-tor
|
||||
~ComponentsToBlit(); //d-tor
|
||||
};
|
||||
|
||||
class CMessage
|
||||
|
@ -2609,8 +2609,8 @@ bool CPlayerInterface::moveHero( const CGHeroInstance *h, CPath path )
|
||||
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
|
||||
stillMoveHero.data = CONTINUE_MOVE;
|
||||
|
||||
enum EterrainType currentTerrain = border; // not init yet
|
||||
enum EterrainType newTerrain;
|
||||
enum TerrainTile::EterrainType currentTerrain = TerrainTile::border; // not init yet
|
||||
enum TerrainTile::EterrainType newTerrain;
|
||||
int sh = -1;
|
||||
|
||||
for(int i=path.nodes.size()-1; i>0 && stillMoveHero.data == CONTINUE_MOVE; i--)
|
||||
@ -3464,6 +3464,7 @@ void CRecrutationWindow::activate()
|
||||
slider->activate();
|
||||
LOCPLINT->statusbar = bar;
|
||||
}
|
||||
|
||||
void CRecrutationWindow::deactivate()
|
||||
{
|
||||
ClickableL::deactivate();
|
||||
@ -3473,20 +3474,23 @@ void CRecrutationWindow::deactivate()
|
||||
cancel->deactivate();
|
||||
slider->deactivate();
|
||||
}
|
||||
|
||||
void CRecrutationWindow::show(SDL_Surface * to)
|
||||
{
|
||||
static char c=0;
|
||||
static char animCounter=0; //animation counter - for determining appropriate animation frame to be shown
|
||||
blitAt(bitmap,pos.x,pos.y,to);
|
||||
buy->show(to);
|
||||
max->show(to);
|
||||
cancel->show(to);
|
||||
slider->show(to);
|
||||
|
||||
char pom[15];
|
||||
SDL_itoa(creatures[which].amount-slider->value,pom,10); //available
|
||||
printAtMiddle(pom,pos.x+205,pos.y+252,GEOR13,zwykly,to);
|
||||
SDL_itoa(slider->value,pom,10); //recruit
|
||||
printAtMiddle(pom,pos.x+279,pos.y+252,GEOR13,zwykly,to);
|
||||
printAtMiddle(CGI->generaltexth->allTexts[16] + " " + CGI->creh->creatures[creatures[which].ID].namePl,pos.x+243,pos.y+32,GEOR16,tytulowy,to); //eg "Recruit Dragon flies"
|
||||
|
||||
int curx = pos.x+115-creatures[which].res.size()*16;
|
||||
for(int i=0;i<creatures[which].res.size();i++)
|
||||
{
|
||||
@ -3500,18 +3504,19 @@ void CRecrutationWindow::show(SDL_Surface * to)
|
||||
}
|
||||
|
||||
curx = pos.x + 192 + 102 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
|
||||
for(int i=0;i<creatures.size();i++)
|
||||
for(int i=0; i<creatures.size(); ++i)
|
||||
{
|
||||
creatures[i].pic->blitPic(to,curx-50,pos.y+130-65,!(c%4));
|
||||
creatures[i].pic->blitPic(to, curx-50, pos.y+130-65, !(animCounter%4));
|
||||
curx += 120;
|
||||
}
|
||||
c++;
|
||||
|
||||
++animCounter;
|
||||
bar->show(to);
|
||||
}
|
||||
|
||||
CRecrutationWindow::CRecrutationWindow(const std::vector<std::pair<int,int> > &Creatures, const boost::function<void(int,int)> &Recruit) //creatures - pairs<creature_ID,amount>
|
||||
:recruit(Recruit)
|
||||
:recruit(Recruit), which(0)
|
||||
{
|
||||
which = 0;
|
||||
creatures.resize(Creatures.size());
|
||||
amounts.resize(Creatures.size());
|
||||
for(int i=0;i<creatures.size();i++)
|
||||
@ -3526,7 +3531,7 @@ CRecrutationWindow::CRecrutationWindow(const std::vector<std::pair<int,int> > &C
|
||||
}
|
||||
SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPRCRT.bmp");
|
||||
graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID);
|
||||
bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo
|
||||
bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo //it wouldn't work on 8bpp map
|
||||
SDL_SetColorKey(bitmap,SDL_SRCCOLORKEY,SDL_MapRGB(bitmap->format,0,255,255));
|
||||
SDL_FreeSurface(hhlp);
|
||||
pos.x = screen->w/2 - bitmap->w/2;
|
||||
@ -3573,6 +3578,7 @@ CRecrutationWindow::CRecrutationWindow(const std::vector<std::pair<int,int> > &C
|
||||
}
|
||||
//buy->block(true); //not needed, will be blocked by initing slider on 0
|
||||
}
|
||||
|
||||
CRecrutationWindow::~CRecrutationWindow()
|
||||
{
|
||||
for(int i=0;i<creatures.size();i++)
|
||||
@ -3614,7 +3620,8 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int
|
||||
boost::algorithm::replace_first(title,"%s",CGI->creh->creatures[cid].namePl);
|
||||
printAtMiddle(title,150,34,GEOR16,tytulowy,bitmap);
|
||||
}
|
||||
CSplitWindow::~CSplitWindow()
|
||||
|
||||
CSplitWindow::~CSplitWindow() //d-tor
|
||||
{
|
||||
SDL_FreeSurface(bitmap);
|
||||
delete ok;
|
||||
@ -3622,6 +3629,7 @@ CSplitWindow::~CSplitWindow()
|
||||
delete slider;
|
||||
delete anim;
|
||||
}
|
||||
|
||||
void CSplitWindow::activate()
|
||||
{
|
||||
ClickableL::activate();
|
||||
@ -3630,6 +3638,7 @@ void CSplitWindow::activate()
|
||||
cancel->activate();
|
||||
slider->activate();
|
||||
}
|
||||
|
||||
void CSplitWindow::deactivate()
|
||||
{
|
||||
ClickableL::deactivate();
|
||||
@ -3638,15 +3647,18 @@ void CSplitWindow::deactivate()
|
||||
cancel->deactivate();
|
||||
slider->deactivate();
|
||||
}
|
||||
|
||||
void CSplitWindow::split()
|
||||
{
|
||||
gar->splitStacks(a2);
|
||||
close();
|
||||
}
|
||||
|
||||
void CSplitWindow::close()
|
||||
{
|
||||
LOCPLINT->popIntTotally(this);
|
||||
}
|
||||
|
||||
void CSplitWindow::sliderMoved(int to)
|
||||
{
|
||||
int all = a1+a2;
|
||||
@ -3654,6 +3666,7 @@ void CSplitWindow::sliderMoved(int to)
|
||||
if(slider)
|
||||
a1 = all - a2;
|
||||
}
|
||||
|
||||
void CSplitWindow::show(SDL_Surface * to)
|
||||
{
|
||||
blitAt(bitmap,pos.x,pos.y,to);
|
||||
@ -3665,6 +3678,7 @@ void CSplitWindow::show(SDL_Surface * to)
|
||||
anim->blitPic(to,pos.x+20,pos.y+54,false);
|
||||
anim->blitPic(to,pos.x+177,pos.y+54,false);
|
||||
}
|
||||
|
||||
void CSplitWindow::keyPressed (const SDL_KeyboardEvent & key)
|
||||
{
|
||||
if(key.state != SDL_PRESSED)
|
||||
@ -3705,9 +3719,9 @@ void CSplitWindow::clickLeft( boost::logic::tribool down )
|
||||
{
|
||||
Point click(LOCPLINT->current->motion.x,LOCPLINT->current->motion.y);
|
||||
click -= pos.topLeft();
|
||||
if(Rect(19,216,105,40).isIn(click))
|
||||
if(Rect(19,216,105,40).isIn(click)) //left picture
|
||||
which = 0;
|
||||
else if(Rect(175,216,105,40).isIn(click))
|
||||
else if(Rect(175,216,105,40).isIn(click)) //right picture
|
||||
which = 1;
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ public:
|
||||
{
|
||||
show(to);
|
||||
}
|
||||
virtual ~IShowable(){};
|
||||
virtual ~IShowable(){}; //d-tor
|
||||
};
|
||||
|
||||
class IStatusBar
|
||||
@ -232,7 +232,7 @@ class IActivable
|
||||
public:
|
||||
virtual void activate()=0;
|
||||
virtual void deactivate()=0;
|
||||
virtual ~IActivable(){};
|
||||
virtual ~IActivable(){}; //d-tor
|
||||
};
|
||||
class IShowActivable : public IShowable, public IActivable
|
||||
{
|
||||
@ -240,7 +240,7 @@ public:
|
||||
enum {WITH_GARRISON = 1};
|
||||
int type; //bin flags using etype
|
||||
IShowActivable();
|
||||
virtual ~IShowActivable(){};
|
||||
virtual ~IShowActivable(){}; //d-tor
|
||||
};
|
||||
|
||||
class CWindowWithGarrison : public IShowActivable
|
||||
@ -270,7 +270,7 @@ public:
|
||||
class CSimpleWindow : public IShowActivable, public virtual CIntObject
|
||||
{
|
||||
public:
|
||||
SDL_Surface * bitmap;
|
||||
SDL_Surface * bitmap; //background
|
||||
CIntObject * owner; //who made this window
|
||||
virtual void show(SDL_Surface * to);
|
||||
CSimpleWindow():bitmap(NULL),owner(NULL){}; //c-tor
|
||||
@ -301,7 +301,7 @@ class ClickableL : public virtual CIntObject //for left-clicks
|
||||
public:
|
||||
bool pressedL; //for determining if object is L-pressed
|
||||
ClickableL(); //c-tor
|
||||
virtual ~ClickableL();//{};
|
||||
virtual ~ClickableL();//{};//d-tor
|
||||
virtual void clickLeft (boost::logic::tribool down)=0;
|
||||
virtual void activate();
|
||||
virtual void deactivate();
|
||||
@ -311,7 +311,7 @@ class ClickableR : public virtual CIntObject //for right-clicks
|
||||
public:
|
||||
bool pressedR; //for determining if object is R-pressed
|
||||
ClickableR(); //c-tor
|
||||
virtual ~ClickableR();//{};
|
||||
virtual ~ClickableR();//{};//d-tor
|
||||
virtual void clickRight (boost::logic::tribool down)=0;
|
||||
virtual void activate()=0;
|
||||
virtual void deactivate()=0;
|
||||
@ -331,12 +331,14 @@ class KeyInterested : public virtual CIntObject
|
||||
public:
|
||||
bool captureAllKeys; //if true, only this object should get info about pressed keys
|
||||
KeyInterested(): captureAllKeys(false){}
|
||||
virtual ~KeyInterested();//{};
|
||||
virtual ~KeyInterested();//{};//d-tor
|
||||
virtual void keyPressed(const SDL_KeyboardEvent & key)=0;
|
||||
virtual void activate()=0;
|
||||
virtual void deactivate()=0;
|
||||
};
|
||||
|
||||
//class for binding keys to left mouse button clicks
|
||||
//classes wanting use it should have it as one of their base classes
|
||||
class KeyShortcut : public KeyInterested, public ClickableL
|
||||
{
|
||||
public:
|
||||
@ -352,7 +354,7 @@ class MotionInterested: public virtual CIntObject
|
||||
public:
|
||||
bool strongInterest; //if true - report all mouse movements, if not - only when hovered
|
||||
MotionInterested(){strongInterest=false;};
|
||||
virtual ~MotionInterested(){};
|
||||
virtual ~MotionInterested(){};//d-tor
|
||||
virtual void mouseMoved (const SDL_MouseMotionEvent & sEvent)=0;
|
||||
virtual void activate()=0;
|
||||
virtual void deactivate()=0;
|
||||
@ -408,7 +410,7 @@ public:
|
||||
bool delInner;
|
||||
|
||||
void show(SDL_Surface * to);
|
||||
CRClickPopupInt(IShowActivable *our, bool deleteInt);
|
||||
CRClickPopupInt(IShowActivable *our, bool deleteInt); //c-tor
|
||||
virtual ~CRClickPopupInt(); //d-tor
|
||||
};
|
||||
|
||||
@ -498,7 +500,7 @@ public:
|
||||
void deactivate();
|
||||
void show(SDL_Surface * to);
|
||||
CGarrisonSlot(CGarrisonInt *Owner, int x, int y, int IID, int Upg=0, const CCreature * Creature=NULL, int Count=0);
|
||||
~CGarrisonSlot();
|
||||
~CGarrisonSlot(); //d-tor
|
||||
};
|
||||
|
||||
class CGarrisonInt :public CIntObject
|
||||
@ -514,8 +516,8 @@ public:
|
||||
const CCreatureSet *set1; //top set of creatures
|
||||
const CCreatureSet *set2; //bottom set of creatures
|
||||
|
||||
std::vector<CGarrisonSlot*> *sup, *sdown; //TODO: comment me
|
||||
const CArmedInstance *oup, *odown; //TODO: comment me
|
||||
std::vector<CGarrisonSlot*> *sup, *sdown; //slots of upper and lower garrison
|
||||
const CArmedInstance *oup, *odown; //upper and lower garrisons (heroes or towns)
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
@ -581,7 +583,7 @@ public:
|
||||
//overloaded funcs from CGameInterface
|
||||
void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished
|
||||
void garrisonChanged(const CGObjectInstance * obj);
|
||||
void heroArtifactSetChanged(const CGHeroInstance*hero);
|
||||
void heroArtifactSetChanged(const CGHeroInstance* hero);
|
||||
void heroCreated(const CGHeroInstance* hero);
|
||||
void heroGotLevel(const CGHeroInstance *hero, int pskill, std::vector<ui16> &skills, boost::function<void(ui32)> &callback);
|
||||
void heroInGarrisonChange(const CGTownInstance *town);
|
||||
@ -597,8 +599,8 @@ public:
|
||||
//void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID);
|
||||
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
|
||||
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
|
||||
void tileHidden(const std::set<int3> &pos);
|
||||
void tileRevealed(const std::set<int3> &pos);
|
||||
void tileHidden(const std::set<int3> &pos); //called when given tiles become hidden under fog of war
|
||||
void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles
|
||||
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
|
||||
@ -623,7 +625,7 @@ public:
|
||||
|
||||
|
||||
//-------------//
|
||||
bool shiftPressed() const;
|
||||
bool shiftPressed() const; //determines if shift key is pressed (left or right or both)
|
||||
void redrawHeroWin(const CGHeroInstance * hero);
|
||||
void updateWater();
|
||||
void showComp(SComponent comp); //TODO: comment me
|
||||
@ -785,7 +787,7 @@ public:
|
||||
AdventureMapButton *ok, *cancel;
|
||||
SDL_Surface *bitmap; //background
|
||||
int a1, a2, c; //TODO: comment me
|
||||
bool which; //TODO: comment me
|
||||
bool which; //which creature is selected
|
||||
int last; //0/1/2 - at least one creature must be in the src/dst/both stacks; -1 - no restrictions
|
||||
|
||||
CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last = -1, int val=0); //c-tor; val - initial amount of second stack
|
||||
@ -806,12 +808,12 @@ public:
|
||||
//bool active; //TODO: comment me
|
||||
int type;//0 - rclick popup; 1 - normal window
|
||||
SDL_Surface *bitmap; //background
|
||||
char anf; //TODO: comment me
|
||||
char anf; //animation counter
|
||||
std::string count; //creature count in text format
|
||||
|
||||
boost::function<void()> dsm; //TODO: comment me
|
||||
CCreaturePic *anim;
|
||||
CCreature *c;
|
||||
boost::function<void()> dsm; //dismiss button callback
|
||||
CCreaturePic *anim; //related creature's animation
|
||||
CCreature *c; //related creature
|
||||
std::vector<SComponent*> upgResCost; //cost of upgrade (if not possible then empty)
|
||||
|
||||
AdventureMapButton *dismiss, *upgrade, *ok;
|
||||
@ -878,9 +880,9 @@ public:
|
||||
CTradeableItem *hLeft, *hRight; //highlighted items (NULL if no highlight)
|
||||
|
||||
int mode,//0 - res<->res; 1 - res<->plauer; 2 - buy artifact; 3 - sell artifact
|
||||
r1, r2; //TODO: comment me
|
||||
r1, r2; //suggested amounts of traded resources
|
||||
AdventureMapButton *ok, *max, *deal;
|
||||
CSlider *slider;
|
||||
CSlider *slider; //for choosing amount to be exchanged
|
||||
|
||||
void activate();
|
||||
void deactivate();
|
||||
@ -936,7 +938,7 @@ public:
|
||||
} h1, h2; //recruitable heroes
|
||||
|
||||
SDL_Surface *bg; //background
|
||||
CStatusBar *bar;
|
||||
CStatusBar *bar; //tavern's internal status bar
|
||||
int selected;//0 (left) or 1 (right)
|
||||
|
||||
AdventureMapButton *thiefGuild, *cancel, *recruit;
|
||||
@ -977,15 +979,15 @@ public:
|
||||
class CGarrisonWindow : public CWindowWithGarrison, public CIntObject
|
||||
{
|
||||
public:
|
||||
SDL_Surface *bg;
|
||||
SDL_Surface *bg; //background surface
|
||||
AdventureMapButton *split, *quit;
|
||||
|
||||
void close();
|
||||
void activate();
|
||||
void deactivate();
|
||||
void show(SDL_Surface * to);
|
||||
CGarrisonWindow(const CArmedInstance *up, const CGHeroInstance *down);
|
||||
~CGarrisonWindow();
|
||||
CGarrisonWindow(const CArmedInstance *up, const CGHeroInstance *down); //c-tor
|
||||
~CGarrisonWindow(); //d-tor
|
||||
};
|
||||
|
||||
extern CPlayerInterface * LOCPLINT;
|
||||
|
10
CPreGame.cpp
10
CPreGame.cpp
@ -948,16 +948,16 @@ void MapSel::printMaps(int elemIdx)
|
||||
int temp=-1;
|
||||
switch (curMap->version)
|
||||
{
|
||||
case RoE:
|
||||
case CMapHeader::RoE:
|
||||
temp=0;
|
||||
break;
|
||||
case AB:
|
||||
case CMapHeader::AB:
|
||||
temp=1;
|
||||
break;
|
||||
case SoD:
|
||||
case CMapHeader::SoD:
|
||||
temp=2;
|
||||
break;
|
||||
case WoG:
|
||||
case CMapHeader::WoG:
|
||||
temp=3;
|
||||
break;
|
||||
default:
|
||||
@ -1355,7 +1355,7 @@ void MapSel::select(int which, bool updateMapsList, bool forceSettingsUpdate)
|
||||
}
|
||||
pset.heroPortrait=-1;
|
||||
if (!
|
||||
(((curVector()[which]->players[i].generateHeroAtMainTown || curVector()[which]->version==RoE)
|
||||
(((curVector()[which]->players[i].generateHeroAtMainTown || curVector()[which]->version==CMapHeader::RoE)
|
||||
&& curVector()[which]->players[i].hasMainTown)
|
||||
|| curVector()[which]->players[i].p8)
|
||||
)
|
||||
|
@ -42,8 +42,8 @@ public:
|
||||
void convert();
|
||||
SDL_Surface * getSurface(); //for standard H3 PCX
|
||||
//SDL_Surface * getSurfaceZ(); //for ZSoft PCX
|
||||
CPCXConv(){pcx=bmp=NULL;pcxs=bmps=0;};
|
||||
~CPCXConv(){if (pcxs) delete[] pcx; if(bmps) delete[] bmp;}
|
||||
CPCXConv(){pcx=bmp=NULL;pcxs=bmps=0;}; //c-tor
|
||||
~CPCXConv(){if (pcxs) delete[] pcx; if(bmps) delete[] bmp;} //d-tor
|
||||
};
|
||||
namespace BitmapHandler
|
||||
{
|
||||
|
@ -70,8 +70,8 @@ namespace config
|
||||
std::map<std::pair<int,int>, GUIOptions > guiOptions;
|
||||
GUIOptions *go(); //return pointer to gui options appropriate for used screen resolution
|
||||
void init();
|
||||
CConfigHandler(void);
|
||||
~CConfigHandler(void);
|
||||
CConfigHandler(void); //c-tor
|
||||
~CConfigHandler(void); //d-tor
|
||||
};
|
||||
}
|
||||
extern config::CConfigHandler conf;
|
||||
|
17
global.h
17
global.h
@ -44,23 +44,16 @@ typedef boost::int8_t si8; //signed int 8 bits (1 byte)
|
||||
*/
|
||||
|
||||
enum Ecolor {RED, BLUE, TAN, GREEN, ORANGE, PURPLE, TEAL, PINK}; //player's colors
|
||||
enum EterrainType {border=-1, dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock};
|
||||
enum Eriver {noRiver=0, clearRiver, icyRiver, muddyRiver, lavaRiver};
|
||||
enum Eroad {dirtRoad=1, grazvelRoad, cobblestoneRoad};
|
||||
enum Eformat { WoG=0x33, AB=0x15, RoE=0x0e, SoD=0x1c};
|
||||
enum EvictoryConditions {artifact, gatherTroop, gatherResource, buildCity, buildGrail, beatHero,
|
||||
captureCity, beatMonster, takeDwellings, takeMines, transportItem, winStandard=255};
|
||||
enum ElossCon {lossCastle, lossHero, timeExpires, lossStandard=255};
|
||||
enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHEMIST, HERO_WIZARD,
|
||||
HERO_DEMONIAC, HERO_HERETIC, HERO_DEATHKNIGHT, HERO_NECROMANCER, HERO_WARLOCK, HERO_OVERLORD,
|
||||
HERO_BARBARIAN, HERO_BATTLEMAGE, HERO_BEASTMASTER, HERO_WITCH, HERO_PLANESWALKER, HERO_ELEMENTALIST};
|
||||
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
||||
enum EAbilities {DOUBLE_WIDE, FLYING, SHOOTER, TWO_HEX_ATTACK, SIEGE_ABILITY, SIEGE_WEAPON,
|
||||
KING1, KING2, KING3, MIND_IMMUNITY, NO_OBSTACLE_PENALTY, NO_CLOSE_COMBAT_PENALTY,
|
||||
JOUSTING, FIRE_IMMUNITY, TWICE_ATTACK, NO_ENEMY_RETALIATION, NO_MORAL_PENALTY,
|
||||
UNDEAD, MULTI_HEAD_ATTACK, EXTENDED_RADIOUS_SHOOTER, GHOST, RAISES_MORALE,
|
||||
LOWERS_MORALE, DRAGON, STRIKE_AND_RETURN, FEARLESS, REBIRTH, NOT_ACTIVE}; //some flags are used only for battles
|
||||
KING1, KING2, KING3, MIND_IMMUNITY, NO_OBSTACLE_PENALTY, NO_CLOSE_COMBAT_PENALTY,
|
||||
JOUSTING, FIRE_IMMUNITY, TWICE_ATTACK, NO_ENEMY_RETALIATION, NO_MORAL_PENALTY,
|
||||
UNDEAD, MULTI_HEAD_ATTACK, EXTENDED_RADIOUS_SHOOTER, GHOST, RAISES_MORALE,
|
||||
LOWERS_MORALE, DRAGON, STRIKE_AND_RETURN, FEARLESS, REBIRTH, NOT_ACTIVE}; //some flags are used only for battles
|
||||
enum ECombatInfo{ALIVE = NOT_ACTIVE+1, SUMMONED, CLONED, HAD_MORALE, WAITING, MOVED, DEFENDING};
|
||||
|
||||
class CGameInfo;
|
||||
extern CGameInfo* CGI;
|
||||
|
||||
|
@ -42,8 +42,8 @@ void CArtHandler::loadArtifacts(bool onlyTxt)
|
||||
{
|
||||
std::vector<ui16> slots;
|
||||
slots += 17, 16, 15,14,13, 18, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0;
|
||||
std::map<char,EartClass> classes =
|
||||
map_list_of('S',ART_SPECIAL)('T',ART_TREASURE)('N',ART_MINOR)('J',ART_MAJOR)('R',ART_RELIC);
|
||||
std::map<char, CArtifact::EartClass> classes =
|
||||
map_list_of('S',CArtifact::ART_SPECIAL)('T',CArtifact::ART_TREASURE)('N',CArtifact::ART_MINOR)('J',CArtifact::ART_MAJOR)('R',CArtifact::ART_RELIC);
|
||||
std::string buf = bitmaph->getTextFile("ARTRAITS.TXT"), dump, pom;
|
||||
int it=0;
|
||||
for(int i=0; i<2; ++i)
|
||||
@ -118,16 +118,16 @@ void CArtHandler::sortArts()
|
||||
{
|
||||
switch (artifacts[i].aClass)
|
||||
{
|
||||
case ART_TREASURE:
|
||||
case CArtifact::ART_TREASURE:
|
||||
treasures.push_back(&(artifacts[i]));
|
||||
break;
|
||||
case ART_MINOR:
|
||||
case CArtifact::ART_MINOR:
|
||||
minors.push_back(&(artifacts[i]));
|
||||
break;
|
||||
case ART_MAJOR:
|
||||
case CArtifact::ART_MAJOR:
|
||||
majors.push_back(&(artifacts[i]));
|
||||
break;
|
||||
case ART_RELIC:
|
||||
case CArtifact::ART_RELIC:
|
||||
relics.push_back(&(artifacts[i]));
|
||||
break;
|
||||
}
|
||||
|
@ -21,8 +21,9 @@ class DLL_EXPORT CArtifact //container for artifacts
|
||||
{
|
||||
std::string name, description; //set if custom
|
||||
public:
|
||||
const std::string &Name() const;
|
||||
const std::string &Description() const;
|
||||
enum EartClass {ART_SPECIAL=1, ART_TREASURE=2, ART_MINOR=4, ART_MAJOR=8, ART_RELIC=16}; //artifact classes
|
||||
const std::string &Name() const; //getter
|
||||
const std::string &Description() const; //getter
|
||||
|
||||
ui32 price;
|
||||
std::vector<ui16> possibleSlots; //ids of slots where artifact can be placed
|
||||
|
@ -39,7 +39,7 @@ public:
|
||||
std::map<int, std::pair<std::string,std::vector< std::vector< std::vector<int> > > > > hall; //map<castle ID, pair<hall bg name, std::vector< std::vector<building id> >[5]> - external vector is the vector of buildings in the row, internal is the list of buildings for the specific slot
|
||||
|
||||
void loadBuildings(); //main loader
|
||||
~CBuildingHandler();
|
||||
~CBuildingHandler(); //d-tor
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -45,8 +45,8 @@ public:
|
||||
bool alphaTransformed;
|
||||
bool notFreeImgs;
|
||||
|
||||
CDefHandler();
|
||||
~CDefHandler();
|
||||
CDefHandler(); //c-tor
|
||||
~CDefHandler(); //d-tor
|
||||
static void print (std::ostream & stream, int nr, int bytcon);
|
||||
int readNormalNr (int pos, int bytCon, unsigned char * str=NULL, bool cyclic=false);
|
||||
static unsigned char *writeNormalNr (int nr, int bytCon);
|
||||
@ -64,7 +64,7 @@ class CDefEssential //DefHandler with images only
|
||||
{
|
||||
public:
|
||||
std::vector<Cimage> ourImages;
|
||||
~CDefEssential();
|
||||
~CDefEssential(); //d-tor
|
||||
};
|
||||
|
||||
|
||||
|
@ -167,19 +167,19 @@ void CHeroHandler::loadHeroes()
|
||||
int numberOfCurrentClassHeroes = 0;
|
||||
int currentClass = 0;
|
||||
int additHero = 0;
|
||||
EHeroClasses addTab[12];
|
||||
addTab[0] = HERO_KNIGHT;
|
||||
addTab[1] = HERO_WITCH;
|
||||
addTab[2] = HERO_KNIGHT;
|
||||
addTab[3] = HERO_WIZARD;
|
||||
addTab[4] = HERO_RANGER;
|
||||
addTab[5] = HERO_BARBARIAN;
|
||||
addTab[6] = HERO_DEATHKNIGHT;
|
||||
addTab[7] = HERO_WARLOCK;
|
||||
addTab[8] = HERO_KNIGHT;
|
||||
addTab[9] = HERO_WARLOCK;
|
||||
addTab[10] = HERO_BARBARIAN;
|
||||
addTab[11] = HERO_DEMONIAC;
|
||||
CHero::EHeroClasses addTab[12];
|
||||
addTab[0] = CHero::KNIGHT;
|
||||
addTab[1] = CHero::WITCH;
|
||||
addTab[2] = CHero::KNIGHT;
|
||||
addTab[3] = CHero::WIZARD;
|
||||
addTab[4] = CHero::RANGER;
|
||||
addTab[5] = CHero::BARBARIAN;
|
||||
addTab[6] = CHero::DEATHKNIGHT;
|
||||
addTab[7] = CHero::WARLOCK;
|
||||
addTab[8] = CHero::KNIGHT;
|
||||
addTab[9] = CHero::WARLOCK;
|
||||
addTab[10] = CHero::BARBARIAN;
|
||||
addTab[11] = CHero::DEMONIAC;
|
||||
|
||||
|
||||
for (int i=0; i<HEROES_QUANTITY; i++)
|
||||
@ -187,7 +187,7 @@ void CHeroHandler::loadHeroes()
|
||||
CHero * nher = new CHero;
|
||||
if(currentClass<18)
|
||||
{
|
||||
nher->heroType = (EHeroClasses)currentClass;
|
||||
nher->heroType = static_cast<CHero::EHeroClasses>(currentClass);
|
||||
++numberOfCurrentClassHeroes;
|
||||
if(numberOfCurrentClassHeroes==8)
|
||||
{
|
||||
|
@ -22,7 +22,11 @@ class CGHeroInstance;
|
||||
class DLL_EXPORT CHero
|
||||
{
|
||||
public:
|
||||
std::string name;
|
||||
enum EHeroClasses {KNIGHT, CLERIC, RANGER, DRUID, ALCHEMIST, WIZARD,
|
||||
DEMONIAC, HERETIC, DEATHKNIGHT, NECROMANCER, WARLOCK, OVERLORD,
|
||||
BARBARIAN, BATTLEMAGE, BEASTMASTER, WITCH, PLANESWALKER, ELEMENTALIST};
|
||||
|
||||
std::string name; //name of hero
|
||||
int ID;
|
||||
int lowStack[3], highStack[3]; //amount of units; described below
|
||||
std::string refTypeStack[3]; //reference names of units appearing in hero's army if he is recruited in tavern
|
||||
@ -44,15 +48,15 @@ public:
|
||||
ui32 skillLimit; //how many secondary skills can hero learn
|
||||
std::string name;
|
||||
float aggression;
|
||||
int initialAttack, initialDefence, initialPower, initialKnowledge;
|
||||
int initialAttack, initialDefence, initialPower, initialKnowledge; //initial values of primary skills
|
||||
std::vector<std::pair<int,int> > primChance;//primChance[PRIMARY_SKILL_ID] - first is for levels 2 - 9, second for 10+;;; probability (%) of getting point of primary skill when getting new level
|
||||
std::vector<int> proSec; //probabilities of gaining secondary skills (out of 112), in id order
|
||||
int selectionProbability[9]; //probability of selection in towns
|
||||
std::vector<int> terrCosts; //default costs of going through terrains: dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock; -1 means terrain is imapassable
|
||||
|
||||
int chooseSecSkill(const std::set<int> & possibles) const; //picks secondary skill out from given possibilities
|
||||
CHeroClass();
|
||||
~CHeroClass();
|
||||
CHeroClass(); //c-tor
|
||||
~CHeroClass(); //d-tor
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
@ -83,7 +87,7 @@ struct DLL_EXPORT CObstacleInfo
|
||||
class DLL_EXPORT CHeroHandler
|
||||
{
|
||||
public:
|
||||
std::vector<CHero*> heroes; //by³o nodrze
|
||||
std::vector<CHero*> heroes; //by³o nodrze //changed from nodrze
|
||||
std::vector<CHeroClass *> heroClasses;
|
||||
std::vector<int> expPerLevel; //expPerLEvel[i] is amount of exp needed to reach level i; if it is not in this vector, multiplicate last value by 1,2 to get next value
|
||||
|
||||
@ -102,17 +106,17 @@ public:
|
||||
|
||||
std::map<int, CObstacleInfo> obstacles; //info about obstacles that may be placed on battlefield
|
||||
|
||||
void loadObstacles();
|
||||
void loadObstacles(); //loads info about obstacles
|
||||
|
||||
unsigned int level(unsigned int experience);
|
||||
unsigned int reqExp(unsigned int level);
|
||||
unsigned int level(unsigned int experience); //calculates level corresponding to given experience amount
|
||||
unsigned int reqExp(unsigned int level); //calculates experience resuired for given level
|
||||
|
||||
void loadHeroes();
|
||||
void loadHeroClasses();
|
||||
void initHeroClasses();
|
||||
void initTerrainCosts();
|
||||
CHeroHandler();
|
||||
~CHeroHandler();
|
||||
CHeroHandler(); //c-tor
|
||||
~CHeroHandler(); //d-tor
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -277,13 +277,13 @@ unsigned int CGHeroInstance::getTileCost(const TerrainTile &dest, const TerrainT
|
||||
int road = std::min(dest.malle,from.malle); //used road ID
|
||||
switch(road)
|
||||
{
|
||||
case dirtRoad:
|
||||
case TerrainTile::dirtRoad:
|
||||
ret = 75;
|
||||
break;
|
||||
case grazvelRoad:
|
||||
case TerrainTile::grazvelRoad:
|
||||
ret = 65;
|
||||
break;
|
||||
case cobblestoneRoad:
|
||||
case TerrainTile::cobblestoneRoad:
|
||||
ret = 50;
|
||||
break;
|
||||
default:
|
||||
@ -867,18 +867,19 @@ int CGHeroInstance::valOfBonuses( HeroBonus::BonusType type, int subtype /*= -1*
|
||||
|
||||
bool CGHeroInstance::hasBonusOfType(HeroBonus::BonusType type, int subtype /*= -1*/) const
|
||||
{
|
||||
if(subtype == -1)
|
||||
if(subtype == -1) //any subtype
|
||||
{
|
||||
for(std::list<HeroBonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++)
|
||||
if(i->type == type)
|
||||
return true;
|
||||
}
|
||||
else
|
||||
else //given subtype
|
||||
{
|
||||
for(std::list<HeroBonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++)
|
||||
if(i->type == type && i->subtype == subtype)
|
||||
return true;
|
||||
}
|
||||
throw "CGHeroInstance::hasBonusOfType - we shouln't be here!";
|
||||
}
|
||||
|
||||
int CGTownInstance::getSightRadious() const //returns sight distance
|
||||
@ -2884,7 +2885,7 @@ void CGOnceVisitable::initObj()
|
||||
{
|
||||
artOrRes = 1;
|
||||
std::vector<CArtifact*> arts;
|
||||
cb->getAllowed(arts, ART_TREASURE | ART_MINOR | ART_MAJOR);
|
||||
cb->getAllowed(arts, CArtifact::ART_TREASURE | CArtifact::ART_MINOR | CArtifact::ART_MAJOR);
|
||||
bonusType = arts[ran() % arts.size()]->id;
|
||||
}
|
||||
else
|
||||
@ -2910,13 +2911,13 @@ void CGOnceVisitable::initObj()
|
||||
|
||||
int hlp = ran()%100;
|
||||
if(hlp < 30)
|
||||
cb->getAllowed(arts,ART_TREASURE);
|
||||
cb->getAllowed(arts,CArtifact::ART_TREASURE);
|
||||
else if(hlp < 80)
|
||||
cb->getAllowed(arts,ART_MINOR);
|
||||
cb->getAllowed(arts,CArtifact::ART_MINOR);
|
||||
else if(hlp < 95)
|
||||
cb->getAllowed(arts,ART_MAJOR);
|
||||
cb->getAllowed(arts,CArtifact::ART_MAJOR);
|
||||
else
|
||||
cb->getAllowed(arts,ART_RELIC);
|
||||
cb->getAllowed(arts,CArtifact::ART_RELIC);
|
||||
|
||||
bonusType = arts[ran() % arts.size()]->id;
|
||||
}
|
||||
@ -2934,7 +2935,7 @@ void CGOnceVisitable::initObj()
|
||||
{
|
||||
artOrRes = 1;
|
||||
std::vector<CArtifact*> arts;
|
||||
cb->getAllowed(arts, ART_TREASURE | ART_MINOR);
|
||||
cb->getAllowed(arts, CArtifact::ART_TREASURE | CArtifact::ART_MINOR);
|
||||
bonusType = arts[ran() % arts.size()]->id;
|
||||
}
|
||||
else //2 - 5 of non-gold resource
|
||||
|
@ -150,7 +150,7 @@ public:
|
||||
class DLL_EXPORT CPlayersVisited: public CGObjectInstance
|
||||
{
|
||||
public:
|
||||
std::set<ui8> players;
|
||||
std::set<ui8> players; //players that visited this object
|
||||
|
||||
bool hasVisited(ui8 player) const;
|
||||
void setPropertyDer(ui8 what, ui32 val);//synchr
|
||||
@ -342,7 +342,7 @@ public:
|
||||
int creatureGrowth(const int & level) const;
|
||||
bool hasFort() const;
|
||||
bool hasCapitol() const;
|
||||
int dailyIncome() const;
|
||||
int dailyIncome() const; //calculates daily income of this town
|
||||
int spellsAtLevel(int level, bool checkGuild) const; //levels are counted from 1 (1 - 5)
|
||||
|
||||
CGTownInstance();
|
||||
@ -464,8 +464,8 @@ class DLL_EXPORT CGSeerHut : public CGObjectInstance, public CQuest
|
||||
public:
|
||||
ui8 rewardType; //type of reward: 0 - no reward; 1 - experience; 2 - mana points; 3 - morale bonus; 4 - luck bonus; 5 - resources; 6 - main ability bonus (attak, defence etd.); 7 - secondary ability gain; 8 - artifact; 9 - spell; 10 - creature
|
||||
|
||||
si32 rID;
|
||||
si32 rVal;
|
||||
si32 rID; //reward ID
|
||||
si32 rVal; //reward value
|
||||
|
||||
template <typename Handler> void serialize(Handler &h, const int version)
|
||||
{
|
||||
|
@ -45,8 +45,8 @@ private:
|
||||
public:
|
||||
std::vector<Entry> entries;
|
||||
std::map<std::string, int> fimap; // map of wav file and index
|
||||
~CSndHandler();
|
||||
CSndHandler(std::string fname);
|
||||
~CSndHandler(); //d-tor
|
||||
CSndHandler(std::string fname); //c-tor
|
||||
void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file
|
||||
const char * extract (std::string srcfile, int & size); //return selecte file data, NULL if file doesn't exist
|
||||
void extract(int index, std::string dstfile); //saves selected file
|
||||
@ -67,8 +67,8 @@ protected:
|
||||
bool opened;
|
||||
public:
|
||||
std::vector<Entry> entries;
|
||||
~CVidHandler();
|
||||
CVidHandler(std::string fname);
|
||||
~CVidHandler(); //d-tor
|
||||
CVidHandler(std::string fname); //c-tor
|
||||
std::ifstream & extract(std::string srcfile);
|
||||
void extract(std::string srcfile, std::string dstfile, bool caseSens=true); //saves selected file
|
||||
unsigned char * extract (std::string srcfile, int & size); //return selecte file,
|
||||
|
@ -67,8 +67,8 @@ public:
|
||||
std::map<int,std::map<int, Structure*> > structures; // <town ID, <structure ID, structure>>
|
||||
std::map<int, std::map<int,std::set<int> > > requirements; //requirements[town_id][structure_id] -> set of required buildings
|
||||
|
||||
CTownHandler();
|
||||
~CTownHandler();
|
||||
CTownHandler(); //c-tor
|
||||
~CTownHandler(); //d-tor
|
||||
void loadNames();
|
||||
void loadStructures();
|
||||
|
||||
|
@ -123,7 +123,7 @@ public:
|
||||
const char *GetLibExtension();
|
||||
void *FindAddress234(const char *symbol);
|
||||
|
||||
virtual ~DLLHandler();
|
||||
virtual ~DLLHandler(); //d-tor
|
||||
};
|
||||
|
||||
class CBIKHandler
|
||||
|
@ -136,12 +136,12 @@ void IGameCallback::getAllowedArts(std::vector<CArtifact*> &out, std::vector<CAr
|
||||
|
||||
void IGameCallback::getAllowed(std::vector<CArtifact*> &out, int flags)
|
||||
{
|
||||
if(flags & ART_TREASURE)
|
||||
if(flags & CArtifact::ART_TREASURE)
|
||||
getAllowedArts(out,&CArtHandler::treasures);
|
||||
if(flags & ART_MINOR)
|
||||
if(flags & CArtifact::ART_MINOR)
|
||||
getAllowedArts(out,&CArtHandler::minors);
|
||||
if(flags & ART_MAJOR)
|
||||
if(flags & CArtifact::ART_MAJOR)
|
||||
getAllowedArts(out,&CArtHandler::majors);
|
||||
if(flags & ART_RELIC)
|
||||
if(flags & CArtifact::ART_RELIC)
|
||||
getAllowedArts(out,&CArtHandler::relics);
|
||||
}
|
@ -39,14 +39,14 @@ struct SharedMem
|
||||
boost::interprocess::mapped_region *mr;
|
||||
ServerReady *sr;
|
||||
|
||||
SharedMem()
|
||||
SharedMem() //c-tor
|
||||
:smo(boost::interprocess::open_or_create,"vcmi_memory",boost::interprocess::read_write)
|
||||
{
|
||||
smo.truncate(sizeof(ServerReady));
|
||||
mr = new boost::interprocess::mapped_region(smo,boost::interprocess::read_write);
|
||||
sr = new(mr->get_address())ServerReady();
|
||||
};
|
||||
~SharedMem()
|
||||
~SharedMem() //d-tor
|
||||
{
|
||||
delete mr;
|
||||
boost::interprocess::shared_memory_object::remove("vcmi_memory");
|
||||
|
12
map.cpp
12
map.cpp
@ -1238,11 +1238,11 @@ void Mapa::readTerrain( unsigned char * bufor, int &i)
|
||||
{
|
||||
for (int z=0; z<height; z++)
|
||||
{
|
||||
terrain[z][c][0].tertype = (EterrainType)(bufor[i++]);
|
||||
terrain[z][c][0].tertype = static_cast<TerrainTile::EterrainType>(bufor[i++]);
|
||||
terrain[z][c][0].terview = bufor[i++];
|
||||
terrain[z][c][0].nuine = (Eriver)bufor[i++];
|
||||
terrain[z][c][0].nuine = static_cast<TerrainTile::Eriver>(bufor[i++]);
|
||||
terrain[z][c][0].rivDir = bufor[i++];
|
||||
terrain[z][c][0].malle = (Eroad)bufor[i++];
|
||||
terrain[z][c][0].malle = static_cast<TerrainTile::Eroad>(bufor[i++]);
|
||||
terrain[z][c][0].roadDir = bufor[i++];
|
||||
terrain[z][c][0].siodmyTajemniczyBajt = bufor[i++];
|
||||
terrain[z][c][0].blocked = 0;
|
||||
@ -1255,11 +1255,11 @@ void Mapa::readTerrain( unsigned char * bufor, int &i)
|
||||
{
|
||||
for (int z=0; z<height; z++)
|
||||
{
|
||||
terrain[z][c][1].tertype = (EterrainType)(bufor[i++]);
|
||||
terrain[z][c][1].tertype = static_cast<TerrainTile::EterrainType>(bufor[i++]);
|
||||
terrain[z][c][1].terview = bufor[i++];
|
||||
terrain[z][c][1].nuine = (Eriver)bufor[i++];
|
||||
terrain[z][c][1].nuine = static_cast<TerrainTile::Eriver>(bufor[i++]);
|
||||
terrain[z][c][1].rivDir = bufor[i++];
|
||||
terrain[z][c][1].malle = (Eroad)bufor[i++];
|
||||
terrain[z][c][1].malle = static_cast<TerrainTile::Eroad>(bufor[i++]);
|
||||
terrain[z][c][1].roadDir = bufor[i++];
|
||||
terrain[z][c][1].siodmyTajemniczyBajt = bufor[i++];
|
||||
terrain[z][c][1].blocked = 0;
|
||||
|
5
map.h
5
map.h
@ -66,6 +66,10 @@ public:
|
||||
};
|
||||
struct DLL_EXPORT TerrainTile
|
||||
{
|
||||
enum EterrainType {border=-1, dirt, sand, grass, snow, swamp, rough, subterranean, lava, water, rock};
|
||||
enum Eriver {noRiver=0, clearRiver, icyRiver, muddyRiver, lavaRiver};
|
||||
enum Eroad {dirtRoad=1, grazvelRoad, cobblestoneRoad};
|
||||
|
||||
EterrainType tertype; // type of terrain
|
||||
unsigned char terview; // look of terrain
|
||||
Eriver nuine; // type of Eriver (0 if there is no Eriver)
|
||||
@ -199,6 +203,7 @@ public:
|
||||
class DLL_EXPORT CMapHeader
|
||||
{
|
||||
public:
|
||||
enum Eformat { WoG=0x33, AB=0x15, RoE=0x0e, SoD=0x1c};
|
||||
Eformat version; // version of map Eformat
|
||||
ui8 areAnyPLayers; // if there are any playable players on map
|
||||
si32 height, width, twoLevel; //sizes
|
||||
|
@ -30,59 +30,59 @@ extern SDL_Surface * screen;
|
||||
|
||||
std::string nameFromType (int typ)
|
||||
{
|
||||
switch((EterrainType)typ)
|
||||
switch(static_cast<TerrainTile::EterrainType>(typ))
|
||||
{
|
||||
case dirt:
|
||||
case TerrainTile::dirt:
|
||||
{
|
||||
return std::string("DIRTTL.DEF");
|
||||
break;
|
||||
}
|
||||
case sand:
|
||||
case TerrainTile::sand:
|
||||
{
|
||||
return std::string("SANDTL.DEF");
|
||||
break;
|
||||
}
|
||||
case grass:
|
||||
case TerrainTile::grass:
|
||||
{
|
||||
return std::string("GRASTL.DEF");
|
||||
break;
|
||||
}
|
||||
case snow:
|
||||
case TerrainTile::snow:
|
||||
{
|
||||
return std::string("SNOWTL.DEF");
|
||||
break;
|
||||
}
|
||||
case swamp:
|
||||
case TerrainTile::swamp:
|
||||
{
|
||||
return std::string("SWMPTL.DEF");
|
||||
break;
|
||||
}
|
||||
case rough:
|
||||
case TerrainTile::rough:
|
||||
{
|
||||
return std::string("ROUGTL.DEF");
|
||||
break;
|
||||
}
|
||||
case subterranean:
|
||||
case TerrainTile::subterranean:
|
||||
{
|
||||
return std::string("SUBBTL.DEF");
|
||||
break;
|
||||
}
|
||||
case lava:
|
||||
case TerrainTile::lava:
|
||||
{
|
||||
return std::string("LAVATL.DEF");
|
||||
break;
|
||||
}
|
||||
case water:
|
||||
case TerrainTile::water:
|
||||
{
|
||||
return std::string("WATRTL.DEF");
|
||||
break;
|
||||
}
|
||||
case rock:
|
||||
case TerrainTile::rock:
|
||||
{
|
||||
return std::string("ROCKTL.DEF");
|
||||
break;
|
||||
}
|
||||
case border:
|
||||
case TerrainTile::border:
|
||||
//TODO use me
|
||||
break;
|
||||
default:
|
||||
|
12
mapHandler.h
12
mapHandler.h
@ -80,12 +80,12 @@ public:
|
||||
class CMapHandler
|
||||
{
|
||||
public:
|
||||
PseudoV< PseudoV< PseudoV<TerrainTile2> > > ttiles;
|
||||
int3 sizes;
|
||||
PseudoV< PseudoV< PseudoV<TerrainTile2> > > ttiles; //informations about map tiles
|
||||
int3 sizes; //map size (x - width, y - height, z - number of levels)
|
||||
Mapa * map;
|
||||
std::set<int> usedHeroes;
|
||||
CDefHandler * fullHide;
|
||||
CDefHandler * partialHide;
|
||||
CDefHandler * fullHide; //for Fog of War
|
||||
CDefHandler * partialHide; //for For of War
|
||||
|
||||
std::vector<std::vector<SDL_Surface *> > terrainGraphics; // [terrain id] [view type] [rotation type]
|
||||
std::vector<CDefHandler *> roadDefs;
|
||||
@ -96,8 +96,8 @@ public:
|
||||
|
||||
std::vector<std::vector<std::vector<unsigned char> > > hideBitmap; //specifies number of graphic that should be used to fully hide a tile
|
||||
|
||||
CMapHandler();
|
||||
~CMapHandler();
|
||||
CMapHandler(); //c-tor
|
||||
~CMapHandler(); //d-tor
|
||||
|
||||
void loadDefs();
|
||||
SDL_Surface * getVisBitmap(int x, int y, const std::vector< std::vector< std::vector<unsigned char> > > & visibilityMap, int lvl);
|
||||
|
@ -1139,8 +1139,8 @@ bool CGameHandler::moveHero( si32 hid, int3 dst, ui8 instant, ui8 asker /*= 255*
|
||||
tmh.movePoints = h->movement;
|
||||
|
||||
//check if destination tile is available
|
||||
if( t.tertype == rock
|
||||
|| (!h->canWalkOnSea() && t.tertype == water)
|
||||
if( t.tertype == TerrainTile::rock
|
||||
|| (!h->canWalkOnSea() && t.tertype == TerrainTile::water)
|
||||
|| (t.blocked && !t.visitable) //tile is blocked andnot visitable
|
||||
)
|
||||
{
|
||||
@ -1934,8 +1934,8 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
|
||||
bool CGameHandler::tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 )
|
||||
{
|
||||
val = std::min(si32(val),gs->getPlayer(player)->resources[id1]);
|
||||
double uzysk = (double)gs->resVals[id1] * val * gs->getMarketEfficiency(player);
|
||||
uzysk /= gs->resVals[id2];
|
||||
double yield = (double)gs->resVals[id1] * val * gs->getMarketEfficiency(player);
|
||||
yield /= gs->resVals[id2];
|
||||
SetResource sr;
|
||||
sr.player = player;
|
||||
sr.resid = id1;
|
||||
@ -1943,7 +1943,7 @@ bool CGameHandler::tradeResources( ui32 val, ui8 player, ui32 id1, ui32 id2 )
|
||||
sendAndApply(&sr);
|
||||
|
||||
sr.resid = id2;
|
||||
sr.val = gs->getPlayer(player)->resources[id2] + (int)uzysk;
|
||||
sr.val = gs->getPlayer(player)->resources[id2] + (int)yield;
|
||||
sendAndApply(&sr);
|
||||
|
||||
return true;
|
||||
|
@ -36,8 +36,8 @@ class CVCMIServer
|
||||
std::map<int,CConnection*> connections;
|
||||
std::set<CConnection*> conns;
|
||||
public:
|
||||
CVCMIServer();
|
||||
~CVCMIServer();
|
||||
CVCMIServer(); //c-tor
|
||||
~CVCMIServer(); //d-tor
|
||||
void setUpConnection(CConnection *c, std::string mapname, si32 checksum);
|
||||
void newGame(CConnection *c);
|
||||
void loadGame(CConnection *c);
|
||||
|
Loading…
Reference in New Issue
Block a user