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

- fixed several crashes with joining creatures

- support for loading *.tga images
- minor fixes
This commit is contained in:
Ivan Savenko 2011-07-18 15:21:16 +00:00
parent 79f5b29196
commit 0693312a8e
13 changed files with 255 additions and 164 deletions

View File

@ -577,22 +577,7 @@ SDLImage::SDLImage(SDL_Surface * from, bool extraRef):
SDLImage::SDLImage(std::string filename, bool compressed):
margins(0,0)
{
if (spriteh->haveFile(filename, FILE_GRAPHICS))
{
int size;
unsigned char * pic=NULL;
pic = spriteh->giveFile(filename, FILE_GRAPHICS, &size);
surf = IMG_Load_RW( SDL_RWFromMem((void*)pic, size), 1);
delete [] pic;
}
else if(bitmaph->haveFile(filename, FILE_GRAPHICS))
{
surf = BitmapHandler::loadBitmap(filename);
}
else
{
surf = NULL;
}
surf = BitmapHandler::loadBitmap(filename);
if (surf == NULL)
{

View File

@ -17,10 +17,9 @@
*
*/
boost::mutex bitmap_handler_mx;
extern DLL_EXPORT CLodHandler *bitmaph;
extern DLL_EXPORT CLodHandler *bitmaph_ab;
extern DLL_EXPORT CLodHandler *spriteh;
void CPCXConv::openPCX(char * PCX, int len)
{
@ -53,7 +52,7 @@ SDL_Surface * CPCXConv::getSurface() const
int width = -1, height = -1;
Epcxformat format;
int fSize,y;//,i; //TODO use me 'i'
int fSize,y;
bool check1, check2;
unsigned char add;
int it=0;
@ -149,26 +148,23 @@ bool isPCX(const unsigned char *header)//check whether file can be PCX according
return fSize == width*height || fSize == width*height*3;
}
SDL_Surface * BitmapHandler::loadBitmap(std::string fname, bool setKey)
SDL_Surface * BitmapHandler::loadBitmapFromLod(CLodHandler *lod, std::string fname, bool setKey)
{
if(!fname.size())
{
tlog2 << "Call to loadBitmap with void fname!\n";
return NULL;
}
SDL_Surface * ret=NULL;
int size;
unsigned char * file = 0;
if (bitmaph->haveFile(fname, FILE_GRAPHICS))
file = bitmaph->giveFile(fname, FILE_GRAPHICS, &size);
else if (bitmaph_ab->haveFile(fname, FILE_GRAPHICS))
file = bitmaph_ab->giveFile(fname, FILE_GRAPHICS, &size);
if (!file)
if (!lod->haveFile(fname, FILE_GRAPHICS))
{
tlog2<<"Entry for file "<<fname<<" was not found"<<std::endl;
return NULL;
}
SDL_Surface * ret=NULL;
int size;
unsigned char * file = 0;
file = lod->giveFile(fname, FILE_GRAPHICS, &size);
if (isPCX(file))
{//H3-style PCX
@ -185,10 +181,37 @@ SDL_Surface * BitmapHandler::loadBitmap(std::string fname, bool setKey)
}
else
{ //loading via SDL_Image
ret = IMG_Load_RW( SDL_RWFromMem((void*)file, size), 1);
std::string filename = lod->getFileName(fname, FILE_GRAPHICS);
std::string ext;
lod->convertName(filename, &ext);
if (ext == ".TGA")//Special case - targa can't be loaded by IMG_Load_RW (no magic constants in header)
{
SDL_RWops *rw = SDL_RWFromMem((void*)file, size);
ret = IMG_LoadTGA_RW( rw );
SDL_FreeRW(rw);
}
else
ret = IMG_Load_RW( SDL_RWFromMem((void*)file, size), 1);
if (!ret)
tlog1<<"Failed to open "<<fname<<" via SDL_Image\n";
delete [] file;
}
return ret;
}
SDL_Surface * BitmapHandler::loadBitmap(std::string fname, bool setKey)
{
if (bitmaph->haveFile(fname, FILE_GRAPHICS))
return loadBitmapFromLod(bitmaph, fname, setKey);
if (bitmaph_ab->haveFile(fname, FILE_GRAPHICS))
return loadBitmapFromLod(bitmaph_ab, fname, setKey);
if (spriteh->haveFile(fname, FILE_GRAPHICS))
return loadBitmapFromLod(spriteh, fname, setKey);
tlog1<<"Failed to find file "<<fname<<"\n";
return NULL;
}

View File

@ -47,6 +47,9 @@ public:
namespace BitmapHandler
{
//Load file from specific LOD
SDL_Surface * loadBitmapFromLod(CLodHandler *lod, std::string fname, bool setKey=true);
//Load file from any LODs
SDL_Surface * loadBitmap(std::string fname, bool setKey=true);
};

View File

@ -1032,25 +1032,25 @@ void CCastleInterface::recreateIcons()
creainfo.clear();
for (size_t i=0; i<4; i++)
creainfo.push_back(new CCreaInfo(14+55*i, 459, town, i));
creainfo.push_back(new CCreaInfo(Point(14+55*i, 459), town, i));
for (size_t i=0; i<4; i++)
creainfo.push_back(new CCreaInfo(14+55*i, 507, town, i+4));
creainfo.push_back(new CCreaInfo(Point(14+55*i, 507), town, i+4));
}
CCreaInfo::CCreaInfo(int posX, int posY, const CGTownInstance *Town, int Level):
CCreaInfo::CCreaInfo(Point position, const CGTownInstance *Town, int Level, bool compact, bool ShowAvailable):
town(Town),
level(Level)
level(Level),
showAvailable(ShowAvailable)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos.x += posX;
pos.y += posY;
pos.w = 48;
pos.h = 48;
pos += position;
if ( town->creatures.size() <= level || town->creatures[level].second.empty())
{
level = -1;
label = NULL;
picture = NULL;
return;//No creature
}
used = LCLICK | RCLICK | HOVER;
@ -1058,8 +1058,42 @@ CCreaInfo::CCreaInfo(int posX, int posY, const CGTownInstance *Town, int Level):
unsigned int creatureID = town->creatures[level].second.back();
creature = CGI->creh->creatures[creatureID];
label = new CLabel(24, 40, FONT_SMALL, CENTER, zwykly, boost::lexical_cast<std::string>(town->creatureGrowth(level)));
picture = new CAnimImage("CPRSMALL", creatureID+2, 0, 8, 0);
std::string value;
if (showAvailable)
value = boost::lexical_cast<std::string>(town->creatures[level].first);
else
value = boost::lexical_cast<std::string>(town->creatureGrowth(level));
if (compact)
{
label = new CLabel(40, 32, FONT_TINY, BOTTOMRIGHT, zwykly, value);
pos.x += 8;
pos.w = 32;
pos.h = 32;
}
else
{
label = new CLabel(24, 40, FONT_SMALL, CENTER, zwykly, value);
pos.w = 48;
pos.h = 48;
}
}
void CCreaInfo::update()
{
if (label)
{
std::string value;
if (showAvailable)
value = boost::lexical_cast<std::string>(town->creatures[level].first);
else
value = boost::lexical_cast<std::string>(town->creatureGrowth(level));
if (value != label->text)
label->setTxt(value);
}
}
void CCreaInfo::hover(bool on)
@ -1076,9 +1110,14 @@ void CCreaInfo::hover(bool on)
}
void CCreaInfo::clickLeft(tribool down, bool previousState)
{//FIXME: castleInt should be present - may be NULL if no castle window opened
if(previousState && (!down) && LOCPLINT->castleInt)
LOCPLINT->castleInt->builds->enterDwelling(level);
{
if(previousState && (!down))
{
int offset = LOCPLINT->castleInt? (-87) : 0;
GH.pushInt(new CRecruitmentWindow(town, level, town,
boost::bind(&CCallback::recruitCreatures, LOCPLINT->cb, town, _1, _2, level), offset));
}
}
int CCreaInfo::AddToString(std::string from, std::string & to, int numb)
@ -1090,88 +1129,98 @@ int CCreaInfo::AddToString(std::string from, std::string & to, int numb)
return numb;
}
std::string CCreaInfo::genGrowthText()
{
int summ=0;
std::string descr=CGI->generaltexth->allTexts[589];//Growth of creature is number
boost::algorithm::replace_first(descr,"%s", creature->nameSing);
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(town->creatureGrowth(level)));
descr +="\n"+CGI->generaltexth->allTexts[590];
summ = creature->growth;
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(summ));
if ( level>=0 && level<CREATURES_PER_TOWN)
{
if ( vstd::contains(town->builtBuildings, Buildings::CASTLE))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::CASTLE]->Name()+" %+d",descr,summ);
else if ( vstd::contains(town->builtBuildings, Buildings::CITADEL))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::CITADEL]->Name()+" %+d",descr,summ/2);
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, //double growth or plague
summ * creature->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100);
summ+=AddToString(CGI->generaltexth->artifNames[133] + " %+d",descr,
summ * town->valOfGlobalBonuses
(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion
if(town->town->hordeLvl[0]==level)//horde, x to summ
if( vstd::contains(town->builtBuildings, Buildings::HORDE_1) || vstd::contains(town->builtBuildings, Buildings::HORDE_1_UPGR))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::HORDE_1]->Name()+" %+d",descr,
creature->hordeGrowth);
if(town->town->hordeLvl[1]==level)//horde, x to summ
if( vstd::contains(town->builtBuildings, Buildings::HORDE_2) || vstd::contains(town->builtBuildings, Buildings::HORDE_2_UPGR))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::HORDE_2]->Name()+" %+d",descr,
creature->hordeGrowth);
int cnt = 0;
std::vector< const CGDwelling * > myDwellings = LOCPLINT->cb->getMyDwellings();
for (std::vector<const CGDwelling*>::const_iterator it = myDwellings.begin(); it != myDwellings.end(); ++it)
if (CGI->creh->creatures[town->town->basicCreatures[level]]->idNumber == (*it)->creatures[0].second[0])
cnt++;//external dwellings count to summ
summ+=AddToString(CGI->generaltexth->allTexts[591],descr,cnt);
boost::shared_ptr<BonusList> bl;
const CGHeroInstance *hero = town->garrisonHero;
if (hero)
{
bl = hero->getAllBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level)
&& Selector::sourceType(Bonus::ARTIFACT), 0, hero);
}
hero = town->visitingHero;
if (hero)
{
boost::shared_ptr<BonusList> blAppend = hero->getAllBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level)
&& Selector::sourceType(Bonus::ARTIFACT), 0, hero);
if (town->garrisonHero)
bl->insert(bl->size(), blAppend->begin(), blAppend->end());
else
bl = blAppend;
}
if (bl->size())
summ+=AddToString (CGI->arth->artifacts[bl->front()->sid]->Name()+" %+d", descr, bl->totalValue());
//TODO: player bonuses
if(vstd::contains(town->builtBuildings, Buildings::GRAIL)) //grail - +50% to ALL growth
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::GRAIL]->Name()+" %+d",descr,summ/2);
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, creature->valOfBonuses(Bonus::CREATURE_GROWTH));
}
return descr;
}
void CCreaInfo::clickRight(tribool down, bool previousState)
{
if(down)
{
int summ=0;
std::string descr=CGI->generaltexth->allTexts[589];//Growth of creature is number
boost::algorithm::replace_first(descr,"%s", creature->nameSing);
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(town->creatureGrowth(level)));
descr +="\n"+CGI->generaltexth->allTexts[590];
summ = creature->growth;
boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(summ));
if ( level>=0 && level<CREATURES_PER_TOWN)
if (showAvailable)
GH.pushInt(new CDwellingInfoBox(screen->w/2, screen->h/2, town, level));
else
{
if ( vstd::contains(town->builtBuildings, Buildings::CASTLE))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::CASTLE]->Name()+" %+d",descr,summ);
else if ( vstd::contains(town->builtBuildings, Buildings::CITADEL))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::CITADEL]->Name()+" %+d",descr,summ/2);
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, //double growth or plague
summ * creature->valOfBonuses(Bonus::CREATURE_GROWTH_PERCENT)/100);
summ+=AddToString(CGI->generaltexth->artifNames[133] + " %+d",descr,
summ * town->valOfGlobalBonuses
(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion
if(town->town->hordeLvl[0]==level)//horde, x to summ
if( vstd::contains(town->builtBuildings, Buildings::HORDE_1) || vstd::contains(town->builtBuildings, Buildings::HORDE_1_UPGR))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::HORDE_1]->Name()+" %+d",descr,
creature->hordeGrowth);
if(town->town->hordeLvl[1]==level)//horde, x to summ
if( vstd::contains(town->builtBuildings, Buildings::HORDE_2) || vstd::contains(town->builtBuildings, Buildings::HORDE_2_UPGR))
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::HORDE_2]->Name()+" %+d",descr,
creature->hordeGrowth);
int cnt = 0;
std::vector< const CGDwelling * > myDwellings = LOCPLINT->cb->getMyDwellings();
for (std::vector<const CGDwelling*>::const_iterator it = myDwellings.begin(); it != myDwellings.end(); ++it)
if (CGI->creh->creatures[town->town->basicCreatures[level]]->idNumber == (*it)->creatures[0].second[0])
cnt++;//external dwellings count to summ
summ+=AddToString(CGI->generaltexth->allTexts[591],descr,cnt);
boost::shared_ptr<BonusList> bl;
const CGHeroInstance *hero = town->garrisonHero;
if (hero)
{
bl = hero->getAllBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level)
&& Selector::sourceType(Bonus::ARTIFACT), 0, hero);
}
hero = town->visitingHero;
if (hero)
{
boost::shared_ptr<BonusList> blAppend = hero->getAllBonuses(Selector::type(Bonus::CREATURE_GROWTH) && Selector::subtype(level)
&& Selector::sourceType(Bonus::ARTIFACT), 0, hero);
if (town->garrisonHero)
bl->insert(bl->size(), blAppend->begin(), blAppend->end());
else
bl = blAppend;
}
if (bl->size())
summ+=AddToString (CGI->arth->artifacts[bl->front()->sid]->Name()+" %+d", descr, bl->totalValue());
//TODO: player bonuses
if(vstd::contains(town->builtBuildings, Buildings::GRAIL)) //grail - +50% to ALL growth
summ+=AddToString(CGI->buildh->buildings[town->subID][Buildings::GRAIL]->Name()+" %+d",descr,summ/2);
summ+=AddToString(CGI->generaltexth->allTexts[63] + " %+d",descr, creature->valOfBonuses(Bonus::CREATURE_GROWTH));
std::string descr = genGrowthText();
CInfoPopup *mess = new CInfoPopup();//creating popup
mess->free = true;
mess->bitmap = CMessage::drawBoxTextBitmapSub
(LOCPLINT->playerID, descr,graphics->bigImgs[creature->idNumber],"");
mess->pos.x = screen->w/2 - mess->bitmap->w/2;
mess->pos.y = screen->h/2 - mess->bitmap->h/2;
GH.pushInt(mess);
}
CInfoPopup *mess = new CInfoPopup();//creating popup
mess->free = true;
mess->bitmap = CMessage::drawBoxTextBitmapSub
(LOCPLINT->playerID, descr,graphics->bigImgs[creature->idNumber],"");
mess->pos.x = screen->w/2 - mess->bitmap->w/2;
mess->pos.y = screen->h/2 - mess->bitmap->h/2;
GH.pushInt(mess);
}
}

