mirror of
https://github.com/vcmi/vcmi.git
synced 2024-11-28 08:48:48 +02:00
Implemented Scuttle Boat and Dimension Door spells.
Fixed #417 and #418. Moved / refactored some code. Minor fixes.
This commit is contained in:
parent
047849a23e
commit
80f49badc9
@ -7,6 +7,7 @@
|
||||
#include "lib/map.h"
|
||||
#include "hch/CBuildingHandler.h"
|
||||
#include "hch/CDefObjInfoHandler.h"
|
||||
#include "hch/CGeneralTextHandler.h"
|
||||
#include "hch/CHeroHandler.h"
|
||||
#include "hch/CObjectHandler.h"
|
||||
#include "lib/Connection.h"
|
||||
@ -33,21 +34,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
static int gcd(int x, int y)
|
||||
{
|
||||
int temp;
|
||||
if (y > x)
|
||||
std::swap(x,y);
|
||||
while (y != 0)
|
||||
{
|
||||
temp = y;
|
||||
y = x-y;
|
||||
x = temp;
|
||||
if (y > x)
|
||||
std::swap(x,y);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
HeroMoveDetails::HeroMoveDetails(int3 Src, int3 Dst, CGHeroInstance*Ho)
|
||||
:src(Src),dst(Dst),ho(Ho)
|
||||
{
|
||||
@ -186,12 +173,18 @@ const CGTownInstance * CCallback::getTownInfo(int val, bool mode) const //mode =
|
||||
|
||||
bool CCallback::getTownInfo( const CGObjectInstance *town, InfoAboutTown &dest ) const
|
||||
{
|
||||
const CGTownInstance *t = dynamic_cast<const CGTownInstance *>(town);
|
||||
if(!t || !isVisible(t, player)) //it's not a town or it's not visible for layer
|
||||
if(!isVisible(town, player)) //it's not a town or it's not visible for layer
|
||||
return false;
|
||||
|
||||
bool detailed = hasAccess(town->tempOwner);
|
||||
|
||||
//TODO vision support, info about allies
|
||||
dest.initFromTown(t, false);
|
||||
if(town->ID == TOWNI_TYPE)
|
||||
dest.initFromTown(static_cast<const CGTownInstance *>(town), detailed);
|
||||
else if(town->ID == 33 || town->ID == 219)
|
||||
dest.initFromGarrison(static_cast<const CGGarrison *>(town), detailed);
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -245,7 +238,7 @@ bool CCallback::getHeroInfo( const CGObjectInstance *hero, InfoAboutHero &dest )
|
||||
return false;
|
||||
|
||||
//TODO vision support, info about allies
|
||||
dest.initFromHero(h, false);
|
||||
dest.initFromHero(h, hasAccess(h->tempOwner));
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -963,6 +956,11 @@ void CCallback::castSpell(const CGHeroInstance *hero, int spellID, const int3 &p
|
||||
sendRequest(&cas);
|
||||
}
|
||||
|
||||
bool CCallback::hasAccess(int playerId) const
|
||||
{
|
||||
return playerId == player || player < 0;
|
||||
}
|
||||
|
||||
InfoAboutTown::InfoAboutTown()
|
||||
{
|
||||
tType = NULL;
|
||||
@ -1004,3 +1002,24 @@ void InfoAboutTown::initFromTown( const CGTownInstance *t, bool detailed )
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void InfoAboutTown::initFromGarrison(const CGGarrison *garr, bool detailed)
|
||||
{
|
||||
obj = garr;
|
||||
fortLevel = 0;
|
||||
army = garr->army;
|
||||
name = CGI->generaltexth->names[33]; // "Garrison"
|
||||
owner = garr->tempOwner;
|
||||
built = false;
|
||||
tType = NULL;
|
||||
|
||||
// Show detailed info only to owning player.
|
||||
if(detailed)
|
||||
{
|
||||
details = new InfoAboutTown::Details;
|
||||
details->customRes = false;
|
||||
details->garrisonedHero = false;
|
||||
details->goldIncome = -1;
|
||||
details->hallLevel = -1;
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ struct CPackForServer;
|
||||
class CMapHeader;
|
||||
struct CGPathNode;
|
||||
struct CGPath;
|
||||
class CGGarrison;
|
||||
|
||||
struct InfoAboutTown
|
||||
{
|
||||
@ -65,6 +66,7 @@ struct InfoAboutTown
|
||||
InfoAboutTown();
|
||||
~InfoAboutTown();
|
||||
void initFromTown(const CGTownInstance *t, bool detailed);
|
||||
void initFromGarrison(const CGGarrison *garr, bool detailed);
|
||||
};
|
||||
|
||||
class ICallback
|
||||
@ -201,6 +203,7 @@ private:
|
||||
template <typename T> void sendRequest(const T*request);
|
||||
|
||||
protected:
|
||||
bool hasAccess(int playerId) const;
|
||||
int player;
|
||||
|
||||
public:
|
||||
|
@ -152,10 +152,7 @@ void AdventureMapButton::clickLeft(tribool down, bool previousState)
|
||||
void AdventureMapButton::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(down && helpBox.size()) //there is no point to show window with nothing inside...
|
||||
if(LOCPLINT)
|
||||
adventureInt->handleRightClick(helpBox,down,this);
|
||||
else
|
||||
GH.pushInt(new CRClickPopupInt(CMessage::genWindow(helpBox, 0),true));
|
||||
CRClickPopup::createAndPush(helpBox);
|
||||
}
|
||||
|
||||
void AdventureMapButton::hover (bool on)
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <sstream>
|
||||
#include "CPreGame.h"
|
||||
#include "../lib/VCMI_Lib.h"
|
||||
#include "../hch/CSpellHandler.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning (disable : 4355)
|
||||
@ -272,7 +273,7 @@ void CMinimap::updateRadar()
|
||||
|
||||
void CMinimap::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
adventureInt->handleRightClick(rcText,down,this);
|
||||
adventureInt->handleRightClick(rcText,down);
|
||||
}
|
||||
|
||||
void CMinimap::clickLeft(tribool down, bool previousState)
|
||||
@ -473,96 +474,12 @@ void CTerrainRect::clickLeft(tribool down, bool previousState)
|
||||
{
|
||||
if ((down==false) || indeterminate(down))
|
||||
return;
|
||||
|
||||
int3 mp = whichTileIsIt();
|
||||
if (mp.x<0 || mp.y<0 || mp.x >= LOCPLINT->cb->getMapSize().x || mp.y >= LOCPLINT->cb->getMapSize().y)
|
||||
return;
|
||||
|
||||
std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mp), //blocking objects at tile
|
||||
vobjs = LOCPLINT->cb->getVisitableObjs(mp); //visitable objects
|
||||
|
||||
if (adventureInt->selection->ID != HEROI_TYPE) //hero is not selected (presumably town)
|
||||
{
|
||||
if(currentPath)
|
||||
{
|
||||
tlog2<<"Warning: Lost path?" << std::endl;
|
||||
//delete currentPath;
|
||||
currentPath = NULL;
|
||||
}
|
||||
|
||||
for(size_t i=0; i < bobjs.size(); ++i)
|
||||
{
|
||||
if(bobjs[i]->ID == TOWNI_TYPE && bobjs[i]->getOwner() == LOCPLINT->playerID) //our town clicked
|
||||
{
|
||||
if(adventureInt->selection == (bobjs[i])) //selected town clicked
|
||||
LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(bobjs[i]));
|
||||
else
|
||||
adventureInt->select(static_cast<const CArmedInstance*>(bobjs[i]));
|
||||
|
||||
return;
|
||||
}
|
||||
else if(bobjs[i]->ID == HEROI_TYPE && bobjs[i]->tempOwner == LOCPLINT->playerID) //hero clicked - select him
|
||||
{
|
||||
adventureInt->select(static_cast<const CArmedInstance*>(bobjs[i]));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else //hero is selected
|
||||
{
|
||||
bool townEntrance = false; //town entrance tile has been clicked?
|
||||
const CGHeroInstance * currentHero = static_cast<const CGHeroInstance*>(adventureInt->selection);
|
||||
|
||||
for(size_t i=0; i < vobjs.size(); ++i)
|
||||
{
|
||||
if(vobjs[i]->ID == TOWNI_TYPE)
|
||||
townEntrance = true;
|
||||
}
|
||||
|
||||
if(!townEntrance) //not entrance - select town or open hero window
|
||||
{
|
||||
for(size_t i=0; i < bobjs.size(); ++i)
|
||||
{
|
||||
const CGObjectInstance *o = bobjs[i];
|
||||
const CGPathNode *pn = LOCPLINT->cb->getPathInfo(mp);
|
||||
if( ((o->ID == HEROI_TYPE && pn->turns == 255) //inaccessible hero
|
||||
|| o->ID == TOWNI_TYPE) //or town
|
||||
&& o->tempOwner == LOCPLINT->playerID) //but must belong to us
|
||||
{
|
||||
adventureInt->select(static_cast<const CArmedInstance*>(o));
|
||||
return;
|
||||
}
|
||||
else if(o->ID == HEROI_TYPE //it's a hero
|
||||
&& o->tempOwner == LOCPLINT->playerID //our hero (is this condition needed?)
|
||||
&& currentHero == (o) ) //and selected one
|
||||
{
|
||||
LOCPLINT->openHeroWindow(currentHero);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(currentHero == vobjs.back()) //selected hero is standing at the town entrance
|
||||
{
|
||||
LOCPLINT->openHeroWindow(currentHero);
|
||||
return;
|
||||
}
|
||||
|
||||
//still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
|
||||
if (currentPath && currentPath->endPos() == mp)//we'll be moving
|
||||
{
|
||||
LOCPLINT->pim->unlock();
|
||||
LOCPLINT->moveHero(currentHero,*currentPath);
|
||||
LOCPLINT->pim->lock();
|
||||
}
|
||||
else if(mp.z == currentHero->pos.z) //remove old path and find a new one if we clicked on the map level on which hero is present
|
||||
{
|
||||
int3 bufpos = currentHero->getPosition(false);
|
||||
CGPath &path = LOCPLINT->paths[currentHero];
|
||||
currentPath = &path;
|
||||
if(!LOCPLINT->cb->getPath2(mp, path))
|
||||
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||
}
|
||||
} //end of hero is selected "case"
|
||||
adventureInt->tileLClicked(mp);
|
||||
}
|
||||
void CTerrainRect::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
@ -571,118 +488,7 @@ void CTerrainRect::clickRight(tribool down, bool previousState)
|
||||
if (!CGI->mh->map->isInTheMap(mp) || down != true)
|
||||
return;
|
||||
|
||||
std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp);
|
||||
if(!objs.size())
|
||||
{
|
||||
// Bare or undiscovered terrain
|
||||
const TerrainTile * tile = LOCPLINT->cb->getTileInfo(mp);
|
||||
if (tile)
|
||||
{
|
||||
std::string hlp;
|
||||
CGI->mh->getTerrainDescr(mp, hlp, true);
|
||||
CSimpleWindow * temp = CMessage::genWindow(hlp, LOCPLINT->playerID, true);
|
||||
CRClickPopupInt *rcpi = new CRClickPopupInt(temp,true);
|
||||
GH.pushInt(rcpi);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const CGObjectInstance * obj = objs.back();
|
||||
switch(obj->ID)
|
||||
{
|
||||
case HEROI_TYPE:
|
||||
{
|
||||
if(!vstd::contains(graphics->heroWins,obj->subID) || obj->tempOwner != LOCPLINT->playerID)
|
||||
{
|
||||
InfoAboutHero iah;
|
||||
if(LOCPLINT->cb->getHeroInfo(obj, iah))
|
||||
{
|
||||
SDL_Surface *iwin = graphics->drawHeroInfoWin(iah);
|
||||
CInfoPopup * ip = new CInfoPopup(iwin, GH.current->motion.x-iwin->w,
|
||||
GH.current->motion.y-iwin->h, true);
|
||||
GH.pushInt(ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlog3 << "Warning - no infowin for hero " << obj->id << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CInfoPopup * ip = new CInfoPopup(graphics->heroWins[obj->subID],
|
||||
GH.current->motion.x-graphics->heroWins[obj->subID]->w,
|
||||
GH.current->motion.y-graphics->heroWins[obj->subID]->h,false
|
||||
);
|
||||
GH.pushInt(ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case TOWNI_TYPE:
|
||||
{
|
||||
if(!vstd::contains(graphics->townWins,obj->id) || obj->tempOwner != LOCPLINT->playerID)
|
||||
{
|
||||
InfoAboutTown iah;
|
||||
if(LOCPLINT->cb->getTownInfo(obj, iah))
|
||||
{
|
||||
SDL_Surface *iwin = graphics->drawTownInfoWin(iah);
|
||||
CInfoPopup * ip = new CInfoPopup(iwin, GH.current->motion.x - iwin->w/2,
|
||||
GH.current->motion.y - iwin->h/2, true);
|
||||
GH.pushInt(ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
tlog3 << "Warning - no infowin for town " << obj->id << std::endl;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CInfoPopup * ip = new CInfoPopup(graphics->townWins[obj->id],
|
||||
GH.current->motion.x - graphics->townWins[obj->id]->w/2,
|
||||
GH.current->motion.y - graphics->townWins[obj->id]->h/2,false
|
||||
);
|
||||
GH.pushInt(ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 33: // Garrison
|
||||
case 219:
|
||||
{
|
||||
const CGGarrison *garr = dynamic_cast<const CGGarrison *>(obj);
|
||||
|
||||
if (garr != NULL) {
|
||||
InfoAboutTown iah;
|
||||
|
||||
iah.obj = garr;
|
||||
iah.fortLevel = 0;
|
||||
iah.army = garr->army;
|
||||
iah.name = VLC->generaltexth->names[33]; // "Garrison"
|
||||
iah.owner = garr->tempOwner;
|
||||
iah.built = false;
|
||||
iah.tType = NULL;
|
||||
|
||||
// Show detailed info only to owning player.
|
||||
if (garr->tempOwner == LOCPLINT->playerID) {
|
||||
iah.details = new InfoAboutTown::Details;
|
||||
iah.details->customRes = false;
|
||||
iah.details->garrisonedHero = false;
|
||||
iah.details->goldIncome = -1;
|
||||
iah.details->hallLevel = -1;
|
||||
}
|
||||
|
||||
SDL_Surface *iwin = graphics->drawTownInfoWin(iah);
|
||||
CInfoPopup * ip = new CInfoPopup(iwin,
|
||||
GH.current->motion.x - iwin->w/2,
|
||||
GH.current->motion.y - iwin->h/2, true);
|
||||
GH.pushInt(ip);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
adventureInt->handleRightClick(obj->getHoverText(),down,this);
|
||||
break;
|
||||
}
|
||||
}
|
||||
adventureInt->tileRClicked(mp);
|
||||
}
|
||||
void CTerrainRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
|
||||
{
|
||||
@ -700,163 +506,7 @@ void CTerrainRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
|
||||
else
|
||||
return;
|
||||
|
||||
std::vector<std::string> temp = LOCPLINT->cb->getObjDescriptions(pom);
|
||||
if (temp.size())
|
||||
{
|
||||
boost::replace_all(temp.back(),"\n"," ");
|
||||
adventureInt->statusbar.print(temp.back());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string hlp;
|
||||
CGI->mh->getTerrainDescr(pom, hlp, false);
|
||||
adventureInt->statusbar.print(hlp);
|
||||
//adventureInt->statusbar.clear();
|
||||
}
|
||||
|
||||
const CGPathNode *pnode = LOCPLINT->cb->getPathInfo(pom);
|
||||
std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getBlockingObjs(pom);
|
||||
const CGObjectInstance *obj = objs.size() ? objs.back() : NULL;
|
||||
bool accessible = pnode->turns < 255;
|
||||
|
||||
int turns = pnode->turns;
|
||||
amin(turns, 3);
|
||||
|
||||
if(adventureInt->selection)
|
||||
{
|
||||
if(adventureInt->selection->ID == TOWNI_TYPE)
|
||||
{
|
||||
if(obj && obj->tempOwner == LOCPLINT->playerID)
|
||||
{
|
||||
if(obj->ID == TOWNI_TYPE)
|
||||
{
|
||||
CGI->curh->changeGraphic(0, 3);
|
||||
}
|
||||
else if(obj->ID == HEROI_TYPE)
|
||||
{
|
||||
CGI->curh->changeGraphic(0, 2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else if(adventureInt->selection->ID == HEROI_TYPE)
|
||||
{
|
||||
const CGHeroInstance *h = static_cast<const CGHeroInstance *>(adventureInt->selection);
|
||||
if(obj)
|
||||
{
|
||||
if(obj->ID == HEROI_TYPE)
|
||||
{
|
||||
if(obj->tempOwner != LOCPLINT->playerID) //enemy hero TODO: allies
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else //our hero
|
||||
{
|
||||
if(adventureInt->selection == obj)
|
||||
CGI->curh->changeGraphic(0, 2);
|
||||
else if(accessible)
|
||||
CGI->curh->changeGraphic(0, 8 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 2);
|
||||
}
|
||||
}
|
||||
else if(obj->ID == TOWNI_TYPE)
|
||||
{
|
||||
if(obj->tempOwner != LOCPLINT->playerID) //enemy town TODO: allies
|
||||
{
|
||||
if(accessible) {
|
||||
const CGTownInstance* townObj = dynamic_cast<const CGTownInstance*>(obj);
|
||||
|
||||
// Show movement cursor for unguarded enemy towns, otherwise attack cursor.
|
||||
if (townObj && townObj->army.slots.empty())
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
|
||||
} else {
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else //our town
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 3);
|
||||
}
|
||||
}
|
||||
else if(obj->ID == 54) //monster
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else if(obj->ID == 8) //boat
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 6 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else if (obj->ID == 33 || obj->ID == 219) // Garrison
|
||||
{
|
||||
if (accessible) {
|
||||
const CGGarrison* garrObj = dynamic_cast<const CGGarrison*>(obj);
|
||||
|
||||
// Show battle cursor for guarded enemy garrisons, otherwise movement cursor.
|
||||
if (garrObj && garrObj->tempOwner != LOCPLINT->playerID
|
||||
&& !garrObj->army.slots.empty())
|
||||
{
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
}
|
||||
else
|
||||
{
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
}
|
||||
} else {
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(accessible)
|
||||
{
|
||||
if(pnode->land)
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 28 + turns);
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else //no objs
|
||||
{
|
||||
if(accessible)
|
||||
{
|
||||
if(pnode->land)
|
||||
{
|
||||
if(LOCPLINT->cb->getTileInfo(h->getPosition(false))->tertype != TerrainTile::water)
|
||||
CGI->curh->changeGraphic(0, 4 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 7 + turns*6); //anchor
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 6 + turns*6);
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
//tlog1 << "Tile " << pom << ": Turns=" << (int)pnode->turns <<" Move:=" << pnode->moveRemains <</* " (from " << ")" << */std::endl;
|
||||
adventureInt->tileHovered(curHoveredTile);
|
||||
}
|
||||
void CTerrainRect::hover(bool on)
|
||||
{
|
||||
@ -1321,6 +971,7 @@ CInfoBar::CInfoBar()
|
||||
week2 = CDefHandler::giveDef("NEWWEEK2.DEF");
|
||||
week3 = CDefHandler::giveDef("NEWWEEK3.DEF");
|
||||
week4 = CDefHandler::giveDef("NEWWEEK4.DEF");
|
||||
selInfoWin = NULL;
|
||||
}
|
||||
CInfoBar::~CInfoBar()
|
||||
{
|
||||
@ -1329,8 +980,12 @@ CInfoBar::~CInfoBar()
|
||||
delete week2;
|
||||
delete week3;
|
||||
delete week4;
|
||||
|
||||
if(selInfoWin)
|
||||
SDL_FreeSurface(selInfoWin);
|
||||
}
|
||||
void CInfoBar::draw(SDL_Surface * to, const CGObjectInstance * specific)
|
||||
|
||||
void CInfoBar::showAll(SDL_Surface * to)
|
||||
{
|
||||
if ((mode>=0) && mode<5)
|
||||
{
|
||||
@ -1340,24 +995,11 @@ void CInfoBar::draw(SDL_Surface * to, const CGObjectInstance * specific)
|
||||
else if (mode==5)
|
||||
{
|
||||
mode = -1;
|
||||
draw(to,adventureInt->selection);
|
||||
}
|
||||
if (!specific)
|
||||
specific = adventureInt->selection;
|
||||
|
||||
if(!specific)
|
||||
return;
|
||||
|
||||
if(specific->ID == HEROI_TYPE) //hero
|
||||
if(selInfoWin)
|
||||
{
|
||||
if(graphics->heroWins.find(specific->subID)!=graphics->heroWins.end())
|
||||
blitAt(graphics->heroWins[specific->subID],pos.x,pos.y,to);
|
||||
}
|
||||
else if (specific->ID == TOWNI_TYPE)
|
||||
{
|
||||
const CGTownInstance * t = static_cast<const CGTownInstance*>(specific);
|
||||
if(graphics->townWins.find(t->id)!=graphics->townWins.end())
|
||||
blitAt(graphics->townWins[t->id],pos.x,pos.y,to);
|
||||
blitAt(selInfoWin, pos.x, pos.y, to);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1450,7 +1092,7 @@ void CInfoBar::showComp(SComponent * comp, int time)
|
||||
|
||||
void CInfoBar::tick()
|
||||
{
|
||||
if((mode >= 0) && (mode < 5))
|
||||
if(mode >= 0 && mode < 5)
|
||||
{
|
||||
pom++;
|
||||
if (pom >= getAnim(mode)->ourImages.size())
|
||||
@ -1458,20 +1100,19 @@ void CInfoBar::tick()
|
||||
deactivateTimer();
|
||||
toNextTick = -1;
|
||||
mode = 5;
|
||||
draw(screen2);
|
||||
showAll(screen2);
|
||||
return;
|
||||
}
|
||||
toNextTick = 150;
|
||||
blitAnim(mode);
|
||||
}
|
||||
else if (mode == 6)
|
||||
else if(mode == 6)
|
||||
{
|
||||
deactivateTimer();
|
||||
toNextTick = -1;
|
||||
mode = 5;
|
||||
draw(screen2);
|
||||
showAll(screen2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CInfoBar::show( SDL_Surface * to )
|
||||
@ -1491,6 +1132,13 @@ void CInfoBar::deactivate()
|
||||
deactivateTimer();
|
||||
}
|
||||
|
||||
void CInfoBar::updateSelection(const CGObjectInstance *obj)
|
||||
{
|
||||
if(selInfoWin)
|
||||
SDL_FreeSurface(selInfoWin);
|
||||
selInfoWin = LOCPLINT->infoWin(obj);
|
||||
}
|
||||
|
||||
CAdvMapInt::CAdvMapInt()
|
||||
:statusbar(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG),
|
||||
kingOverview(CGI->generaltexth->zelp[293].first,CGI->generaltexth->zelp[293].second,
|
||||
@ -1526,6 +1174,7 @@ endTurn(CGI->generaltexth->zelp[302].first,CGI->generaltexth->zelp[302].second,
|
||||
heroList(ADVOPT.hlistSize),
|
||||
townList(ADVOPT.tlistSize,ADVOPT.tlistX,ADVOPT.tlistY,ADVOPT.tlistAU,ADVOPT.tlistAD)//(5,&genRect(192,48,747,196),747,196,747,372),
|
||||
{
|
||||
spellBeingCasted = NULL;
|
||||
player = 0;
|
||||
pos.x = pos.y = 0;
|
||||
pos.w = screen->w;
|
||||
@ -1593,24 +1242,21 @@ void CAdvMapInt::fsleepWake()
|
||||
{
|
||||
}
|
||||
void CAdvMapInt::fmoveHero()
|
||||
{
|
||||
if (selection->ID!=HEROI_TYPE)
|
||||
return;
|
||||
if (!terrain.currentPath)
|
||||
{
|
||||
const CGHeroInstance *h = curHero();
|
||||
if (!h || !terrain.currentPath)
|
||||
return;
|
||||
|
||||
LOCPLINT->pim->unlock();
|
||||
LOCPLINT->moveHero(static_cast<const CGHeroInstance*>(adventureInt->selection),*terrain.currentPath);
|
||||
LOCPLINT->pim->lock();
|
||||
LOCPLINT->moveHero(h, *terrain.currentPath);
|
||||
}
|
||||
|
||||
void CAdvMapInt::fshowSpellbok()
|
||||
{
|
||||
if (selection->ID!=HEROI_TYPE) //checking necessary values
|
||||
if (!curHero()) //checking necessary values
|
||||
return;
|
||||
|
||||
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), (static_cast<const CGHeroInstance*>(adventureInt->selection)), LOCPLINT, false);
|
||||
centerOn(selection);
|
||||
CSpellWindow * spellWindow = new CSpellWindow(genRect(595, 620, (conf.cc.resx - 620)/2, (conf.cc.resy - 595)/2), curHero(), LOCPLINT, false);
|
||||
GH.pushInt(spellWindow);
|
||||
}
|
||||
|
||||
@ -1736,7 +1382,7 @@ void CAdvMapInt::showAll(SDL_Surface *to)
|
||||
|
||||
statusbar.show(to);
|
||||
|
||||
infoBar.draw(to);
|
||||
infoBar.showAll(to);
|
||||
LOCPLINT->cingconsole->show(to);
|
||||
}
|
||||
void CAdvMapInt::show(SDL_Surface *to)
|
||||
@ -1802,10 +1448,6 @@ void CAdvMapInt::selectionChanged()
|
||||
}
|
||||
void CAdvMapInt::centerOn(int3 on)
|
||||
{
|
||||
// TODO:convertPosition should not belong to CGHeroInstance, and it
|
||||
// should be split in 2 methods.
|
||||
on = CGHeroInstance::convertPosition(on, false);
|
||||
|
||||
on.x -= CGI->mh->frameW;
|
||||
on.y -= CGI->mh->frameH;
|
||||
|
||||
@ -1818,10 +1460,20 @@ void CAdvMapInt::centerOn(int3 on)
|
||||
if(GH.topInt() == this)
|
||||
underground.redraw();
|
||||
}
|
||||
|
||||
void CAdvMapInt::centerOn(const CGObjectInstance *obj)
|
||||
{
|
||||
centerOn(obj->getSightCenter());
|
||||
}
|
||||
|
||||
void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
ui8 Dir = 0;
|
||||
int k = key.keysym.sym;
|
||||
const CGHeroInstance *h = curHero(); //selected hero
|
||||
const CGTownInstance *t = curTown(); //selected town
|
||||
|
||||
|
||||
switch(k)
|
||||
{
|
||||
case SDLK_i:
|
||||
@ -1834,7 +1486,6 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
return;
|
||||
case SDLK_d:
|
||||
{
|
||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance*>(selection);
|
||||
if(h && isActive() && key.state == SDL_PRESSED)
|
||||
LOCPLINT->tryDiggging(h);
|
||||
return;
|
||||
@ -1847,7 +1498,6 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
if(!isActive())
|
||||
return;
|
||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance*>(selection);
|
||||
if(h && key.state == SDL_PRESSED)
|
||||
{
|
||||
LOCPLINT->pim->unlock();
|
||||
@ -1860,10 +1510,10 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
{
|
||||
if(!isActive() || !selection || key.state != SDL_PRESSED)
|
||||
return;
|
||||
if(selection->ID == HEROI_TYPE)
|
||||
LOCPLINT->openHeroWindow(static_cast<const CGHeroInstance*>(selection));
|
||||
else if(selection->ID == TOWNI_TYPE)
|
||||
LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(selection));
|
||||
if(h)
|
||||
LOCPLINT->openHeroWindow(h);
|
||||
else if(t)
|
||||
LOCPLINT->openTownWindow(t);
|
||||
return;
|
||||
}
|
||||
case SDLK_t:
|
||||
@ -1919,12 +1569,12 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
if(k < 0 || k > 8 || key.state != SDL_PRESSED)
|
||||
return;
|
||||
|
||||
if(!h)
|
||||
break;
|
||||
|
||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(selection);
|
||||
if(!h) break;
|
||||
if(k == 4)
|
||||
{
|
||||
centerOn(h->getPosition(false));
|
||||
centerOn(h);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1940,9 +1590,7 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
|
||||
if(!path.nodes[0].turns)
|
||||
{
|
||||
LOCPLINT->pim->unlock();
|
||||
LOCPLINT->moveHero(h, path);
|
||||
LOCPLINT->pim->lock();
|
||||
}
|
||||
}
|
||||
|
||||
@ -1955,13 +1603,11 @@ void CAdvMapInt::keyPressed(const SDL_KeyboardEvent & key)
|
||||
else
|
||||
scrollingDir &= ~Dir;
|
||||
}
|
||||
void CAdvMapInt::handleRightClick(std::string text, tribool down, CIntObject * client)
|
||||
void CAdvMapInt::handleRightClick(std::string text, tribool down)
|
||||
{
|
||||
if (down)
|
||||
if(down)
|
||||
{
|
||||
CSimpleWindow * temp = CMessage::genWindow(text,LOCPLINT->playerID,true);
|
||||
CRClickPopupInt *rcpi = new CRClickPopupInt(temp,true);
|
||||
GH.pushInt(rcpi);
|
||||
CRClickPopup::createAndPush(text);
|
||||
}
|
||||
}
|
||||
int3 CAdvMapInt::verifyPos(int3 ver)
|
||||
@ -1981,12 +1627,12 @@ int3 CAdvMapInt::verifyPos(int3 ver)
|
||||
return ver;
|
||||
}
|
||||
|
||||
void CAdvMapInt::select(const CArmedInstance *sel )
|
||||
void CAdvMapInt::select(const CArmedInstance *sel, bool centerView /*= true*/)
|
||||
{
|
||||
LOCPLINT->cb->setSelection(sel);
|
||||
|
||||
centerOn(sel->pos);
|
||||
selection = sel;
|
||||
if(centerView)
|
||||
centerOn(sel);
|
||||
|
||||
terrain.currentPath = NULL;
|
||||
if(sel->ID==TOWNI_TYPE)
|
||||
@ -2009,7 +1655,8 @@ void CAdvMapInt::select(const CArmedInstance *sel )
|
||||
}
|
||||
townList.draw(screen);
|
||||
heroList.draw(screen);
|
||||
infoBar.draw(screen);
|
||||
infoBar.updateSelection(sel);
|
||||
infoBar.showAll(screen);
|
||||
}
|
||||
|
||||
void CAdvMapInt::mouseMoved( const SDL_MouseMotionEvent & sEvent )
|
||||
@ -2090,10 +1737,317 @@ void CAdvMapInt::startTurn()
|
||||
state = INGAME;
|
||||
}
|
||||
|
||||
void CAdvMapInt::tileLClicked(const int3 &mp)
|
||||
{
|
||||
std::vector < const CGObjectInstance * > bobjs = LOCPLINT->cb->getBlockingObjs(mp), //blocking objects at tile
|
||||
vobjs = LOCPLINT->cb->getVisitableObjs(mp); //visitable objects
|
||||
const TerrainTile *tile = LOCPLINT->cb->getTileInfo(mp);
|
||||
const CGObjectInstance *topBlocking = bobjs.size() ? bobjs.back() : NULL;
|
||||
|
||||
|
||||
int3 selPos = selection->getSightCenter();
|
||||
if(spellBeingCasted && isInScreenRange(selPos, mp))
|
||||
{
|
||||
const TerrainTile *heroTile = LOCPLINT->cb->getTileInfo(selPos);
|
||||
|
||||
switch(spellBeingCasted->id)
|
||||
{
|
||||
case Spells::SCUTTLE_BOAT: //Scuttle Boat
|
||||
if(topBlocking && topBlocking->ID == 8)
|
||||
leaveCastingMode(true, mp);
|
||||
break;
|
||||
case Spells::DIMENSION_DOOR:
|
||||
if(!tile || tile->isClear(heroTile))
|
||||
leaveCastingMode(true, mp);
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (selection->ID != HEROI_TYPE) //hero is not selected (presumably town)
|
||||
{
|
||||
assert(!terrain.currentPath); //path can be active only when hero is selected
|
||||
if(selection == topBlocking) //selected town clicked
|
||||
LOCPLINT->openTownWindow(static_cast<const CGTownInstance*>(topBlocking));
|
||||
else if(topBlocking && (topBlocking->ID == TOWNI_TYPE || topBlocking->ID == HEROI_TYPE) && topBlocking->tempOwner == LOCPLINT->playerID) //our town/hero clicked
|
||||
select(static_cast<const CArmedInstance*>(topBlocking), false);
|
||||
}
|
||||
else if(const CGHeroInstance * currentHero = curHero()) //hero is selected
|
||||
{
|
||||
const CGPathNode *pn = LOCPLINT->cb->getPathInfo(mp);
|
||||
if(currentHero == topBlocking) //clicked selected hero
|
||||
{
|
||||
LOCPLINT->openHeroWindow(currentHero);
|
||||
}
|
||||
else if(topBlocking && (topBlocking->ID == HEROI_TYPE || topBlocking->ID == TOWNI_TYPE) //clicked our town or hero
|
||||
&& pn->turns == 255 && topBlocking->tempOwner == LOCPLINT->playerID) //at inaccessible tile
|
||||
{
|
||||
select(static_cast<const CArmedInstance*>(topBlocking), false);
|
||||
}
|
||||
else //still here? we need to move hero if we clicked end of already selected path or calculate a new path otherwise
|
||||
{
|
||||
if (terrain.currentPath && terrain.currentPath->endPos() == mp)//we'll be moving
|
||||
{
|
||||
LOCPLINT->moveHero(currentHero,*terrain.currentPath);
|
||||
}
|
||||
else if(mp.z == currentHero->pos.z) //remove old path and find a new one if we clicked on the map level on which hero is present
|
||||
{
|
||||
CGPath &path = LOCPLINT->paths[currentHero];
|
||||
terrain.currentPath = &path;
|
||||
if(!LOCPLINT->cb->getPath2(mp, path)) //try getting path, erase if failed
|
||||
LOCPLINT->eraseCurrentPathOf(currentHero);
|
||||
}
|
||||
}
|
||||
} //end of hero is selected "case"
|
||||
else
|
||||
{
|
||||
throw std::string("Nothing is selected...");
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapInt::tileHovered(const int3 &tile)
|
||||
{
|
||||
std::vector<std::string> temp = LOCPLINT->cb->getObjDescriptions(tile);
|
||||
if (temp.size())
|
||||
{
|
||||
boost::replace_all(temp.back(),"\n"," ");
|
||||
statusbar.print(temp.back());
|
||||
}
|
||||
else
|
||||
{
|
||||
std::string hlp;
|
||||
CGI->mh->getTerrainDescr(tile, hlp, false);
|
||||
statusbar.print(hlp);
|
||||
}
|
||||
|
||||
const CGPathNode *pnode = LOCPLINT->cb->getPathInfo(tile);
|
||||
std::vector<const CGObjectInstance *> objs = LOCPLINT->cb->getBlockingObjs(tile);
|
||||
const CGObjectInstance *objAtTile = objs.size() ? objs.back() : NULL;
|
||||
bool accessible = pnode->turns < 255;
|
||||
|
||||
int turns = pnode->turns;
|
||||
amin(turns, 3);
|
||||
|
||||
if(!selection) //may occur just at the start of game (fake move before full intiialization)
|
||||
return;
|
||||
|
||||
if(spellBeingCasted)
|
||||
{
|
||||
switch(spellBeingCasted->id)
|
||||
{
|
||||
case Spells::SCUTTLE_BOAT:
|
||||
if(objAtTile && objAtTile->ID == 8)
|
||||
CGI->curh->changeGraphic(0, 42);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
return;
|
||||
case Spells::DIMENSION_DOOR:
|
||||
{
|
||||
const TerrainTile *t = LOCPLINT->cb->getTileInfo(tile);
|
||||
int3 hpos = selection->getSightCenter();
|
||||
if((!t || t->isClear(LOCPLINT->cb->getTileInfo(hpos))) && isInScreenRange(hpos, tile))
|
||||
CGI->curh->changeGraphic(0, 41);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(selection->ID == TOWNI_TYPE)
|
||||
{
|
||||
if(objAtTile && objAtTile->tempOwner == LOCPLINT->playerID)
|
||||
{
|
||||
if(objAtTile->ID == TOWNI_TYPE)
|
||||
CGI->curh->changeGraphic(0, 3);
|
||||
else if(objAtTile->ID == HEROI_TYPE)
|
||||
CGI->curh->changeGraphic(0, 2);
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else if(const CGHeroInstance *h = curHero())
|
||||
{
|
||||
if(objAtTile)
|
||||
{
|
||||
if(objAtTile->ID == HEROI_TYPE)
|
||||
{
|
||||
if(objAtTile->tempOwner != LOCPLINT->playerID) //enemy hero TODO: allies
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else //our hero
|
||||
{
|
||||
if(selection == objAtTile)
|
||||
CGI->curh->changeGraphic(0, 2);
|
||||
else if(accessible)
|
||||
CGI->curh->changeGraphic(0, 8 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 2);
|
||||
}
|
||||
}
|
||||
else if(objAtTile->ID == TOWNI_TYPE)
|
||||
{
|
||||
if(objAtTile->tempOwner != LOCPLINT->playerID) //enemy town TODO: allies
|
||||
{
|
||||
if(accessible)
|
||||
{
|
||||
const CGTownInstance* townObj = dynamic_cast<const CGTownInstance*>(objAtTile);
|
||||
|
||||
// Show movement cursor for unguarded enemy towns, otherwise attack cursor.
|
||||
if (townObj && townObj->army.slots.empty())
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else //our town
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 3);
|
||||
}
|
||||
}
|
||||
else if(objAtTile->ID == 54) //monster
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else if(objAtTile->ID == 8) //boat
|
||||
{
|
||||
if(accessible)
|
||||
CGI->curh->changeGraphic(0, 6 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else if (objAtTile->ID == 33 || objAtTile->ID == 219) // Garrison
|
||||
{
|
||||
if (accessible)
|
||||
{
|
||||
const CGGarrison* garrObj = dynamic_cast<const CGGarrison*>(objAtTile); //TODO evil evil cast!
|
||||
|
||||
// Show battle cursor for guarded enemy garrisons, otherwise movement cursor.
|
||||
if (garrObj && garrObj->tempOwner != LOCPLINT->playerID && !garrObj->army.slots.empty())
|
||||
CGI->curh->changeGraphic(0, 5 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(accessible)
|
||||
{
|
||||
if(pnode->land)
|
||||
CGI->curh->changeGraphic(0, 9 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 28 + turns);
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
else //no objs
|
||||
{
|
||||
if(accessible)
|
||||
{
|
||||
if(pnode->land)
|
||||
{
|
||||
if(LOCPLINT->cb->getTileInfo(h->getPosition(false))->tertype != TerrainTile::water)
|
||||
CGI->curh->changeGraphic(0, 4 + turns*6);
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 7 + turns*6); //anchor
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 6 + turns*6);
|
||||
}
|
||||
else
|
||||
CGI->curh->changeGraphic(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CAdvMapInt::tileRClicked(const int3 &mp)
|
||||
{
|
||||
if(spellBeingCasted)
|
||||
{
|
||||
leaveCastingMode();
|
||||
LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[731]); //Spell cancelled
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector < const CGObjectInstance * > objs = LOCPLINT->cb->getBlockingObjs(mp);
|
||||
if(!objs.size())
|
||||
{
|
||||
// Bare or undiscovered terrain
|
||||
const TerrainTile * tile = LOCPLINT->cb->getTileInfo(mp);
|
||||
if (tile)
|
||||
{
|
||||
std::string hlp;
|
||||
CGI->mh->getTerrainDescr(mp, hlp, true);
|
||||
CRClickPopup::createAndPush(hlp);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const CGObjectInstance * obj = objs.back();
|
||||
CRClickPopup::createAndPush(obj, GH.current->motion, CENTER);
|
||||
}
|
||||
|
||||
void CAdvMapInt::enterCastingMode(const CSpell * sp)
|
||||
{
|
||||
using namespace Spells;
|
||||
assert(sp->id == SCUTTLE_BOAT || sp->id == DIMENSION_DOOR);
|
||||
spellBeingCasted = sp;
|
||||
|
||||
deactivate();
|
||||
terrain.activate();
|
||||
GH.fakeMouseMove();
|
||||
}
|
||||
|
||||
void CAdvMapInt::leaveCastingMode(bool cast /*= false*/, int3 dest /*= int3(-1, -1, -1)*/)
|
||||
{
|
||||
assert(spellBeingCasted);
|
||||
int id = spellBeingCasted->id;
|
||||
spellBeingCasted = NULL;
|
||||
terrain.deactivate();
|
||||
activate();
|
||||
|
||||
LOCPLINT->cb->castSpell(curHero(), id, dest);
|
||||
}
|
||||
|
||||
const CGHeroInstance * CAdvMapInt::curHero() const
|
||||
{
|
||||
if(selection && selection->ID == HEROI_TYPE)
|
||||
return static_cast<const CGHeroInstance *>(selection);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const CGTownInstance * CAdvMapInt::curTown() const
|
||||
{
|
||||
if(selection && selection->ID == TOWNI_TYPE)
|
||||
return static_cast<const CGTownInstance *>(selection);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CAdventureOptions::CAdventureOptions()
|
||||
{
|
||||
OBJ_CONSTRUCTION_CAPTURING_ALL;
|
||||
bg = new CPicture(BitmapHandler::loadBitmap("ADVOPTS.bmp"), 0, 0);
|
||||
bg = new CPicture("ADVOPTS.bmp");
|
||||
graphics->blueToPlayersAdv(bg->bg, LOCPLINT->playerID);
|
||||
pos = bg->center();
|
||||
exit = new AdventureMapButton("","",boost::bind(&CGuiHandler::popIntTotally, &GH, this), 204, 313, "IOK6432.DEF",SDLK_RETURN);
|
||||
@ -2106,13 +2060,11 @@ CAdventureOptions::CAdventureOptions()
|
||||
puzzle = new AdventureMapButton("","", boost::bind(&CGuiHandler::popIntTotally, &GH, this), 24, 81, "ADVPUZ.DEF");
|
||||
puzzle->callback += boost::bind(&CPlayerInterface::showPuzzleMap, LOCPLINT);
|
||||
|
||||
const CGHeroInstance *h = dynamic_cast<const CGHeroInstance *>(adventureInt->selection);
|
||||
dig = new AdventureMapButton("","", boost::bind(&CGuiHandler::popIntTotally, &GH, this), 24, 139, "ADVDIG.DEF");
|
||||
if(h)
|
||||
if(const CGHeroInstance *h = adventureInt->curHero())
|
||||
dig->callback += boost::bind(&CPlayerInterface::tryDiggging, LOCPLINT, h);
|
||||
else
|
||||
dig->block(true);
|
||||
|
||||
}
|
||||
|
||||
CAdventureOptions::~CAdventureOptions()
|
||||
|
@ -13,6 +13,7 @@ class CAdvMapInt;
|
||||
class CGHeroInstance;
|
||||
class CGTownInstance;
|
||||
class CHeroWindow;
|
||||
class CSpell;
|
||||
/*****************************/
|
||||
|
||||
/*
|
||||
@ -116,18 +117,20 @@ public:
|
||||
SComponent * current;
|
||||
int mode;
|
||||
int pom;
|
||||
SDL_Surface *selInfoWin; //info box for selection
|
||||
|
||||
CInfoBar();
|
||||
~CInfoBar();
|
||||
void newDay(int Day); //start showing new day/week animation
|
||||
void showComp(SComponent * comp, int time=5000);
|
||||
void tick();
|
||||
void draw(SDL_Surface * to, const CGObjectInstance * specific=NULL); // if specific==0 function draws info about selected hero/town
|
||||
void showAll(SDL_Surface * to); // if specific==0 function draws info about selected hero/town
|
||||
void blitAnim(int mode);//0 - day, 1 - week
|
||||
CDefHandler * getAnim(int mode);
|
||||
void show(SDL_Surface * to);
|
||||
void activate();
|
||||
void deactivate();
|
||||
void updateSelection(const CGObjectInstance *obj);
|
||||
};
|
||||
/*****************************/
|
||||
class CAdvMapInt : public CIntObject //adventure map interface
|
||||
@ -166,13 +169,13 @@ public:
|
||||
endTurn;//- end turn
|
||||
|
||||
CTerrainRect terrain; //visible terrain
|
||||
|
||||
CResDataBar resdatabar;
|
||||
|
||||
CHeroList heroList;
|
||||
CTownList townList;
|
||||
CInfoBar infoBar;
|
||||
|
||||
const CSpell *spellBeingCasted; //NULL if none
|
||||
|
||||
CHeroWindow * heroWindow;
|
||||
|
||||
const CArmedInstance *selection; //currently selected town/hero
|
||||
@ -195,11 +198,12 @@ public:
|
||||
void show(SDL_Surface * to); //redraws terrain
|
||||
void showAll(SDL_Surface * to); //shows and activates adv. map interface
|
||||
|
||||
void select(const CArmedInstance *sel);
|
||||
void select(const CArmedInstance *sel, bool centerView = true);
|
||||
void selectionChanged();
|
||||
void centerOn(int3 on);
|
||||
void centerOn(const CGObjectInstance *obj);
|
||||
int3 verifyPos(int3 ver);
|
||||
void handleRightClick(std::string text, tribool down, CIntObject * client);
|
||||
void handleRightClick(std::string text, tribool down);
|
||||
void keyPressed(const SDL_KeyboardEvent & key);
|
||||
void mouseMoved (const SDL_MouseMotionEvent & sEvent);
|
||||
bool isActive();
|
||||
@ -207,6 +211,13 @@ public:
|
||||
void setPlayer(int Player);
|
||||
void startHotSeatWait(int Player);
|
||||
void startTurn();
|
||||
void tileLClicked(const int3 &mp);
|
||||
void tileHovered(const int3 &tile);
|
||||
void tileRClicked(const int3 &mp);
|
||||
void enterCastingMode(const CSpell * sp);
|
||||
void leaveCastingMode(bool cast = false, int3 dest = int3(-1, -1, -1));
|
||||
const CGHeroInstance * curHero() const;
|
||||
const CGTownInstance * curTown() const;
|
||||
};
|
||||
|
||||
extern CAdvMapInt *adventureInt;
|
||||
|
@ -164,7 +164,12 @@ void CCursorHandler::shiftPos( int &x, int &y )
|
||||
y -= 16;
|
||||
}
|
||||
}
|
||||
else if(number < 31)
|
||||
else if(number == 41)
|
||||
{
|
||||
x -= 14;
|
||||
y -= 16;
|
||||
}
|
||||
else if(number < 31 || number == 42)
|
||||
{
|
||||
x -= 20;
|
||||
y -= 20;
|
||||
|
@ -77,6 +77,7 @@ std::queue<SDL_Event*> events;
|
||||
boost::mutex eventsM;
|
||||
|
||||
static bool gOnlyAI = false;
|
||||
static bool setResolution = false; //set by event handling thread after resolution is adjusted
|
||||
|
||||
void processCommand(const std::string &message);
|
||||
static void setScreenRes(int w, int h, int bpp, bool fullscreen);
|
||||
@ -483,6 +484,7 @@ static void listenForEvents()
|
||||
else if(ev->type == SDL_USEREVENT && ev->user.code == 1)
|
||||
{
|
||||
setScreenRes(conf.cc.resx,conf.cc.resy,conf.cc.bpp,conf.cc.fullscreen);
|
||||
setResolution = true;
|
||||
delete ev;
|
||||
continue;
|
||||
}
|
||||
@ -540,5 +542,11 @@ void startGame(StartInfo * options)
|
||||
}
|
||||
|
||||
CGI->musich->stopMusic();
|
||||
|
||||
//allow event handling thread change resolution
|
||||
eventsM.unlock();
|
||||
while(!setResolution) boost::this_thread::sleep(boost::posix_time::milliseconds(50));
|
||||
eventsM.lock();
|
||||
|
||||
client->connectionHandler = new boost::thread(&CClient::run, client);
|
||||
}
|
||||
|
@ -133,14 +133,6 @@ CPlayerInterface::~CPlayerInterface()
|
||||
cingconsole->deactivate();
|
||||
delete cingconsole;
|
||||
|
||||
for(std::map<int,SDL_Surface*>::iterator i=graphics->heroWins.begin(); i!= graphics->heroWins.end(); i++)
|
||||
SDL_FreeSurface(i->second);
|
||||
graphics->heroWins.clear();
|
||||
|
||||
for(std::map<int,SDL_Surface*>::iterator i=graphics->townWins.begin(); i!= graphics->townWins.end(); i++)
|
||||
SDL_FreeSurface(i->second);
|
||||
graphics->townWins.clear();
|
||||
|
||||
LOCPLINT = NULL;
|
||||
}
|
||||
void CPlayerInterface::init(ICallback * CB)
|
||||
@ -149,13 +141,6 @@ void CPlayerInterface::init(ICallback * CB)
|
||||
if(!adventureInt)
|
||||
adventureInt = new CAdvMapInt();
|
||||
|
||||
std::vector<const CGTownInstance*> tt = cb->getTownsInfo(false);
|
||||
for(int i=0;i<tt.size();i++)
|
||||
{
|
||||
SDL_Surface * pom = infoWin(tt[i]);
|
||||
graphics->townWins.insert(std::pair<int,SDL_Surface*>(tt[i]->id,pom));
|
||||
}
|
||||
|
||||
if(!towns.size() && !wanderingHeroes.size())
|
||||
{
|
||||
recreateHeroTownList();
|
||||
@ -248,7 +233,7 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
const CGHeroInstance * ho = cb->getHeroInfo(details.id); //object representing this hero
|
||||
int3 hp = details.start;
|
||||
|
||||
adventureInt->centerOn(ho->pos); //actualizing screen pos
|
||||
adventureInt->centerOn(ho); //actualizing screen pos
|
||||
adventureInt->minimap.draw(screen2);
|
||||
adventureInt->heroList.draw(screen2);
|
||||
|
||||
@ -336,15 +321,12 @@ void CPlayerInterface::heroMoved(const TryMoveHero & details)
|
||||
void CPlayerInterface::heroKilled(const CGHeroInstance* hero)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
graphics->heroWins.erase(hero->ID);
|
||||
wanderingHeroes -= hero;
|
||||
adventureInt->heroList.updateHList(hero);
|
||||
}
|
||||
void CPlayerInterface::heroCreated(const CGHeroInstance * hero)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
if(graphics->heroWins.find(hero->subID)==graphics->heroWins.end())
|
||||
graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hero->subID,infoWin(hero)));
|
||||
wanderingHeroes.push_back(hero);
|
||||
adventureInt->heroList.updateHList();
|
||||
}
|
||||
@ -356,38 +338,31 @@ void CPlayerInterface::openTownWindow(const CGTownInstance * town)
|
||||
|
||||
SDL_Surface * CPlayerInterface::infoWin(const CGObjectInstance * specific) //specific=0 => draws info about selected town/hero
|
||||
{
|
||||
if (specific)
|
||||
if(!specific)
|
||||
specific = adventureInt->selection;
|
||||
|
||||
assert(specific);
|
||||
|
||||
switch(specific->ID)
|
||||
{
|
||||
switch (specific->ID)
|
||||
case HEROI_TYPE:
|
||||
{
|
||||
case HEROI_TYPE:
|
||||
return graphics->drawHeroInfoWin(dynamic_cast<const CGHeroInstance*>(specific));
|
||||
break;
|
||||
case TOWNI_TYPE:
|
||||
return graphics->drawTownInfoWin(dynamic_cast<const CGTownInstance*>(specific));
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
InfoAboutHero iah;
|
||||
bool gotInfo = LOCPLINT->cb->getHeroInfo(specific, iah);
|
||||
assert(gotInfo);
|
||||
return graphics->drawHeroInfoWin(iah);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (adventureInt->selection->ID)
|
||||
case TOWNI_TYPE:
|
||||
case 33: // Garrison
|
||||
case 219:
|
||||
{
|
||||
case HEROI_TYPE:
|
||||
{
|
||||
const CGHeroInstance * curh = (const CGHeroInstance *)adventureInt->selection;
|
||||
return graphics->drawHeroInfoWin(curh);
|
||||
}
|
||||
case TOWNI_TYPE:
|
||||
{
|
||||
return graphics->drawTownInfoWin((const CGTownInstance *)adventureInt->selection);
|
||||
}
|
||||
default:
|
||||
tlog1 << "Strange... selection is neither hero nor town\n";
|
||||
return NULL;
|
||||
InfoAboutTown iah;
|
||||
bool gotInfo = LOCPLINT->cb->getTownInfo(specific, iah);
|
||||
assert(gotInfo);
|
||||
return graphics->drawTownInfoWin(iah);
|
||||
}
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -408,12 +383,12 @@ void CPlayerInterface::heroPrimarySkillChanged(const CGHeroInstance * hero, int
|
||||
if(which >= PRIMARY_SKILLS) //no need to redraw infowin if this is experience (exp is treated as prim skill with id==4)
|
||||
return;
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
redrawHeroWin(hero);
|
||||
updateInfo(hero);
|
||||
}
|
||||
void CPlayerInterface::heroManaPointsChanged(const CGHeroInstance * hero)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
redrawHeroWin(hero);
|
||||
updateInfo(hero);
|
||||
}
|
||||
void CPlayerInterface::heroMovePointsChanged(const CGHeroInstance * hero)
|
||||
{
|
||||
@ -439,10 +414,7 @@ void CPlayerInterface::heroGotLevel(const CGHeroInstance *hero, int pskill, std:
|
||||
void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
//redraw infowindow
|
||||
SDL_FreeSurface(graphics->townWins[town->id]);
|
||||
graphics->townWins[town->id] = infoWin(town);
|
||||
|
||||
updateInfo(town);
|
||||
|
||||
if(town->garrisonHero && vstd::contains(wanderingHeroes,town->garrisonHero)) //wandering hero moved to the garrison
|
||||
{
|
||||
@ -479,30 +451,7 @@ void CPlayerInterface::heroVisitsTown(const CGHeroInstance* hero, const CGTownIn
|
||||
void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
|
||||
{
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
if(obj->ID == HEROI_TYPE) //hero
|
||||
{
|
||||
const CGHeroInstance * hh;
|
||||
if(hh = dynamic_cast<const CGHeroInstance*>(obj))
|
||||
{
|
||||
SDL_FreeSurface(graphics->heroWins[hh->subID]);
|
||||
graphics->heroWins[hh->subID] = infoWin(hh);
|
||||
}
|
||||
}
|
||||
else if (obj->ID == TOWNI_TYPE) //town
|
||||
{
|
||||
const CGTownInstance * tt;
|
||||
if(tt = static_cast<const CGTownInstance*>(obj))
|
||||
{
|
||||
SDL_FreeSurface(graphics->townWins[tt->id]);
|
||||
graphics->townWins[tt->id] = infoWin(tt);
|
||||
}
|
||||
if(tt->visitingHero)
|
||||
{
|
||||
SDL_FreeSurface(graphics->heroWins[tt->visitingHero->subID]);
|
||||
graphics->heroWins[tt->visitingHero->subID] = infoWin(tt->visitingHero);
|
||||
}
|
||||
|
||||
}
|
||||
updateInfo(obj);
|
||||
|
||||
bool wasGarrison = false;
|
||||
for(std::list<IShowActivable*>::iterator i = GH.listInt.begin(); i != GH.listInt.end(); i++)
|
||||
@ -530,12 +479,10 @@ void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID,
|
||||
switch (buildingID)
|
||||
{
|
||||
case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 15:
|
||||
{
|
||||
SDL_FreeSurface(graphics->townWins[town->id]);
|
||||
graphics->townWins[town->id] = infoWin(town);
|
||||
break;
|
||||
}
|
||||
updateInfo(town);
|
||||
break;
|
||||
}
|
||||
|
||||
if(!castleInt)
|
||||
return;
|
||||
if(castleInt->town!=town)
|
||||
@ -983,7 +930,7 @@ void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const HeroB
|
||||
{
|
||||
if(bonus.type == HeroBonus::NONE) return;
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
redrawHeroWin(hero);
|
||||
updateInfo(hero);
|
||||
}
|
||||
|
||||
template <typename Handler> void CPlayerInterface::serializeTempl( Handler &h, const int version )
|
||||
@ -1004,72 +951,63 @@ void CPlayerInterface::serialize( CISer<CLoadFile> &h, const int version )
|
||||
firstCall = -1;
|
||||
}
|
||||
|
||||
void CPlayerInterface::redrawHeroWin(const CGHeroInstance * hero)
|
||||
{
|
||||
if(!vstd::contains(graphics->heroWins,hero->subID))
|
||||
{
|
||||
tlog1 << "Cannot redraw infowindow for hero with subID=" << hero->subID << " - not present in our map\n";
|
||||
return;
|
||||
}
|
||||
SDL_FreeSurface(graphics->heroWins[hero->subID]);
|
||||
graphics->heroWins[hero->subID] = infoWin(hero);
|
||||
if (adventureInt->selection == hero)
|
||||
adventureInt->infoBar.draw(screen);
|
||||
}
|
||||
|
||||
bool CPlayerInterface::moveHero( const CGHeroInstance *h, CGPath path )
|
||||
{
|
||||
if (!h)
|
||||
return false; //can't find hero
|
||||
|
||||
pim->unlock();
|
||||
bool result = false;
|
||||
path.convert(0);
|
||||
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
|
||||
stillMoveHero.data = CONTINUE_MOVE;
|
||||
|
||||
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--)
|
||||
{
|
||||
//stop sending move requests if the next node can't be reached at the current turn (hero exhausted his move points)
|
||||
if(path.nodes[i-1].turns)
|
||||
{
|
||||
stillMoveHero.data = STOP_MOVE;
|
||||
break;
|
||||
}
|
||||
// Start a new sound for the hero movement or let the existing one carry on.
|
||||
#if 0
|
||||
// TODO
|
||||
if (hero is flying && sh == -1)
|
||||
sh = CGI->soundh->playSound(soundBase::horseFlying, -1);
|
||||
#endif
|
||||
{
|
||||
newTerrain = cb->getTileInfo(CGHeroInstance::convertPosition(path.nodes[i].coord, false))->tertype;
|
||||
path.convert(0);
|
||||
boost::unique_lock<boost::mutex> un(stillMoveHero.mx);
|
||||
stillMoveHero.data = CONTINUE_MOVE;
|
||||
|
||||
if (newTerrain != currentTerrain) {
|
||||
CGI->soundh->stopSound(sh);
|
||||
sh = CGI->soundh->playSound(CGI->soundh->horseSounds[newTerrain], -1);
|
||||
currentTerrain = 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--)
|
||||
{
|
||||
//stop sending move requests if the next node can't be reached at the current turn (hero exhausted his move points)
|
||||
if(path.nodes[i-1].turns)
|
||||
{
|
||||
stillMoveHero.data = STOP_MOVE;
|
||||
break;
|
||||
}
|
||||
// Start a new sound for the hero movement or let the existing one carry on.
|
||||
#if 0
|
||||
// TODO
|
||||
if (hero is flying && sh == -1)
|
||||
sh = CGI->soundh->playSound(soundBase::horseFlying, -1);
|
||||
#endif
|
||||
{
|
||||
newTerrain = cb->getTileInfo(CGHeroInstance::convertPosition(path.nodes[i].coord, false))->tertype;
|
||||
|
||||
if (newTerrain != currentTerrain) {
|
||||
CGI->soundh->stopSound(sh);
|
||||
sh = CGI->soundh->playSound(CGI->soundh->horseSounds[newTerrain], -1);
|
||||
currentTerrain = newTerrain;
|
||||
}
|
||||
}
|
||||
|
||||
stillMoveHero.data = WAITING_MOVE;
|
||||
|
||||
int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
|
||||
cb->moveHero(h,endpos);
|
||||
|
||||
eventsM.unlock();
|
||||
while(stillMoveHero.data != STOP_MOVE && stillMoveHero.data != CONTINUE_MOVE)
|
||||
stillMoveHero.cond.wait(un);
|
||||
eventsM.lock();
|
||||
}
|
||||
|
||||
stillMoveHero.data = WAITING_MOVE;
|
||||
|
||||
int3 endpos(path.nodes[i-1].coord.x, path.nodes[i-1].coord.y, h->pos.z);
|
||||
cb->moveHero(h,endpos);
|
||||
|
||||
eventsM.unlock();
|
||||
while(stillMoveHero.data != STOP_MOVE && stillMoveHero.data != CONTINUE_MOVE)
|
||||
stillMoveHero.cond.wait(un);
|
||||
eventsM.lock();
|
||||
CGI->soundh->stopSound(sh);
|
||||
cb->recalculatePaths();
|
||||
}
|
||||
|
||||
CGI->soundh->stopSound(sh);
|
||||
|
||||
//stillMoveHero = false;
|
||||
cb->recalculatePaths();
|
||||
pim->lock();
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -1905,15 +1843,6 @@ void CPlayerInterface::acceptTurn()
|
||||
adventureInt->startTurn();
|
||||
|
||||
boost::unique_lock<boost::recursive_mutex> un(*pim);
|
||||
for(std::map<int,SDL_Surface*>::iterator i=graphics->heroWins.begin(); i!=graphics->heroWins.end();i++) //redraw hero infoboxes
|
||||
SDL_FreeSurface(i->second);
|
||||
graphics->heroWins.clear();
|
||||
std::vector <const CGHeroInstance *> hh = cb->getHeroesInfo(false);
|
||||
for(int i=0;i<hh.size();i++)
|
||||
{
|
||||
SDL_Surface * pom = infoWin(hh[i]);
|
||||
graphics->heroWins.insert(std::pair<int,SDL_Surface*>(hh[i]->subID,pom));
|
||||
}
|
||||
|
||||
/* TODO: This isn't quite right. First day in game should play
|
||||
* NEWDAY. And we don't play NEWMONTH. */
|
||||
@ -1952,3 +1881,10 @@ void CPlayerInterface::tryDiggging(const CGHeroInstance *h)
|
||||
cb->dig(h);
|
||||
}
|
||||
}
|
||||
|
||||
void CPlayerInterface::updateInfo(const CGObjectInstance * specific)
|
||||
{
|
||||
adventureInt->infoBar.updateSelection(specific);
|
||||
// if (adventureInt->selection == specific)
|
||||
// adventureInt->infoBar.showAll(screen);
|
||||
}
|
@ -207,6 +207,7 @@ public:
|
||||
void openTownWindow(const CGTownInstance * town); //shows townscreen
|
||||
void openHeroWindow(const CGHeroInstance * hero); //shows hero window with given hero
|
||||
SDL_Surface * infoWin(const CGObjectInstance * specific); //specific=0 => draws info about selected town/hero
|
||||
void updateInfo(const CGObjectInstance * specific);
|
||||
void init(ICallback * CB);
|
||||
int3 repairScreenPos(int3 pos); //returns position closest to pos we can center screen on
|
||||
void showInfoDialog(const std::string &text, const std::vector<SComponent*> & components = std::vector<SComponent*>(), int soundID = 0);
|
||||
|
@ -2467,9 +2467,7 @@ void CBonusSelection::CRegion::clickRight( tribool down, bool previousState )
|
||||
if( down && !CSDL_Ext::isTransparent(graphics[0], GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) &&
|
||||
rclickText.size() )
|
||||
{
|
||||
CSimpleWindow * temp = CMessage::genWindow(rclickText, 0, true);
|
||||
CRClickPopupInt *rcpi = new CRClickPopupInt(temp, true);
|
||||
GH.pushInt(rcpi);
|
||||
CRClickPopup::createAndPush(rclickText);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +51,7 @@ void SpellbookInteractiveArea::clickLeft(tribool down, bool previousState)
|
||||
|
||||
void SpellbookInteractiveArea::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
adventureInt->handleRightClick(textOnRclick, down, this);
|
||||
adventureInt->handleRightClick(textOnRclick, down);
|
||||
}
|
||||
|
||||
void SpellbookInteractiveArea::hover(bool on)
|
||||
@ -688,13 +688,14 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
else
|
||||
{
|
||||
using namespace Spells;
|
||||
int spell = mySpell;
|
||||
const CGHeroInstance *h = owner->myHero;
|
||||
owner->fexitb();
|
||||
|
||||
switch(spell)
|
||||
{
|
||||
case 0: //summon boat
|
||||
case SUMMON_BOAT:
|
||||
{
|
||||
int3 pos = h->bestLocation();
|
||||
if(pos.x < 0)
|
||||
@ -703,6 +704,21 @@ void CSpellWindow::SpellArea::clickLeft(tribool down, bool previousState)
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCUTTLE_BOAT:
|
||||
case DIMENSION_DOOR:
|
||||
adventureInt->enterCastingMode(sp);
|
||||
return;
|
||||
case VISIONS:
|
||||
case VIEW_EARTH:
|
||||
case DISGUISE:
|
||||
case VIEW_AIR:
|
||||
case FLY:
|
||||
case WATER_WALK:
|
||||
case TOWN_PORTAL:
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
|
||||
LOCPLINT->cb->castSpell(h, spell);
|
||||
|
@ -313,7 +313,10 @@ int CClient::getCurrentPlayer()
|
||||
|
||||
int CClient::getSelectedHero()
|
||||
{
|
||||
return IGameCallback::getSelectedHero(getCurrentPlayer())->id;
|
||||
if(const CGHeroInstance *selHero = IGameCallback::getSelectedHero(getCurrentPlayer()))
|
||||
return selHero->id;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CClient::newGame( CConnection *con, StartInfo *si )
|
||||
|
@ -71,6 +71,9 @@ struct Point
|
||||
Point(const int3 &a)
|
||||
:x(a.x),y(a.y)
|
||||
{}
|
||||
Point(const SDL_MouseMotionEvent &a)
|
||||
:x(a.x),y(a.y)
|
||||
{}
|
||||
|
||||
template<typename T>
|
||||
Point operator+(const T &b) const
|
||||
@ -365,6 +368,8 @@ public:
|
||||
ui8 defActions; //which calls will be tried to be redirected to children
|
||||
ui8 recActions; //which calls we allow te receive from parent
|
||||
|
||||
enum EAlignment {TOPLEFT, CENTER, BOTTOMRIGHT};
|
||||
|
||||
void disable(); //deactivates if needed, blocks all automatic activity, allows only disposal
|
||||
void enable(bool activation = true); //activates if needed, all activity enabled (Warning: may not be symetric with disable if recActions was limited!)
|
||||
void defActivate();
|
||||
|
@ -770,21 +770,55 @@ void CRClickPopup::close()
|
||||
GH.popIntTotally(this);
|
||||
}
|
||||
|
||||
void CRClickPopup::createAndPush(const std::string &txt)
|
||||
{
|
||||
int player = LOCPLINT ? LOCPLINT->playerID : 1; //if no player, then use blue
|
||||
CSimpleWindow * temp = CMessage::genWindow(txt,player,true);
|
||||
CRClickPopupInt *rcpi = new CRClickPopupInt(temp,true);
|
||||
GH.pushInt(rcpi);
|
||||
}
|
||||
|
||||
void CRClickPopup::createAndPush(const CGObjectInstance *obj, const Point &p, EAlignment alignment /*= BOTTOMRIGHT*/)
|
||||
{
|
||||
SDL_Surface *iWin = LOCPLINT->infoWin(obj); //try get custom infowindow for this obj
|
||||
if(iWin)
|
||||
GH.pushInt(new CInfoPopup(iWin, p, alignment, true));
|
||||
else
|
||||
CRClickPopup::createAndPush(obj->getHoverText());
|
||||
}
|
||||
|
||||
CRClickPopup::CRClickPopup()
|
||||
{
|
||||
}
|
||||
|
||||
CRClickPopup::~CRClickPopup()
|
||||
{
|
||||
}
|
||||
|
||||
CInfoPopup::CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free)
|
||||
:free(Free),bitmap(Bitmap)
|
||||
{
|
||||
CGI->curh->hide();
|
||||
init(x, y);
|
||||
}
|
||||
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
pos.h = bitmap->h;
|
||||
pos.w = bitmap->w;
|
||||
|
||||
// Put the window back on screen if necessary
|
||||
amax(pos.x, 0);
|
||||
amax(pos.y, 0);
|
||||
amin(pos.x, conf.cc.resx - bitmap->w);
|
||||
amin(pos.y, conf.cc.resy - bitmap->h);
|
||||
CInfoPopup::CInfoPopup(SDL_Surface * Bitmap, const Point &p, EAlignment alignment, bool Free/*=false*/)
|
||||
: free(Free),bitmap(Bitmap)
|
||||
{
|
||||
switch(alignment)
|
||||
{
|
||||
case BOTTOMRIGHT:
|
||||
init(p.x - Bitmap->w, p.y - Bitmap->h);
|
||||
break;
|
||||
case CENTER:
|
||||
init(p.x - Bitmap->w/2, p.y - Bitmap->h/2);
|
||||
break;
|
||||
case TOPLEFT:
|
||||
init(p.x, p.y);
|
||||
break;
|
||||
default:
|
||||
assert(0); //not implemented
|
||||
}
|
||||
}
|
||||
|
||||
CInfoPopup::CInfoPopup(SDL_Surface *Bitmap, bool Free)
|
||||
@ -818,6 +852,22 @@ CInfoPopup::~CInfoPopup()
|
||||
CGI->curh->show();
|
||||
}
|
||||
|
||||
void CInfoPopup::init(int x, int y)
|
||||
{
|
||||
CGI->curh->hide();
|
||||
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
pos.h = bitmap->h;
|
||||
pos.w = bitmap->w;
|
||||
|
||||
// Put the window back on screen if necessary
|
||||
amax(pos.x, 0);
|
||||
amax(pos.y, 0);
|
||||
amin(pos.x, conf.cc.resx - bitmap->w);
|
||||
amin(pos.y, conf.cc.resy - bitmap->h);
|
||||
}
|
||||
|
||||
void SComponent::init(Etype Type, int Subtype, int Val)
|
||||
{
|
||||
std::ostringstream oss;
|
||||
@ -961,7 +1011,7 @@ SDL_Surface * SComponent::getImg()
|
||||
void SComponent::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
if(description.size())
|
||||
adventureInt->handleRightClick(description,down,this);
|
||||
adventureInt->handleRightClick(description,down);
|
||||
}
|
||||
void SComponent::activate()
|
||||
{
|
||||
@ -1277,7 +1327,7 @@ void CHeroList::select(int which)
|
||||
adventureInt->selection = NULL;
|
||||
adventureInt->terrain.currentPath = NULL;
|
||||
draw(screen);
|
||||
adventureInt->infoBar.draw(screen);
|
||||
adventureInt->infoBar.showAll(screen);
|
||||
}
|
||||
if (which>=LOCPLINT->wanderingHeroes.size())
|
||||
return;
|
||||
@ -1397,11 +1447,11 @@ void CHeroList::clickRight(tribool down, bool previousState)
|
||||
/***************************ARROWS*****************************************/
|
||||
if(isItIn(&arrupp,GH.current->motion.x,GH.current->motion.y) && from>0)
|
||||
{
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[303].second,down,this);
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[303].second,down);
|
||||
}
|
||||
else if(isItIn(&arrdop,GH.current->motion.x,GH.current->motion.y) && (LOCPLINT->wanderingHeroes.size()-from>5))
|
||||
{
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[304].second,down,this);
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[304].second,down);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1413,21 +1463,11 @@ void CHeroList::clickRight(tribool down, bool previousState)
|
||||
if ((ny>SIZE || ny<0) || (from+ny>=LOCPLINT->wanderingHeroes.size()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
} //show popup
|
||||
|
||||
//show popup
|
||||
CInfoPopup * ip = new CInfoPopup(graphics->heroWins[LOCPLINT->wanderingHeroes[from+ny]->subID],
|
||||
GH.current->motion.x-graphics->heroWins[LOCPLINT->wanderingHeroes[from+ny]->subID]->w,
|
||||
GH.current->motion.y-graphics->heroWins[LOCPLINT->wanderingHeroes[from+ny]->subID]->h,
|
||||
false);
|
||||
GH.pushInt(ip);
|
||||
CRClickPopup::createAndPush(LOCPLINT->wanderingHeroes[from+ny], GH.current->motion);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[303].second,down,this);
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[304].second,down,this);
|
||||
}
|
||||
}
|
||||
|
||||
void CHeroList::hover (bool on)
|
||||
@ -1692,11 +1732,11 @@ void CTownList::clickRight(tribool down, bool previousState)
|
||||
/***************************ARROWS*****************************************/
|
||||
if(isItIn(&arrupp,GH.current->motion.x,GH.current->motion.y) && from>0)
|
||||
{
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[306].second,down,this);
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[306].second,down);
|
||||
}
|
||||
else if(isItIn(&arrdop,GH.current->motion.x,GH.current->motion.y) && (LOCPLINT->towns.size()-from>5))
|
||||
{
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[307].second,down,this);
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[307].second,down);
|
||||
}
|
||||
//if not buttons then towns
|
||||
int hx = GH.current->motion.x, hy = GH.current->motion.y;
|
||||
@ -1709,17 +1749,7 @@ void CTownList::clickRight(tribool down, bool previousState)
|
||||
}
|
||||
|
||||
//show popup
|
||||
CInfoPopup * ip = new CInfoPopup(
|
||||
graphics->townWins[LOCPLINT->towns[from+ny]->id],
|
||||
GH.current->motion.x-graphics->townWins[LOCPLINT->towns[from+ny]->id]->w,
|
||||
GH.current->motion.y-graphics->townWins[LOCPLINT->towns[from+ny]->id]->h,
|
||||
false);
|
||||
GH.pushInt(ip);
|
||||
}
|
||||
else
|
||||
{
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[306].second,down,this);
|
||||
adventureInt->handleRightClick(CGI->generaltexth->zelp[307].second,down,this);
|
||||
CRClickPopup::createAndPush(LOCPLINT->towns[from+ny], GH.current->motion);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3912,7 +3942,7 @@ void LRClickableAreaWText::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
void LRClickableAreaWText::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
adventureInt->handleRightClick(text, down, this);
|
||||
adventureInt->handleRightClick(text, down);
|
||||
}
|
||||
void LRClickableAreaWText::activate()
|
||||
{
|
||||
@ -3950,7 +3980,7 @@ void LRClickableAreaWTextComp::clickLeft(tribool down, bool previousState)
|
||||
}
|
||||
void LRClickableAreaWTextComp::clickRight(tribool down, bool previousState)
|
||||
{
|
||||
adventureInt->handleRightClick(text, down, this);
|
||||
adventureInt->handleRightClick(text, down);
|
||||
}
|
||||
void LRClickableAreaWTextComp::activate()
|
||||
{
|
||||
|
@ -63,6 +63,7 @@ class CArtifact;
|
||||
class CArtifactsOfHero;
|
||||
class CResDataBar;
|
||||
struct SPuzzleInfo;
|
||||
class CGGarrison;
|
||||
|
||||
extern SDL_Color tytulowy, tlo, zwykly ;
|
||||
|
||||
@ -103,7 +104,12 @@ public:
|
||||
virtual void deactivate();
|
||||
virtual void close();
|
||||
void clickRight(tribool down, bool previousState);
|
||||
virtual ~CRClickPopup(){}; //d-tor
|
||||
|
||||
CRClickPopup();
|
||||
virtual ~CRClickPopup(); //d-tor
|
||||
|
||||
static void createAndPush(const std::string &txt);
|
||||
static void createAndPush(const CGObjectInstance *obj, const Point &p, EAlignment alignment = BOTTOMRIGHT);
|
||||
};
|
||||
|
||||
class CRClickPopupInt : public CRClickPopup //popup displayed on R-click
|
||||
@ -125,7 +131,10 @@ public:
|
||||
void close();
|
||||
void show(SDL_Surface * to);
|
||||
CInfoPopup(SDL_Surface * Bitmap, int x, int y, bool Free=false); //c-tor
|
||||
CInfoPopup(SDL_Surface * Bitmap, const Point &p, EAlignment alignment, bool Free=false); //c-tor
|
||||
CInfoPopup(SDL_Surface *Bitmap = NULL, bool Free = false); //default c-tor
|
||||
|
||||
void init(int x, int y);
|
||||
~CInfoPopup(); //d-tor
|
||||
};
|
||||
|
||||
@ -265,7 +274,7 @@ class CLabel
|
||||
: public virtual CIntObject
|
||||
{
|
||||
public:
|
||||
enum EAlignment {TOPLEFT, CENTER, BOTTOMRIGHT} alignment;
|
||||
EAlignment alignment;
|
||||
EFonts font;
|
||||
SDL_Color color;
|
||||
std::string text;
|
||||
|
@ -64,8 +64,6 @@ public:
|
||||
CDefEssential *luck22, *luck30, *luck42, *luck82,
|
||||
*morale22, *morale30, *morale42, *morale82,
|
||||
*halls, *forts, *bigTownPic;
|
||||
std::map<int,SDL_Surface*> heroWins; //hero_ID => infobox
|
||||
std::map<int,SDL_Surface*> townWins; //town_ID => infobox
|
||||
CDefEssential * artDefs; //artifacts
|
||||
std::vector<SDL_Surface *> portraitSmall; //48x32 px portraits of heroes
|
||||
std::vector<SDL_Surface *> portraitLarge; //58x64 px portraits of heroes
|
||||
|
@ -1013,11 +1013,13 @@ void CSDL_Ext::setPlayerColor(SDL_Surface * sur, unsigned char player)
|
||||
return;
|
||||
if(sur->format->BitsPerPixel==8)
|
||||
{
|
||||
if(player != 255)
|
||||
*(sur->format->palette->colors+5) = graphics->playerColors[player];
|
||||
else
|
||||
*(sur->format->palette->colors+5) = *graphics->neutralColor;
|
||||
SDL_Color *color = (player == 255
|
||||
? graphics->neutralColor
|
||||
: &graphics->playerColors[player]);
|
||||
SDL_SetColors(sur, color, 5, 1);
|
||||
}
|
||||
else
|
||||
tlog3 << "Warning, setPlayerColor called on not 8bpp surface!\n";
|
||||
}
|
||||
int readNormalNr (std::istream &in, int bytCon)
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "../lib/map.h"
|
||||
#include <sstream>
|
||||
#include <SDL_stdinc.h>
|
||||
#include <boost/foreach.hpp>
|
||||
using namespace boost::assign;
|
||||
|
||||
/*
|
||||
@ -1238,7 +1239,7 @@ int CGHeroInstance::getBoatType() const
|
||||
case 2:
|
||||
return 2;
|
||||
default:
|
||||
assert(0);
|
||||
throw std::string("Wrong alignment!");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1254,6 +1255,17 @@ int CGHeroInstance::getSpellCost(const CSpell *sp) const
|
||||
return sp->costs[getSpellSchoolLevel(sp)];
|
||||
}
|
||||
|
||||
int CGHeroInstance::getBonusesCount(int from, int id) const
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
BOOST_FOREACH(const HeroBonus &hb, bonuses)
|
||||
if(hb.source == from && hb.id == id)
|
||||
ret++;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void CGDwelling::initObj()
|
||||
{
|
||||
switch(ID)
|
||||
|
@ -313,6 +313,7 @@ public:
|
||||
|
||||
const BonusList *ownerBonuses() const;
|
||||
const HeroBonus *getBonus(int from, int id) const;
|
||||
int getBonusesCount(int from, int id) const;
|
||||
int valOfBonuses(HeroBonus::BonusType type, int subtype = -1) const; //subtype -> subtype of bonus, if -1 then any
|
||||
bool hasBonusOfType(HeroBonus::BonusType type, int subtype = -1) const; //determines if hero has a bonus of given type (and optionally subtype)
|
||||
void getModifiersWDescr(std::vector<std::pair<int,std::string> > &out, HeroBonus::BonusType type, int subtype = -1) const; //out: pairs<modifier value, modifier description>
|
||||
|
@ -194,6 +194,15 @@ static bool startsWithX(const std::string &s)
|
||||
return s.size() && s[0] == 'x';
|
||||
}
|
||||
|
||||
bool DLL_EXPORT isInScreenRange(const int3 ¢er, const int3 &pos)
|
||||
{
|
||||
int3 diff = pos - center;
|
||||
if(diff.x >= -9 && diff.x <= 9 && diff.y >= -8 && diff.y <= 8)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void CSpellHandler::loadSpells()
|
||||
{
|
||||
std::string buf = bitmaph->getTextFile("SPTRAITS.TXT"), pom;
|
||||
|
@ -51,6 +51,13 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
namespace Spells
|
||||
{
|
||||
enum {SUMMON_BOAT=0, SCUTTLE_BOAT, VISIONS, VIEW_EARTH, DISGUISE, VIEW_AIR, FLY, WATER_WALK, DIMENSION_DOOR, TOWN_PORTAL};
|
||||
}
|
||||
|
||||
bool DLL_EXPORT isInScreenRange(const int3 ¢er, const int3 &pos); //for spells like Dimension Door
|
||||
|
||||
class DLL_EXPORT CSpellHandler
|
||||
{
|
||||
public:
|
||||
|
@ -1988,12 +1988,16 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
|
||||
return false;
|
||||
|
||||
int3 hpos = hero->getPosition(false);
|
||||
tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
|
||||
|
||||
if (!hero->canWalkOnSea())
|
||||
blockLandSea = (map->getTile(hpos).tertype != TerrainTile::water); //block land if hero is on water and vice versa
|
||||
else
|
||||
blockLandSea = boost::logic::indeterminate;
|
||||
bool flying = false; //hero is under flying effect TODO
|
||||
bool waterWalking = false; //hero is on land and can walk on water TODO
|
||||
bool onLand = map->getTile(hpos).tertype != TerrainTile::water;
|
||||
// tribool blockLandSea; //true - blocks sea, false - blocks land, indeterminate - allows all
|
||||
//
|
||||
// if (!hero->canWalkOnSea())
|
||||
// blockLandSea = (map->getTile(hpos).tertype != TerrainTile::water); //block land if hero is on water and vice versa
|
||||
// else
|
||||
// blockLandSea = boost::logic::indeterminate;
|
||||
|
||||
const std::vector<std::vector<std::vector<ui8> > > &FoW = getPlayer(hero->tempOwner)->fogOfWarMap;
|
||||
|
||||
@ -2016,9 +2020,7 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
|
||||
node.coord.y = j;
|
||||
node.coord.z = dest.z;
|
||||
|
||||
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
|
||||
if(!tinfo->entrableTerrain(onLand, flying || waterWalking)
|
||||
|| !FoW[i][j][src.z] //tile is covered by the FoW
|
||||
)
|
||||
{
|
||||
@ -2039,7 +2041,7 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
|
||||
d.accessible = true; //for allowing visiting objects
|
||||
}
|
||||
|
||||
if(blockLandSea && t->tertype == TerrainTile::water) //hero can walk only on land and dst lays on the water
|
||||
if(onLand && t->tertype == TerrainTile::water) //hero can walk only on land and dst lays on the water
|
||||
{
|
||||
size_t i = 0;
|
||||
for(; i < t->visitableObjects.size(); i++)
|
||||
@ -2048,7 +2050,7 @@ bool CGameState::getPath(int3 src, int3 dest, const CGHeroInstance * hero, CPath
|
||||
|
||||
d.accessible = (i < t->visitableObjects.size()); //dest is accessible only if there is boat/hero
|
||||
}
|
||||
else if(!blockLandSea && t->tertype != TerrainTile::water) //hero is moving by water
|
||||
else if(!onLand && t->tertype != TerrainTile::water) //hero is moving by water
|
||||
{
|
||||
d.accessible = (t->siodmyTajemniczyBajt & 64) && !t->blocked; //tile is accessible if it's coastal and not blocked
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ struct DLL_EXPORT HeroBonus
|
||||
FREE_SHIP_BOARDING //movement points preserved with ship boarding and landing
|
||||
};
|
||||
enum BonusDuration{PERMANENT, ONE_BATTLE, ONE_DAY, ONE_WEEK};
|
||||
enum BonusSource{ARTIFACT, OBJECT};
|
||||
enum BonusSource{ARTIFACT, OBJECT, CASTED_SPELL};
|
||||
|
||||
ui8 duration; //uses BonusDuration values
|
||||
ui8 type; //uses BonusType values - says to what is this bonus
|
||||
|
@ -476,7 +476,7 @@ struct TryMoveHero : public CPackForClient //501
|
||||
|
||||
ui32 id, movePoints;
|
||||
ui8 result; //uses EResult
|
||||
int3 start, end;
|
||||
int3 start, end; //h3m format
|
||||
std::set<int3> fowRevealed; //revealed tiles
|
||||
|
||||
bool humanKnows; //used locally during applying to client
|
||||
|
16
lib/map.cpp
16
lib/map.cpp
@ -2129,3 +2129,19 @@ CVictoryCondition::CVictoryCondition()
|
||||
obj = NULL;
|
||||
ID = allowNormalVictory = appliesToAI = count = 0;
|
||||
}
|
||||
|
||||
bool TerrainTile::entrableTerrain(const TerrainTile *from /*= NULL*/) const
|
||||
{
|
||||
return entrableTerrain(from ? from->tertype != water : true, from ? from->tertype == water : true);
|
||||
}
|
||||
|
||||
bool TerrainTile::entrableTerrain(bool allowLand, bool allowSea) const
|
||||
{
|
||||
return tertype != rock
|
||||
&& (allowSea && tertype == water || allowLand && tertype != water);
|
||||
}
|
||||
|
||||
bool TerrainTile::isClear(const TerrainTile *from /*= NULL*/) const
|
||||
{
|
||||
return entrableTerrain(from) && !blocked;
|
||||
}
|
@ -95,6 +95,10 @@ struct DLL_EXPORT TerrainTile
|
||||
//these flags (and obj vectors) will be restored in map serialization
|
||||
}
|
||||
}
|
||||
|
||||
bool entrableTerrain(const TerrainTile *from = NULL) const; //checks if terrain is not a rock. If from is water/land, same type is also required.
|
||||
bool entrableTerrain(bool allowLand, bool allowSea) const; //checks if terrain is not a rock. If from is water/land, same type is also required.
|
||||
bool isClear(const TerrainTile *from = NULL) const; //checks for blocking objs and terraint type (water / land)
|
||||
};
|
||||
struct DLL_EXPORT SheroName //name of starting hero
|
||||
{
|
||||
|
@ -4213,9 +4213,10 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
|
||||
if(s->combatSpell)
|
||||
COMPLAIN_RET("This function can be used only for adventure map spells!");
|
||||
|
||||
using namespace Spells;
|
||||
switch(spellID)
|
||||
{
|
||||
case 0: //Summon Boat
|
||||
case SUMMON_BOAT: //Summon Boat
|
||||
{
|
||||
//check if spell works at all
|
||||
if(rand() % 100 >= s->powers[schoolLevel]) //power is % chance of success
|
||||
@ -4277,15 +4278,79 @@ bool CGameHandler::castSpell(const CGHeroInstance *h, int spellID, const int3 &p
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: //Scuttle Boat
|
||||
case 2: //Visions
|
||||
case 3: //View Earth
|
||||
case 4: //Disguise
|
||||
case 5: //View Air
|
||||
case 6: //Fly
|
||||
case 7: //Water Walk
|
||||
case 8: //Dimension Door
|
||||
case 9: //Town Portal
|
||||
case SCUTTLE_BOAT: //Scuttle Boat
|
||||
{
|
||||
//check if spell works at all
|
||||
if(rand() % 100 >= s->powers[schoolLevel]) //power is % chance of success
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.addTxt(MetaString::GENERAL_TXT, 337); //%s tried to scuttle the boat, but failed
|
||||
iw.text.addReplacement(h->name);
|
||||
sendAndApply(&iw);
|
||||
return true; //TODO? or should it be false? request was correct and realized, but spell failed...
|
||||
}
|
||||
|
||||
//TODO: test range, visibility
|
||||
const TerrainTile *t = &gs->map->getTile(pos);
|
||||
if(!t->visitableObjects.size() || t->visitableObjects.back()->ID != 8)
|
||||
COMPLAIN_RET("There is no boat to scuttle!");
|
||||
|
||||
RemoveObject ro;
|
||||
ro.id = t->visitableObjects.back()->id;
|
||||
sendAndApply(&ro);
|
||||
break;
|
||||
}
|
||||
case DIMENSION_DOOR: //Dimension Door
|
||||
{
|
||||
const TerrainTile *dest = getTile(pos);
|
||||
const TerrainTile *curr = getTile(h->getSightCenter());
|
||||
|
||||
if(!dest)
|
||||
COMPLAIN_RET("Destination tile doesn't exist!");
|
||||
if(!h->movement)
|
||||
COMPLAIN_RET("Hero needs movement points to cast Dimension Door!");
|
||||
if(h->getBonusesCount(HeroBonus::CASTED_SPELL, Spells::DIMENSION_DOOR) >= s->powers[schoolLevel]) //limit casts per turn
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.addTxt(MetaString::GENERAL_TXT, 338); //%s is not skilled enough to cast this spell again today.
|
||||
iw.text.addReplacement(h->name);
|
||||
sendAndApply(&iw);
|
||||
break;
|
||||
}
|
||||
|
||||
GiveBonus gb;
|
||||
gb.id = h->id;
|
||||
gb.bonus = HeroBonus(HeroBonus::ONE_DAY, HeroBonus::NONE, HeroBonus::CASTED_SPELL, 0, Spells::DIMENSION_DOOR);
|
||||
sendAndApply(&gb);
|
||||
|
||||
if(!dest->isClear(curr)) //wrong dest tile
|
||||
{
|
||||
InfoWindow iw;
|
||||
iw.player = h->tempOwner;
|
||||
iw.text.addTxt(MetaString::GENERAL_TXT, 70); //Dimension Door failed!
|
||||
sendAndApply(&iw);
|
||||
break;
|
||||
}
|
||||
|
||||
TryMoveHero tmh;
|
||||
tmh.id = h->id;
|
||||
tmh.movePoints = std::max<int>(0, h->movement - 300);
|
||||
tmh.result = TryMoveHero::TELEPORTATION;
|
||||
tmh.start = h->pos;
|
||||
tmh.end = pos;
|
||||
getTilesInRange(tmh.fowRevealed, pos, h->getSightRadious(), h->tempOwner,1);
|
||||
sendAndApply(&tmh);
|
||||
}
|
||||
break;
|
||||
case VISIONS: //Visions
|
||||
case VIEW_EARTH: //View Earth
|
||||
case DISGUISE: //Disguise
|
||||
case VIEW_AIR: //View Air
|
||||
case FLY: //Fly
|
||||
case WATER_WALK: //Water Walk
|
||||
case TOWN_PORTAL: //Town Portal
|
||||
default:
|
||||
COMPLAIN_RET("This spell is not implemented yet!");
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user