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

Fixed issues reported by Zamolxis:

* dismiss Hero works blocked in the castles
* the backpack scrollable arrows aren't available (yellow, clickable) even when backpack is empty.
* added missing info texts for buttons in hero window (and added functionality of enable tactic formations button)
* can select (single click) and enter castle (double click) from the map. Same for hero.
* Hero gets automatically selected after End Turn 
* Hero is automatically selected when exiting town
* In Garrison or Hero army: units are selected when we first click on them
Fixed (at least partially) also a problem with disappearing path
This commit is contained in:
Michał W. Urbańczyk 2008-08-28 17:36:34 +00:00
parent e856ad21a9
commit 7722d058f0
17 changed files with 428 additions and 282 deletions

View File

@ -20,12 +20,18 @@ AdventureMapButton::AdventureMapButton ()
//{
// 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 )
AdventureMapButton::AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ, std::vector<std::string> * add, bool playerColoredButton )
{
std::map<int,std::string> pom;
pom[0] = Name;
init(Callback, pom, HelpBox, playerColoredButton, defName, add, x, y, activ);
}
AdventureMapButton::AdventureMapButton( const std::map<int,std::string> &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ/*=false*/, std::vector<std::string> * add /*= NULL*/, bool playerColoredButton /*= false */ )
{
init(Callback, Name, HelpBox, playerColoredButton, defName, add, x, y, activ);
}
void AdventureMapButton::clickLeft (tribool down)
{
if(blocked)
@ -62,11 +68,14 @@ void AdventureMapButton::clickRight (tribool down)
void AdventureMapButton::hover (bool on)
{
Hoverable::hover(on);
if(name.size()) //if there is no name, there is nohing to display also
std::string *name = (vstd::contains(hoverTexts,state))
? (&hoverTexts[state])
: (vstd::contains(hoverTexts,0) ? (&hoverTexts[0]) : NULL);
if(name) //if there is no name, there is nohing to display also
{
if (on)
LOCPLINT->statusbar->print(name);
else if (LOCPLINT->statusbar->getCurrent()==name)
LOCPLINT->statusbar->print(*name);
else if ( LOCPLINT->statusbar->getCurrent()==(*name) )
LOCPLINT->statusbar->clear();
}
}
@ -96,7 +105,7 @@ 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 )
void AdventureMapButton::init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ )
{
callback = Callback;
blocked = actOnDown = false;
@ -105,7 +114,7 @@ void AdventureMapButton::init( CFunctionList<void()> Callback, std::string Name,
active=false;
ourObj=NULL;
state=0;
name=Name;
hoverTexts = Name;
helpBox=HelpBox;
colorChange = playerColoredButton;
int est = LOCPLINT->playerID;
@ -152,6 +161,41 @@ void AdventureMapButton::block( bool on )
show();
}
void CHighlightableButton::clickLeft( tribool down )
{
if(blocked)
return;
if (down)
state=1;
else
state = selected ? 3 : 0;
show();
if (pressedL && (down==false))
{
pressedL=state;
selected = !selected;
state = selected ? 3 : 0;
if(selected)
callback();
else
callback2();
if(hoverTexts.size()>1)
{
hover(false);
hover(true);
}
}
else
{
pressedL=state;
}
}
CHighlightableButton::CHighlightableButton( const CFunctionList<void()> &onSelect, const CFunctionList<void()> &onDeselect, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ )
{
init(onSelect,Name,HelpBox,playerColoredButton,defName,add,x,y,activ);
callback2 = onDeselect;
}
void CSlider::sliderClicked()
{
if(!moving)

View File

@ -6,7 +6,7 @@ class AdventureMapButton
: public ClickableL, public ClickableR, public Hoverable, public KeyInterested, public CButtonBase
{
public:
std::string name; //for status bar
std::map<int,std::string> hoverTexts; //state -> text for statusbar
std::string helpBox; //for right-click help
char key; //key shortcut
CFunctionList<void()> callback;
@ -14,18 +14,29 @@ public:
actOnDown; //runs when mouse is pressed down over it, not when up
void clickRight (tribool down);
void clickLeft (tribool down);
virtual void hover (bool on);
virtual void block(bool on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks
virtual void clickLeft (tribool down);
void hover (bool on);
void block(bool on); //if button is blocked then it'll change it's graphic to inactive (offset==2) and won't react on l-clicks
void keyPressed (SDL_KeyboardEvent & key);
void activate(); // makes button active
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( const std::map<int,std::string> &, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const std::string &defName, bool activ=false, std::vector<std::string> * add = NULL, bool playerColoredButton = false );//c-tor
AdventureMapButton( const std::string &Name, const std::string &HelpBox, const CFunctionList<void()> &Callback, int x, int y, const 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 );
void init(const CFunctionList<void()> &Callback, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ );
};
class CHighlightableButton
: public AdventureMapButton
{
public:
CHighlightableButton(const CFunctionList<void()> &onSelect, const CFunctionList<void()> &onDeselect, const std::map<int,std::string> &Name, const std::string &HelpBox, bool playerColoredButton, const std::string &defName, std::vector<std::string> * add, int x, int y, bool activ );
bool selected;
CFunctionList<void()> callback2; //when disselecting
void clickLeft (tribool down);
};

View File

@ -3,6 +3,7 @@
#include "client/CBitmapHandler.h"
#include "CPlayerInterface.h"
#include "CCastleInterface.h"
#include "CCursorHandler.h"
#include "hch/CPreGameTextHandler.h"
#include "hch/CGeneralTextHandler.h"
#include "hch/CDefHandler.h"
@ -291,18 +292,56 @@ void CTerrainRect::clickLeft(tribool down)
{
if ((down==false) || indeterminate(down))
return;
if (LOCPLINT->adventureInt->selection.type != HEROI_TYPE)
{
if (currentPath)
{
delete currentPath;
currentPath = NULL;
}
return;
}
int3 mp = whichTileIsIt();
if ((mp.x<0) || (mp.y<0))
return;
std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp);
if (LOCPLINT->adventureInt->selection->ID != HEROI_TYPE)
{
if (currentPath)
{
std::cout<<"Warning: Lost path?" << std::endl;
delete currentPath;
currentPath = NULL;
}
for(int i=0; i<objs.size();i++)
{
if(objs[i]->ID == 98) //town
{
if(LOCPLINT->adventureInt->selection == (objs[i]))
{
LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(objs[i]));
}
else
{
LOCPLINT->adventureInt->select(static_cast<const CArmedInstance*>(objs[i]));
return;
}
}
else if(objs[i]->ID == 34)
{
LOCPLINT->adventureInt->select(static_cast<const CArmedInstance*>(objs[i]));
return;
}
}
return;
}
else
{
for(int i=0; i<objs.size();i++)
{
if(objs[i]->ID == 98) //town
{
LOCPLINT->adventureInt->select(static_cast<const CArmedInstance*>(objs[i]));
return;
}
else if(objs[i]->ID == 34 && LOCPLINT->adventureInt->selection == (objs[i]))
{
LOCPLINT->openHeroWindow(static_cast<const CGHeroInstance*>(objs[i]));
return;
}
}
}
bool mres =true;
if (currentPath)
{
@ -310,45 +349,38 @@ void CTerrainRect::clickLeft(tribool down)
{ //move
CPath sended(*currentPath); //temporary path - engine will operate on it
LOCPLINT->pim->unlock();
mres = LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID,&sended,1,0);
mres = LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection)->type->ID,&sended,1,0);
LOCPLINT->pim->lock();
if(mres)
{
delete currentPath;
currentPath = NULL;
int i=0;
for(;i<LOCPLINT->adventureInt->heroList.items.size();i++)
{
if(LOCPLINT->adventureInt->heroList.items[i].first->subID == ((const CGHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID)
{
LOCPLINT->adventureInt->heroList.items[i].second = NULL;
break;
}
}
LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.getPosOfHero(LOCPLINT->adventureInt->selection)].second = NULL;
}
}
else
{
delete currentPath;
currentPath=NULL;
LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.getPosOfHero(LOCPLINT->adventureInt->selection)].second = NULL;
}
return;
}
const CGHeroInstance * currentHero = (LOCPLINT->adventureInt->heroList.items.size())?(LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].first):(NULL);
if(!currentHero)
return;
int3 bufpos = currentHero->getPosition(false);
//bufpos.x-=1;
if (mres)
if(currentHero)
{
vector<Coordinate>* p;
p = CGI->pathf->GetPath(Coordinate(bufpos),Coordinate(mp),currentHero);
//Convert to old format.
currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->ConvertToOldFormat(p);
delete p;
//currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->getPath(bufpos,mp,currentHero,1);
int3 bufpos = currentHero->getPosition(false);
if (mres)
{
vector<Coordinate>* p;
p = CGI->pathf->GetPath(Coordinate(bufpos),Coordinate(mp),currentHero);
//Convert to old format.
currentPath = LOCPLINT->adventureInt->heroList.items[LOCPLINT->adventureInt->heroList.selected].second = CGI->pathf->ConvertToOldFormat(p);
delete p;
}
return;
}
}
void CTerrainRect::clickRight(tribool down)
{
@ -369,7 +401,31 @@ void CTerrainRect::mouseMoved (SDL_MouseMotionEvent & sEvent)
{
LOCPLINT->adventureInt->statusbar.clear();
}
std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getVisitableObjs(pom);
for(int i=0; i<objs.size();i++)
{
if(objs[i]->ID == 98) //town
{
CGI->curh->changeGraphic(0,0);
return;
}
}
objs = LOCPLINT->cb->getBlockingObjs(pom);
for(int i=0; i<objs.size();i++)
{
if(objs[i]->ID == 98) //town
{
CGI->curh->changeGraphic(0,3);
return;
}
else if(objs[i]->ID == 34 //mouse over hero
&& (objs[i]==LOCPLINT->adventureInt->selection || LOCPLINT->adventureInt->selection->ID==98)) //this hero is selected or we've selected a town
{
CGI->curh->changeGraphic(0,2);
return;
}
}
CGI->curh->changeGraphic(0,0);
}
void CTerrainRect::keyPressed (SDL_KeyboardEvent & key){}
void CTerrainRect::hover(bool on)
@ -547,7 +603,7 @@ void CTerrainRect::showPath()
}
}
if ( ((currentPath->nodes[i].dist)-(*(currentPath->nodes.end()-1)).dist) > ((const CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->movement)
if ( ((currentPath->nodes[i].dist)-(*(currentPath->nodes.end()-1)).dist) > ((const CGHeroInstance*)(LOCPLINT->adventureInt->selection))->movement)
pn+=25;
if (pn>=0)
{
@ -689,18 +745,10 @@ void CInfoBar::draw(const CGObjectInstance * specific)
else if (mode==5)
{
mode = -1;
if(!LOCPLINT->adventureInt->selection.selected)
{
if (LOCPLINT->adventureInt->heroList.items.size())
{
LOCPLINT->adventureInt->heroList.select(0);
}
}
draw((const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected);
draw(LOCPLINT->adventureInt->selection);
}
if (!specific)
specific = (const CGObjectInstance *)LOCPLINT->adventureInt->selection.selected;
//TODO: to rzutowanie wyglada groznie, ale dziala. Ale nie powinno wygladac groznie.
specific = LOCPLINT->adventureInt->selection;
if(!specific)
return;
@ -874,6 +922,7 @@ endTurn(CGI->preth->zelp[302].first,CGI->preth->zelp[302].second,
townList(5,&genRect(192,48,747,196),747,196,747,372)
{
selection = NULL;
townList.fun = boost::bind(&CAdvMapInt::selectionChanged,this);
LOCPLINT->adventureInt=this;
bg = BitmapHandler::loadBitmap("ADVMAP.bmp");
@ -931,12 +980,12 @@ void CAdvMapInt::fsleepWake()
}
void CAdvMapInt::fmoveHero()
{
if (selection.type!=HEROI_TYPE)
if (selection->ID!=HEROI_TYPE)
return;
if (!terrain.currentPath)
return;
CPath sended(*(terrain.currentPath)); //temporary path - engine will operate on it
LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection.selected)->type->ID,&sended,1,0);
LOCPLINT->cb->moveHero( ((const CGHeroInstance*)LOCPLINT->adventureInt->selection)->type->ID,&sended,1,0);
}
void CAdvMapInt::fshowSpellbok()
{
@ -1008,6 +1057,7 @@ void CAdvMapInt::show(SDL_Surface *to)
minimap.draw();
heroList.draw();
townList.draw();
updateScreen = true;
update();
resdatabar.draw();
@ -1015,8 +1065,6 @@ void CAdvMapInt::show(SDL_Surface *to)
statusbar.show();
infoBar.draw();
CSDL_Ext::update(screen);
}
void CAdvMapInt::hide()
{
@ -1041,24 +1089,71 @@ void CAdvMapInt::hide()
}
void CAdvMapInt::update()
{
terrain.show();
blitAt(gems[2]->ourImages[LOCPLINT->playerID].bitmap,6,6);
blitAt(gems[0]->ourImages[LOCPLINT->playerID].bitmap,6,508);
blitAt(gems[1]->ourImages[LOCPLINT->playerID].bitmap,556,508);
blitAt(gems[3]->ourImages[LOCPLINT->playerID].bitmap,556,6);
//updateRect(&genRect(550,600,6,6));
++animValHitCount; //for animations
if(animValHitCount == 8)
{
animValHitCount = 0;
++anim;
updateScreen = true;
}
++heroAnim;
if(scrollingLeft)
{
if(position.x>-Woff)
{
position.x--;
updateScreen = true;
updateMinimap=true;
}
}
if(scrollingRight)
{
if(position.x<CGI->mh->map->width-19+4)
{
position.x++;
updateScreen = true;
updateMinimap=true;
}
}
if(scrollingUp)
{
if(position.y>-Hoff)
{
position.y--;
updateScreen = true;
updateMinimap=true;
}
}
if(scrollingDown)
{
if(position.y<CGI->mh->map->height-18+4)
{
position.y++;
updateScreen = true;
updateMinimap=true;
}
}
if(updateScreen)
{
terrain.show();
blitAt(gems[2]->ourImages[LOCPLINT->playerID].bitmap,6,6);
blitAt(gems[0]->ourImages[LOCPLINT->playerID].bitmap,6,508);
blitAt(gems[1]->ourImages[LOCPLINT->playerID].bitmap,556,508);
blitAt(gems[3]->ourImages[LOCPLINT->playerID].bitmap,556,6);
updateScreen=false;
}
if (updateMinimap)
{
minimap.draw();
updateMinimap=false;
}
}
void CAdvMapInt::selectionChanged()
{
const CGTownInstance *to = townList.items[townList.selected];
centerOn(to->pos);
selection.type = TOWNI_TYPE;
selection.selected = to;
terrain.currentPath = NULL;
townList.draw();
heroList.draw();
infoBar.draw(NULL);
select(to);
}
void CAdvMapInt::centerOn(int3 on)
{
@ -1081,11 +1176,6 @@ void CAdvMapInt::centerOn(int3 on)
LOCPLINT->adventureInt->updateScreen=true;
updateMinimap=true;
}
CAdvMapInt::CurrentSelection::CurrentSelection()
{
type=-1;
selected=NULL;
}
void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * client)
{
if (down)
@ -1131,3 +1221,24 @@ int3 CAdvMapInt::verifyPos(int3 ver)
ver.z=CGI->mh->sizes.z-1;
return ver;
}
void CAdvMapInt::select(const CArmedInstance *sel )
{
centerOn(sel->pos);
selection = sel;
if(sel->ID==98)
{
int pos = vstd::findPos(townList.items,sel);
townList.selected = pos;
terrain.currentPath = NULL;
}
else
{
int pos = heroList.getPosOfHero(sel);
heroList.selected = pos;
terrain.currentPath = heroList.items[pos].second;
}
townList.draw();
heroList.draw();
infoBar.draw(NULL);
}

View File

@ -144,12 +144,7 @@ public:
CHeroWindow * heroWindow;
struct CurrentSelection
{
int type; //0 - hero, 1 - town
const void* selected;
CurrentSelection(); //ctor
} selection;
const CArmedInstance *selection;
//fuctions binded to buttons
void fshowOverview();
@ -170,6 +165,7 @@ public:
void hide(); //deactivates advmap interface
void update(); //redraws terrain
void select(const CArmedInstance *sel);
void selectionChanged();
void centerOn(int3 on);
int3 verifyPos(int3 ver);

View File

@ -522,4 +522,22 @@ void CCallback::buyArtifact(const CGHeroInstance *hero, int aid)
{
if(hero->tempOwner != player) return;
*cl->serv << ui16(510) << hero->id << ui32(aid);
}
std::vector < const CGObjectInstance * > CCallback::getBlockingObjs( int3 pos )
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
std::vector<const CGObjectInstance *> ret;
BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].blockingObjects)
ret.push_back(obj);
return ret;
}
std::vector < const CGObjectInstance * > CCallback::getVisitableObjs( int3 pos )
{
boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
std::vector<const CGObjectInstance *> ret;
BOOST_FOREACH(const CGObjectInstance * obj, gs->map->terrain[pos.x][pos.y][pos.z].visitableObjects)
ret.push_back(obj);
return ret;
}