View File

@ -161,15 +161,18 @@ class CCreaInfo : public CIntObject
const CGTownInstance * town;
const CCreature *creature;
int level;
bool showAvailable;
CAnimImage *picture;
CLabel * label;
int AddToString(std::string from, std::string & to, int numb);
std::string genGrowthText();
public:
CCreaInfo(int posX, int posY, const CGTownInstance *Town, int Level);
CCreaInfo(Point position, const CGTownInstance *Town, int Level, bool compact=false, bool showAvailable=false);
void update();
void hover(bool on);
void clickLeft(tribool down, bool previousState);
void clickRight(tribool down, bool previousState);

View File

@ -283,6 +283,17 @@ struct Rect : public SDL_Rect
return Rect();
}
}
Rect operator|(const Rect &p) const //union of two rects
{
Rect ret;
ret.x = std::min(p.x, this->x);
ret.y = std::min(p.y, this->y);
int x2 = std::max(p.x+p.w, this->x+this->w);
int y2 = std::max(p.y+p.h, this->y+this->h);
ret.w = x2 -ret.x;
ret.h = y2 -ret.y;
return ret;
}
};
/// Defines a show method

View File

@ -4513,6 +4513,16 @@ CGarrisonWindow::CGarrisonWindow( const CArmedInstance *up, const CGHeroInstance
garr->addSplitBtn(split);
}
quit = new AdventureMapButton(CGI->generaltexth->tcommands[8],"",boost::bind(&CGarrisonWindow::close,this),399,314,"IOK6432.DEF",SDLK_RETURN);
std::string titleText;
if (garr->armedObjs[1]->tempOwner == garr->armedObjs[0]->tempOwner)
titleText = CGI->generaltexth->allTexts[709];
else
{
titleText = CGI->generaltexth->allTexts[35];
boost::algorithm::replace_first(titleText, "%s", garr->armedObjs[0]->Slots().begin()->second->type->namePl);
}
title = new CLabel(275, 30, FONT_BIG, CENTER, tytulowy, titleText);
}
CGarrisonWindow::~CGarrisonWindow()
@ -4523,18 +4533,8 @@ void CGarrisonWindow::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
std::string title;
if (garr->armedObjs[1]->tempOwner == garr->armedObjs[0]->tempOwner)
title = CGI->generaltexth->allTexts[709];
else
{
title = CGI->generaltexth->allTexts[35];
boost::algorithm::replace_first(title, "%s", garr->armedObjs[0]->Slots().begin()->second->type->namePl);
}
blitAtLoc(graphics->flags->ourImages[garr->armedObjs[1]->getOwner()].bitmap,28,124,to);
blitAtLoc(graphics->portraitLarge[static_cast<const CGHeroInstance*>(garr->armedObjs[1])->portrait],29,222,to);
printAtMiddleLoc(title,275,30,FONT_BIG,tytulowy,to);
}
IShowActivable::IShowActivable()
@ -5143,7 +5143,7 @@ void CArtifactsOfHero::setHero(const CGHeroInstance * hero)
void CArtifactsOfHero::dispose()
{
//delNull(curHero);
unmarkSlots(false);
//unmarkSlots(false);
CCS->curh->dragAndDropCursor(NULL);
}