View File

@ -60,6 +60,8 @@ public:
virtual const CCreatureSet* getGarrison(const CGObjectInstance *obj)=0;
virtual UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos)=0;
virtual const StartInfo * getStartInfo()=0;
virtual std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos)=0;
virtual std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos)=0;
//battle
virtual int battleGetBattlefieldType()=0; // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship
@ -136,6 +138,8 @@ public:
const CCreatureSet* getGarrison(const CGObjectInstance *obj);
UpgradeInfo getUpgradeInfo(const CArmedInstance *obj, int stackPos);
virtual const StartInfo * getStartInfo();
std::vector < const CGObjectInstance * > getBlockingObjs(int3 pos);
std::vector < const CGObjectInstance * > getVisitableObjs(int3 pos);
//battle
int battleGetBattlefieldType(); // 1. sand/shore 2. sand/mesas 3. dirt/birches 4. dirt/hills 5. dirt/pines 6. grass/hills 7. grass/pines 8. lava 9. magic plains 10. snow/mountains 11. snow/trees 12. subterranean 13. swamp/trees 14. fiery fields 15. rock lands 16. magic clouds 17. lucid pools 18. holy ground 19. clover field 20. evil fog 21. "favourable winds" text on magic plains background 22. cursed ground 23. rough 24. ship to ship 25. ship

View File

@ -452,6 +452,8 @@ void CCastleInterface::close()
LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
deactivate();
LOCPLINT->castleInt = NULL;
if(town->visitingHero)
LOCPLINT->adventureInt->select(town->visitingHero);
LOCPLINT->adventureInt->activate();
delete this;
}

View File

@ -32,20 +32,33 @@ void CCursorHandler::cursorMove(int x, int y)
void CCursorHandler::draw1()
{
if(!Show) return;
switch(mode)
int x = xpos, y = ypos;
if(mode==1)
{
case 0:
SDL_BlitSurface(screen,&genRect(32,32,xpos,ypos),help,&genRect(32,32,0,0));
blitAt(cursors[mode]->ourImages[number].bitmap,xpos,ypos);
break;
case 1:
SDL_BlitSurface(screen,&genRect(32,32,xpos-16,ypos-16),help,&genRect(32,32,0,0));
blitAt(cursors[mode]->ourImages[number].bitmap,xpos-16,ypos-16);
break;
x-=16;
y-=16;
}
else if(mode==0 && number>0)
{
x-=12;
y-=10;
}
SDL_BlitSurface(screen,&genRect(32,32,x,y),help,&genRect(32,32,0,0));
blitAt(cursors[mode]->ourImages[number].bitmap,x,y);
}
void CCursorHandler::draw2()
{
if(!Show) return;
blitAt(help,xpos,ypos);
int x = xpos, y = ypos;
if(mode==1)
{
x-=16;
y-=16;
}
else if(mode==0 && number>0)
{
x-=12;
y-=10;
}
blitAt(help,x,y);
}