View File

@ -1072,6 +1072,7 @@ class CGarrisonWindow : public CWindowWithGarrison
{
public:
CPicture *bg; //background surface
CLabel *title;
AdventureMapButton *quit;
void close();

View File

@ -60,14 +60,23 @@ std::string readString(const unsigned char * bufor, int &i)
return ret;
}
unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType type, int * length)
void CLodHandler::convertName(std::string &filename, std::string *extension)
{
std::string fname = defName;
std::transform(fname.begin(), fname.end(), fname.begin(), (int(*)(int))toupper);
int dotPos = fname.find_last_of('.');
if ( dotPos != -1 )
fname.erase(dotPos);
std::transform(filename.begin(), filename.end(), filename.begin(), toupper);
size_t dotPos = filename.find_last_of("/.");
if ( dotPos != std::string::npos && filename[dotPos] == '.')
{
if (extension)
*extension = filename.substr(dotPos);
filename.erase(dotPos);
}
}
unsigned char * CLodHandler::giveFile(std::string fname, LodFileType type, int * length)
{
convertName(fname);
boost::unordered_set<Entry>::const_iterator en_it = entries.find(Entry(fname, type));
if(en_it == entries.end()) //nothing's been found
@ -127,15 +136,20 @@ unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType typ
return NULL;
}
bool CLodHandler::haveFile(const std::string name, LodFileType type)
std::string CLodHandler::getFileName(std::string lodFile, LodFileType type)
{
std::string fname = name;
std::transform(fname.begin(), fname.end(), fname.begin(), (int(*)(int))toupper);
int dotPos = fname.find_last_of('.');
if ( dotPos != -1 )
fname.erase(dotPos);
return vstd::contains(entries, Entry(fname, type));
convertName(lodFile);
boost::unordered_set<Entry>::const_iterator it = entries.find(Entry(lodFile, type));
if (it != entries.end())
return it->realName;
return "";
}
bool CLodHandler::haveFile(std::string name, LodFileType type)
{
convertName(name);
return vstd::contains(entries, Entry(name, type));
}
DLL_EXPORT int CLodHandler::infs2(unsigned char * in, int size, int realSize, unsigned char *& out, int wBits)
@ -219,20 +233,12 @@ void CLodHandler::extractFile(const std::string FName, const std::string name)
}
}
void CLodHandler::initEntry(Entry &e, const std::string name)
void CLodHandler::initEntry(Entry &e, std::string name)
{
e.name = name;
//file names stored in upper case without extension
std::transform(e.name.begin(), e.name.end(), e.name.begin(), toupper);
std::string ext;
size_t dotPos = e.name.find_last_of('.');
if ( dotPos < e.name.size() )
{
ext = e.name.substr(dotPos);
e.name.erase(dotPos);
}
convertName(name, &ext);
e.name = name;
std::map<std::string, LodFileType>::iterator it = extMap.find(ext);
if (it == extMap.end())
e.type = FILE_OTHER;
@ -254,6 +260,7 @@ void CLodHandler::init(const std::string lodFile, const std::string dirName)
EXT(".JPG", FILE_GRAPHICS);
EXT(".PCX", FILE_GRAPHICS);
EXT(".PNG", FILE_GRAPHICS);
EXT(".TGA", FILE_GRAPHICS);
#undef EXT
myDir = dirName;
@ -328,7 +335,7 @@ void CLodHandler::init(const std::string lodFile, const std::string dirName)
tlog1<<"Warning: No "+dirName+"/ folder!"<<std::endl;
}
}
std::string CLodHandler::getTextFile(const std::string name, LodFileType type)
std::string CLodHandler::getTextFile(std::string name, LodFileType type)
{
int length=-1;
unsigned char* data = giveFile(name, type, &length);

View File

@ -103,16 +103,18 @@ class DLL_EXPORT CLodHandler
int infs2(unsigned char * in, int size, int realSize, unsigned char*& out, int wBits=15); //zlib fast handler
public:
//convert string to upper case and remove extension. If extension!=NULL -> it will be copied here (including dot)
void convertName(std::string &filename, std::string *extension=NULL);
boost::unordered_set<Entry> entries;
CLodHandler();
~CLodHandler();
void init(const std::string lodFile, const std::string dirName);
unsigned char * giveFile(const std::string defName, LodFileType type=FILE_ANY, int * length=NULL); //returns pointer to the decompressed data - it must be deleted when no longer needed!
bool haveFile(const std::string name, LodFileType type=FILE_ANY);//check if file is present in lod
std::string getTextFile(const std::string name, LodFileType type=FILE_TEXT); //extracts one file
std::string getFileName(std::string lodFile, LodFileType type=FILE_ANY);
unsigned char * giveFile(std::string defName, LodFileType type=FILE_ANY, int * length=NULL); //returns pointer to the decompressed data - it must be deleted when no longer needed!
bool haveFile(std::string name, LodFileType type=FILE_ANY);//check if file is present in lod
std::string getTextFile(std::string name, LodFileType type=FILE_TEXT); //extracts one file
void extractFile(const std::string FName, const std::string name); //extracts a specific file
static unsigned char * getUnpackedFile(const std::string & path, int * sizeOut); //loads given file, decompresses and returns

View File

@ -1101,10 +1101,17 @@ int CPlayerSpecificInfoCallback::howManyHeroes(bool includeGarrisoned) const
return getHeroCount(player,includeGarrisoned);
}
const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId) const
const CGHeroInstance* CPlayerSpecificInfoCallback::getHeroBySerial(int serialId, bool includeGarrisoned) const
{
const PlayerState *p = getPlayer(player);
ERROR_RET_VAL_IF(!p, "No player info", NULL);
if (!includeGarrisoned)
{
for(unsigned int i = 0; i < p->heroes.size() && i<=serialId; i++)
if(p->heroes[i]->inTownGarrison)
serialId++;
}
ERROR_RET_VAL_IF(serialId < 0 || serialId >= p->heroes.size(), "No player info", NULL);
return p->heroes[serialId];
}

View File

@ -213,7 +213,7 @@ public:
std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
int getHeroSerial(const CGHeroInstance * hero)const;
const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns)
const CGHeroInstance* getHeroBySerial(int serialId) const; // serial id is [0, number of heroes)
const CGHeroInstance* getHeroBySerial(int serialId, bool includeGarrisoned=true) const; // serial id is [0, number of heroes)
std::vector <const CGHeroInstance *> getHeroesInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
std::vector <const CGDwelling *> getMyDwellings() const; //returns all dwellings that belong to player
std::vector <const CGObjectInstance * > getMyObjects() const; //returns all objects flagged by belonging player

View File

@ -4825,7 +4825,7 @@ bool CGameHandler::addToSlot(const StackLocation &sl, const CCreature *c, TQuant
void CGameHandler::tryJoiningArmy(const CArmedInstance *src, const CArmedInstance *dst, bool removeObjWhenFinished, bool allowMerging)
{
if(!dst->canBeMergedWith(*src, allowMerging))
if(!src->canBeMergedWith(*dst, allowMerging))
{
if (allowMerging) //do that, add all matching creatures.
{