View File

@ -18,6 +18,8 @@
#include "hch/CHeroHandler.h"
#include "hch/CLodHandler.h"
#include "hch/CObjectHandler.h"
#include <boost/algorithm/string/replace.hpp>
#include <boost/assign/list_of.hpp>
#include <boost/assign/std/vector.hpp>
#include <cstdlib>
#include <sstream>
@ -46,10 +48,10 @@ CHeroWindow::CHeroWindow(int playerColor):
questlogButton = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CHeroWindow::questlog,this), 379, 437, "hsbtns4.def", false, NULL, false);
gar1button = new AdventureMapButton(CGI->generaltexth->heroscrn[23], CGI->generaltexth->heroscrn[29], boost::bind(&CHeroWindow::gar1,this), 546, 491, "hsbtns6.def", false, NULL, false);
gar2button = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::gar2,this), 604, 491, "hsbtns8.def", false, NULL, false);
gar3button = new AdventureMapButton(CGI->generaltexth->heroscrn[24], CGI->generaltexth->heroscrn[30], boost::bind(&CHeroWindow::gar3,this), 546, 527, "hsbtns7.def", false, NULL, false);
gar4button = new AdventureMapButton(std::string(), CGI->generaltexth->heroscrn[32], boost::function<void()>(), 604, 527, "hsbtns9.def", false, NULL, false);
gar2button = new CHighlightableButton(0, 0, map_list_of(0,CGI->generaltexth->heroscrn[26])(3,CGI->generaltexth->heroscrn[25]), CGI->generaltexth->heroscrn[31], false, "hsbtns8.def", NULL, 604, 491, false);
gar4button = new AdventureMapButton(CGI->generaltexth->allTexts[256], CGI->generaltexth->heroscrn[32], boost::function<void()>(), 604, 527, "hsbtns9.def", false, NULL, false);
boost::algorithm::replace_first(gar4button->hoverTexts[0],"%s",CGI->generaltexth->allTexts[43]);
leftArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::leftArtRoller,this), 379, 364, "hsbtns3.def", false, NULL, false);
rightArtRoll = new AdventureMapButton(std::string(), std::string(), boost::bind(&CHeroWindow::rightArtRoller,this), 632, 364, "hsbtns5.def", false, NULL, false);
@ -195,9 +197,12 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
}
curHero = hero;
gar2button->callback.clear();
gar2button->callback2.clear();
char * prhlp = new char[200];
sprintf(prhlp, CGI->generaltexth->heroscrn[16].c_str(), curHero->name.c_str(), curHero->type->heroClass->name.c_str());
dismissButton->name = std::string(prhlp);
dismissButton->hoverTexts[0] = std::string(prhlp);
delete [] prhlp;
prhlp = new char[200];
@ -293,6 +298,17 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
backpack.push_back(add);
}
activeArtPlace = NULL;
dismissButton->block(hero->visitedTown);
leftArtRoll->block(hero->artifacts.size()<6);
rightArtRoll->block(hero->artifacts.size()<6);
if(hero->getSecSkillLevel(19)<0)
gar2button->block(true);
else
{
gar2button->block(false);
gar2button->callback = boost::bind(vstd::assign<bool,bool>,boost::ref(hero->tacticFormationEnabled), true);
gar2button->callback2 = boost::bind(vstd::assign<bool,bool>,boost::ref(hero->tacticFormationEnabled), true);
}
redrawCurBack();
}
@ -426,10 +442,6 @@ void CHeroWindow::gar1()
{
}
void CHeroWindow::gar2()
{
}
void CHeroWindow::gar3()
{
}

View File

@ -111,8 +111,9 @@ class CHeroWindow: public IShowActivable, public virtual CIntObject
std::vector<LRClickableAreaWTextComp *> secSkillAreas;
public:
AdventureMapButton * quitButton, * dismissButton, * questlogButton, //general
* gar1button, * gar2button, * gar3button, //garrison / formation handling
* gar1button, * gar3button, //garrison / formation handling
* leftArtRoll, * rightArtRoll;
CHighlightableButton *gar2button;
int player;
CHeroWindow(int playerColor); //c-tor
~CHeroWindow(); //d-tor

View File

@ -422,7 +422,7 @@ void CGarrisonInt::recreateSlots()
createSlots();
if(active)
{
ignoreEvent = true;
//ignoreEvent = true;
activeteSlots();
show();
}
@ -831,56 +831,6 @@ void CSelWindow::close()
delete this;
//call owner with selection result
}
template <typename T>CSCButton<T>::CSCButton(CDefHandler * img, CIntObject * obj, void(T::*poin)(tribool), T* Delg)
{
ourObj = obj;
delg = Delg;
func = poin;
imgs.resize(1);
for (int i =0; i<img->ourImages.size();i++)
{
imgs[0].push_back(img->ourImages[i].bitmap);
}
pos.w = imgs[0][0]->w;
pos.h = imgs[0][0]->h;
state = 0;
}
template <typename T> void CSCButton<T>::clickLeft (tribool down)
{
if (down)
{
state=1;
}
else
{
state=0;
}
pressedL=state;
show();
if (delg)
(delg->*func)(down);
}
template <typename T> void CSCButton<T>::activate()
{
ClickableL::activate();
}
template <typename T> void CSCButton<T>::deactivate()
{
ClickableL::deactivate();
}
template <typename T> void CSCButton<T>::show(SDL_Surface * to)
{
if (delg) //we blit on our owner's bitmap
{
blitAt(imgs[curimg][state],posr.x,posr.y,delg->bitmap);
//updateRect(&genRect(pos.h,pos.w,posr.x,posr.y),delg->bitmap);
}
else
{
CButtonBase::show(to);
}
}
CButtonBase::CButtonBase()
{
bitmapOffset = 0;
@ -1037,9 +987,11 @@ void CPlayerInterface::yourTurn()
{
LOCPLINT = this;
makingTurn = true;
unsigned char & animVal = LOCPLINT->adventureInt->anim; //for animations handling
unsigned char & heroAnimVal = LOCPLINT->adventureInt->heroAnim;
adventureInt->infoBar.newDay(cb->getDate(1));
if(adventureInt->heroList.items.size())
adventureInt->select(adventureInt->heroList.items[0].first);
else
adventureInt->select(adventureInt->townList.items[0]);
adventureInt->activate();
//show rest of things
@ -1047,45 +999,13 @@ void CPlayerInterface::yourTurn()
mainFPSmng = new FPSmanager;
SDL_initFramerate(mainFPSmng);
SDL_setFramerate(mainFPSmng, 48);
SDL_Event sEvent;
//framerate keeper initialized
timeHandler th;
th.getDif();
for(;makingTurn;) // main loop
{
//updating water tiles
//int wnumber = -1;
//for(int s=0; s<CGI->mh->reader->defs.size(); ++s)
//{
// if(CGI->mh->reader->defs[s]->defName==std::string("WATRTL.DEF"))
// {
// wnumber = s;
// break;
// }
//}
//if(wnumber>=0)
//{
// for(int g=0; g<CGI->mh->reader->defs[wnumber]->ourImages.size(); ++g)
// {
// SDL_Color tab[32];
// for(int i=0; i<32; ++i)
// {
// tab[i] = CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + (i+1)%32];
// }
// //SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t1.bmp");
// for(int i=0; i<32; ++i)
// {
// CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + i] = tab[i];
// }
// //SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t2.bmp");
// CSDL_Ext::update(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap);
// }
//}
//water tiles updated
//CGI->screenh->updateScreen();
updateWater();
pim->lock();
int tv = th.getDif();
for (int i=0;i<timeinterested.size();i++)
{
@ -1104,61 +1024,7 @@ void CPlayerInterface::yourTurn()
eventsM.unlock();
if (curint == adventureInt) //stuff for advMapInt
{
++LOCPLINT->adventureInt->animValHitCount; //for animations
if(LOCPLINT->adventureInt->animValHitCount == 8)
{
LOCPLINT->adventureInt->animValHitCount = 0;
++animVal;
LOCPLINT->adventureInt->updateScreen = true;
}
++heroAnimVal;
if(LOCPLINT->adventureInt->scrollingLeft)
{
if(LOCPLINT->adventureInt->position.x>-Woff)
{
LOCPLINT->adventureInt->position.x--;
LOCPLINT->adventureInt->updateScreen = true;
adventureInt->updateMinimap=true;
}
}
if(LOCPLINT->adventureInt->scrollingRight)
{
if(LOCPLINT->adventureInt->position.x<CGI->mh->map->width-19+4)
{
LOCPLINT->adventureInt->position.x++;
LOCPLINT->adventureInt->updateScreen = true;
adventureInt->updateMinimap=true;
}
}
if(LOCPLINT->adventureInt->scrollingUp)
{
if(LOCPLINT->adventureInt->position.y>-Hoff)
{
LOCPLINT->adventureInt->position.y--;
LOCPLINT->adventureInt->updateScreen = true;
adventureInt->updateMinimap=true;
}
}
if(LOCPLINT->adventureInt->scrollingDown)
{
if(LOCPLINT->adventureInt->position.y<CGI->mh->map->height-18+4)
{
LOCPLINT->adventureInt->position.y++;
LOCPLINT->adventureInt->updateScreen = true;
adventureInt->updateMinimap=true;
}
}
if(LOCPLINT->adventureInt->updateScreen)
{
adventureInt->update();
adventureInt->updateScreen=false;
}
if (LOCPLINT->adventureInt->updateMinimap)
{
adventureInt->minimap.draw();
adventureInt->updateMinimap=false;
}
adventureInt->update();
}
for(int i=0;i<objsToBlit.size();i++)
objsToBlit[i]->show();
@ -1241,10 +1107,11 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
ho->moveDir = getDir(details.src,details.dst);
ho->isStanding = true;
adventureInt->heroList.draw();
if (adventureInt->terrain.currentPath)
if (adventureInt->terrain.currentPath && ho->movement>145) //TODO: better condition on movement - check cost of endtile
{
delete adventureInt->terrain.currentPath;
adventureInt->terrain.currentPath = NULL;
adventureInt->heroList.items[adventureInt->heroList.getPosOfHero(ho)].second = NULL;
}
return;
}
@ -1573,6 +1440,7 @@ void CPlayerInterface::heroMoved(const HeroMoveDetails & details)
subRect(hp.x-1, hp.y, hp.z, genRect(32, 32, 33+i, 32), ho->id);
subRect(hp.x, hp.y, hp.z, genRect(32, 32, 65+i, 32), ho->id);
}
adventureInt->updateScreen = true;
LOCPLINT->adventureInt->update(); //updating screen
CSDL_Ext::update(screen);
//CGI->screenh->updateScreen();
@ -1693,16 +1561,16 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
}
else
{
switch (adventureInt->selection.type)
switch (adventureInt->selection->ID)
{
case HEROI_TYPE:
{
const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection.selected;
const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection;
return graphics->drawHeroInfoWin(curh);
}
case TOWNI_TYPE:
{
return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection.selected);
return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection);
}
default:
return NULL;
@ -1713,18 +1581,21 @@ SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //spe
void CPlayerInterface::handleMouseMotion(SDL_Event *sEvent)
{
std::vector<int> hlp;
for (int i=0; i<hoverable.size();i++)
{
if (isItIn(&hoverable[i]->pos,sEvent->motion.x,sEvent->motion.y))
{
if (!hoverable[i]->hovered)
hoverable[i]->hover(true);
hlp.push_back(i);
}
else if (hoverable[i]->hovered)
{
hoverable[i]->hover(false);
}
}
for(int i=0; i<hlp.size();i++)
hoverable[hlp[i]]->hover(true);
for(int i=0; i<motioninterested.size();i++)
{
if (motioninterested[i]->strongInterest || isItIn(&motioninterested[i]->pos,sEvent->motion.x,sEvent->motion.y))
@ -1942,7 +1813,7 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
boost::unique_lock<boost::mutex> un(*pim);
SDL_FreeSurface(graphics->heroWins[hero->subID]);//TODO: moznaby zmieniac jedynie fragment bitmapy zwiazany z dana umiejetnoscia
graphics->heroWins[hero->subID] = infoWin(hero); //a nie przerysowywac calosc. Troche roboty, obecnie chyba nie wartej swieczki.
if (adventureInt->selection.selected == hero)
if (adventureInt->selection == hero)
adventureInt->infoBar.draw();
return;
}
@ -2274,10 +2145,45 @@ void CPlayerInterface::heroArtifactSetChanged(const CGHeroInstance*hero)
boost::unique_lock<boost::mutex> un(*pim);
if(curint->subInt == adventureInt->heroWindow)
{
//TODO: update hero window properly
adventureInt->heroWindow->deactivate();
adventureInt->heroWindow->setHero(adventureInt->heroWindow->curHero);
adventureInt->heroWindow->activate();
}
}
void CPlayerInterface::updateWater()
{
//updating water tiles
//int wnumber = -1;
//for(int s=0; s<CGI->mh->reader->defs.size(); ++s)
//{
// if(CGI->mh->reader->defs[s]->defName==std::string("WATRTL.DEF"))
// {
// wnumber = s;
// break;
// }
//}
//if(wnumber>=0)
//{
// for(int g=0; g<CGI->mh->reader->defs[wnumber]->ourImages.size(); ++g)
// {
// SDL_Color tab[32];
// for(int i=0; i<32; ++i)
// {
// tab[i] = CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + (i+1)%32];
// }
// //SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t1.bmp");
// for(int i=0; i<32; ++i)
// {
// CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap->format->palette->colors[160 + i] = tab[i];
// }
// //SDL_SaveBMP(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap,"t2.bmp");
// CSDL_Ext::update(CGI->mh->reader->defs[wnumber]->ourImages[g].bitmap);
// }
//}
//water tiles updated
//CGI->screenh->updateScreen();
}
CStatusBar::CStatusBar(int x, int y, std::string name, int maxw)
{
bg=BitmapHandler::loadBitmap(name);
@ -2388,7 +2294,8 @@ void CHeroList::select(int which)
if (which<0)
{
selected = which;
LOCPLINT->adventureInt->selection.selected = LOCPLINT->adventureInt->terrain.currentPath = NULL;
LOCPLINT->adventureInt->selection = NULL;
LOCPLINT->adventureInt->terrain.currentPath = NULL;
draw();
LOCPLINT->adventureInt->infoBar.draw(NULL);
}
@ -2396,8 +2303,7 @@ void CHeroList::select(int which)
return;
selected = which;
LOCPLINT->adventureInt->centerOn(items[which].first->pos);
LOCPLINT->adventureInt->selection.type = HEROI_TYPE;
LOCPLINT->adventureInt->selection.selected = items[which].first;
LOCPLINT->adventureInt->selection = items[which].first;
LOCPLINT->adventureInt->terrain.currentPath = items[which].second;
draw();
LOCPLINT->adventureInt->townList.draw();
@ -2428,7 +2334,7 @@ void CHeroList::clickLeft(tribool down)
int ny = hy/32;
if (ny>=5 || ny<0)
return;
if ( (ny+from)==selected && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
if ( (ny+from)==selected && (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE))
LOCPLINT->openHeroWindow(items[selected].first);//print hero screen
select(ny+from);
}
@ -2579,7 +2485,7 @@ void CHeroList::draw()
blitAt(mana->ourImages[pom].bitmap,posmanx,posmany+i*32); //mana
SDL_Surface * temp = graphics->portraitSmall[cur->portrait];
blitAt(temp,posporx,pospory+i*32);
if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == HEROI_TYPE))
if ((selected == iT) && (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE))
{
blitAt(selection,posporx,pospory+i*32);
}
@ -2596,6 +2502,10 @@ void CHeroList::draw()
blitAt(arrdo->ourImages[2].bitmap,arrdop.x,arrdop.y);
}
int CHeroList::getPosOfHero(const CArmedInstance* h)
{
return vstd::findPos(items,h,boost::bind(vstd::equal<std::pair<const CGHeroInstance*, CPath *>,const CArmedInstance *,const CGHeroInstance*>,_1,&std::pair<const CGHeroInstance*, CPath *>::first,_2));
}
CTownList::~CTownList()
@ -2701,7 +2611,7 @@ void CTownList::clickLeft(tribool down)
int ny = hy/32;
if (ny>SIZE || ny<0)
return;
if (SIZE==5 && (ny+from)==selected && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
if (SIZE==5 && (ny+from)==selected && (LOCPLINT->adventureInt->selection->ID == TOWNI_TYPE))
LOCPLINT->openTownWindow(items[selected]);//print town screen
else
select(ny+from);
@ -2795,7 +2705,7 @@ void CTownList::draw()
blitAt(graphics->getPic(items[iT]->subID,items[iT]->hasFort(),items[iT]->builded),posporx,pospory+i*32);
if ((selected == iT) && (LOCPLINT->adventureInt->selection.type == TOWNI_TYPE))
if ((selected == iT) && (LOCPLINT->adventureInt->selection->ID == TOWNI_TYPE))
{
blitAt(graphics->getPic(-2),posporx,pospory+i*32);
}

View File

@ -155,20 +155,6 @@ public:
virtual void activate();
virtual void deactivate();
};
template <typename T> class CSCButton: public CButtonBase, public ClickableL //prosty guzik, ktory tylko zmienia obrazek
{
public:
int3 posr; //position in the bitmap
int state;
T* delg;
void(T::*func)(boost::logic::tribool);
CSCButton(CDefHandler * img, CIntObject * obj, void(T::*poin)(boost::logic::tribool), T* Delg=NULL);
void clickLeft (boost::logic::tribool down);
void activate();
void deactivate();
void show(SDL_Surface * to = NULL);
};
class CInfoWindow : public CSimpleWindow //text + comp. + ok button
{ //window able to delete its components when closed
public:
@ -367,7 +353,6 @@ public:
void tileHidden(int3 pos);
void tileRevealed(int3 pos);
void yourTurn();
//for battles
//void actionFinished(BattleAction action);//occurs AFTER every action taken by any stack or by the hero
//void actionStarted(BattleAction action);//occurs BEFORE every action taken by any stack or by the hero
@ -383,7 +368,7 @@ public:
//-------------//
void updateWater();
void showComp(SComponent comp);
void openTownWindow(const CGTownInstance * town); //shows townscreen
void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
@ -449,6 +434,7 @@ public:
int posmobx, posporx, posmanx, posmoby, pospory, posmany;
CHeroList(int Size = 5);
int getPosOfHero(const CArmedInstance* h);
void genList();
void select(int which);
void mouseMoved (SDL_MouseMotionEvent & sEvent);

View File

@ -545,5 +545,7 @@ void CClient::run()
void CClient::close()
{
boost::unique_lock<boost::mutex>(*serv->wmx);
*serv << ui16(99);
serv->close();
}

View File

@ -32,6 +32,10 @@ public:
// funcs.push_back(first);
// return first;
//}
void clear()
{
funcs.clear();
}
operator bool() const
{
return funcs.size();

View File

@ -43,8 +43,8 @@ enum EHeroClasses {HERO_KNIGHT, HERO_CLERIC, HERO_RANGER, HERO_DRUID, HERO_ALCHE
class CGameInfo;
extern CGameInfo* CGI;
#define HEROI_TYPE (0)
#define TOWNI_TYPE (1)
#define HEROI_TYPE (34)
#define TOWNI_TYPE (98)
const int F_NUMBER = 9; //factions (town types) quantity
const int PLAYER_LIMIT = 8; //player limit per map
@ -132,6 +132,22 @@ namespace vstd
{
return std::find(c.begin(),c.end(),i);
}
template <typename T1, typename T2>
int findPos(const std::vector<T1> & c, const T2 &s)
{
for(int i=0;i<c.size();i++)
if(c[i] == s)
return i;
return -1;
}
template <typename T1, typename T2, typename Func>
int findPos(const std::vector<T1> & c, const T2 &s, Func &f) //Func(T1,T2) must say if these elements matches
{
for(int i=0;i<c.size();i++)
if(f(c[i],s))
return i;
return -1;
}
template <typename Container, typename Item>
typename Container::iterator find(Container & c, const Item &i)
{
@ -146,6 +162,21 @@ namespace vstd
c.erase(itr);
return true;
}
template <typename t1, typename t2>
void assign(t1 &a1, const t2 &a2)
{
a1 = a2;
}
template <typename t1, typename t2, typename t3>
bool equal(const t1 &a1, const t3 t1::* point, const t2 &a2)
{
return a1.*point == a2;
}
template <typename t1, typename t2>
bool equal(const t1 &a1, const t2 &a2)
{
return a1 == a2;
}
}
using vstd::operator-=;
#endif //GLOBAL_H

1
int3.h
View File

@ -1,6 +1,7 @@
#ifndef INT3_H
#define INT3_H
#include <map>
#include <vector>
class CCreature;
class CCreatureSet //seven combined creatures
{

View File

@ -88,8 +88,8 @@ void CScriptCallback::showSelectionDialog(SelectionDialog *iw, const CFunctionLi
int CScriptCallback::getSelectedHero()
{
//int ret;
//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
// ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
//if (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE)
// ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection))->subID;
//else
// ret = -1;;
return -1;
@ -214,8 +214,8 @@ int CLuaCallback::getGnrlText(lua_State * L) //(int which),returns string
int CLuaCallback::getSelectedHero(lua_State * L) //(),returns int (ID of hero, -1 if no hero is seleceted)
{
//int ret;
//if (LOCPLINT->adventureInt->selection.type == HEROI_TYPE)
// ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection.selected))->subID;
//if (LOCPLINT->adventureInt->selection->ID == HEROI_TYPE)
// ret = ((CGHeroInstance*)(LOCPLINT->adventureInt->selection))->subID;
//else
// ret = -1;
//lua_pushinteger(L,ret);