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

- removed usage of Graphics in several places (Components and hero window).

minor:
- fixed several deprecation warnings in video player
- config file may have multiple upgrades for creatures
This commit is contained in:
Ivan Savenko 2012-05-13 15:04:21 +00:00
parent 46f48f0676
commit 9efe05c90b
19 changed files with 661 additions and 668 deletions

View File

@ -316,38 +316,35 @@ void CBattleOptionsWindow::bExitf()
CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect & pos, CBattleInterface * _owner)
: owner(_owner)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
this->pos = pos;
background = BitmapHandler::loadBitmap("CPRESULT.BMP", true);
graphics->blueToPlayersAdv(background, owner->curInt->playerID);
SDL_Surface * pom = SDL_ConvertSurface(background, screen->format, screen->flags);
SDL_FreeSurface(background);
background = pom;
exit = new CAdventureMapButton (std::string(), std::string(), boost::bind(&CBattleResultWindow::bExitf,this), 384 + pos.x, 505 + pos.y, "iok6432.def", SDLK_RETURN);
CPicture * bg = new CPicture("CPRESULT");
bg->colorize(owner->curInt->playerID);
exit = new CAdventureMapButton ("", "", boost::bind(&CBattleResultWindow::bExitf,this), 384, 505, "iok6432.def", SDLK_RETURN);
exit->borderColor = Colors::MetallicGold;
exit->borderEnabled = true;
if(br.winner==0) //attacker won
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 59, 124, FONT_SMALL, Colors::Cornsilk, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 408, 124, FONT_SMALL, Colors::Cornsilk, background);
new CLabel( 59, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[410]);
new CLabel(408, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[411]);
}
else //if(br.winner==1)
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[411], 59, 124, FONT_SMALL, Colors::Cornsilk, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[410], 412, 124, FONT_SMALL, Colors::Cornsilk, background);
new CLabel( 59, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[411]);
new CLabel(412, 124, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[410]);
}
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[407], 232, 302, FONT_BIG, Colors::Jasmine, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[408], 232, 332, FONT_BIG, Colors::Cornsilk, background);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[409], 237, 428, FONT_BIG, Colors::Cornsilk, background);
new CLabel(232, 302, FONT_BIG, CENTER, Colors::Jasmine, CGI->generaltexth->allTexts[407]);
new CLabel(232, 332, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[408]);
new CLabel(232, 428, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[409]);
std::string attackerName, defenderName;
if(owner->attackingHeroInstance) //a hero attacked
{
SDL_Rect temp_rect = genRect(64, 58, 21, 38);
SDL_BlitSurface(graphics->portraitLarge[owner->attackingHeroInstance->portrait], NULL, background, &temp_rect);
new CAnimImage("PortraitsLarge", owner->attackingHeroInstance->portrait, 0, 21, 38);
//setting attackerName
attackerName = owner->attackingHeroInstance->name;
}
@ -363,15 +360,13 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
bestMonsterID = it->second->type->idNumber;
}
}
SDL_Rect temp_rect = genRect(64, 58, 21, 38);
SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &temp_rect);
new CAnimImage("TWCRPORT", bestMonsterID, 0, 21, 38);
//setting attackerName
attackerName = CGI->creh->creatures[bestMonsterID]->namePl;
}
if(owner->defendingHeroInstance) //a hero defended
{
SDL_Rect temp_rect = genRect(64, 58, 392, 38);
SDL_BlitSurface(graphics->portraitLarge[owner->defendingHeroInstance->portrait], NULL, background, &temp_rect);
new CAnimImage("PortraitsLarge", owner->defendingHeroInstance->portrait, 0, 392, 38);
//setting defenderName
defenderName = owner->defendingHeroInstance->name;
}
@ -387,21 +382,22 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
bestMonsterID = it->second->type->idNumber;
}
}
SDL_Rect temp_rect = genRect(64, 58, 392, 38);
SDL_BlitSurface(graphics->bigImgs[bestMonsterID], NULL, background, &temp_rect);
new CAnimImage("TWCRPORT", bestMonsterID, 0, 392, 38);
//setting defenderName
defenderName = CGI->creh->creatures[bestMonsterID]->namePl;
}
//printing attacker and defender's names
CSDL_Ext::printAt(attackerName, 89, 37, FONT_SMALL, Colors::Cornsilk, background);
CSDL_Ext::printTo(defenderName, 381, 53, FONT_SMALL, Colors::Cornsilk, background);
new CLabel( 89, 37, FONT_SMALL, TOPLEFT, Colors::Cornsilk, attackerName);
new CLabel( 381, 53, FONT_SMALL, BOTTOMRIGHT, Colors::Cornsilk, defenderName);
//printing casualities
for(int step = 0; step < 2; ++step)
{
if(br.casualties[step].size()==0)
{
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[523], 235, 360 + 97*step, FONT_SMALL, Colors::Cornsilk, background);
new CLabel( 235, 360 + 97*step, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[523]);
}
else
{
@ -409,10 +405,10 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
int yPos = 344 + step*97;
for(std::map<ui32,si32>::const_iterator it=br.casualties[step].begin(); it!=br.casualties[step].end(); ++it)
{
blitAt(graphics->smallImgs[it->first], xPos, yPos, background);
new CAnimImage("CPRSMALL", it->first+2, 0, xPos, yPos);
std::ostringstream amount;
amount<<it->second;
CSDL_Ext::printAtMiddle(amount.str(), xPos+16, yPos + 42, FONT_SMALL, Colors::Cornsilk, background);
new CLabel( xPos+16, yPos + 42, FONT_SMALL, CENTER, Colors::Cornsilk, amount.str());
xPos += 42;
}
}
@ -440,7 +436,8 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
boost::algorithm::replace_first(str,"%s",ourHero->name);
boost::algorithm::replace_first(str,"%d",boost::lexical_cast<std::string>(br.exp[weAreAttacker?0:1]));
}
CSDL_Ext::printAtMiddleWB(str, 235, 235, FONT_SMALL, 55, Colors::Cornsilk, background);
new CTextBox(str, Rect(69, 203, 330, 68), 0, FONT_SMALL, CENTER, Colors::Cornsilk);
}
else // we lose
{
@ -450,21 +447,21 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
{
CCS->musich->playMusic(musicBase::loseCombat);
CCS->videoh->open(VIDEO_LOSE_BATTLE_START);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[311], 235, 235, FONT_SMALL, Colors::Cornsilk, background);
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[311]);
break;
}
case 1: //flee
{
CCS->musich->playMusic(musicBase::retreatBattle);
CCS->videoh->open(VIDEO_RETREAT_START);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[310], 235, 235, FONT_SMALL, Colors::Cornsilk, background);
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[310]);
break;
}
case 2: //surrender
{
CCS->musich->playMusic(musicBase::surrenderBattle);
CCS->videoh->open(VIDEO_SURRENDER);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[309], 235, 220, FONT_SMALL, Colors::Cornsilk, background);
new CLabel(235, 235, FONT_SMALL, CENTER, Colors::Cornsilk, CGI->generaltexth->allTexts[309]);
break;
}
}
@ -473,7 +470,6 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
CBattleResultWindow::~CBattleResultWindow()
{
SDL_FreeSurface(background);
}
void CBattleResultWindow::activate()
@ -489,13 +485,13 @@ void CBattleResultWindow::deactivate()
void CBattleResultWindow::show(SDL_Surface * to)
{
CIntObject::show(to);
//evaluating to
if(!to)
to = screen;
CCS->videoh->update(107, 70, background, false, true);
CCS->videoh->update(pos.x + 107, pos.y + 70, screen, false, true);
SDL_BlitSurface(background, NULL, to, &pos);
exit->showAll(to);
}
@ -759,4 +755,4 @@ CStackQueue::StackBox::~StackBox()
void CStackQueue::StackBox::hover( bool on )
{
}
}

View File

@ -88,7 +88,6 @@ public:
class CBattleResultWindow : public CIntObject
{
private:
SDL_Surface *background;
CAdventureMapButton *exit;
CBattleInterface *owner;
public:

View File

@ -837,7 +837,9 @@ void CInfoBar::showAll(SDL_Surface * to)
{
CPicture bg("ADSTATOT.bmp");
bg.convertToScreenBPP();
blitAt(graphics->flags->ourImages[enemyTurnInfo.color].bitmap, 20, 51, bg);
CAnimImage ai("CREST58", enemyTurnInfo.color, 0, 20, 51);
ai.showAll(&*bg);
int hourglassFrame = enemyTurnInfo.progress * hourglass->ourImages.size();
static int sandFrame = 0;
vstd::amin(hourglassFrame, hourglass->ourImages.size()-1);
@ -933,7 +935,10 @@ void CInfoBar::showComp(const CComponent * comp, int time/*=5000*/)
SDL_Surface * b = BitmapHandler::loadBitmap("ADSTATOT.bmp");
blitAt(b,pos.x+8,pos.y+11);
blitAt(comp->getImg(),pos.x+52,pos.y+54);
CComponent* tempComp = (CComponent*)comp; //evil. TODO: remove need to move component
tempComp->moveTo(Point(pos.x+52, pos.y+54));
tempComp->showAll(screen);
printAtMiddle(comp->subtitle,pos.x+91,pos.y+158,FONT_SMALL,Colors::Cornsilk);
printAtMiddleWB(comp->description,pos.x+94,pos.y+31,FONT_SMALL,26,Colors::Cornsilk);
SDL_FreeSurface(b);

View File

@ -123,9 +123,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
const CBuilding *bld = CGI->buildh->buildings[str->townID].find(bid)->second;
if (bid < EBuilding::DWELL_FIRST)
{
std::vector<CComponent*> comps(1,
new CComponent(CComponent::building, bld->tid, bld->bid,
LOCPLINT->castleInt->bicons->ourImages[bld->bid].bitmap, false));
std::vector<CComponent*> comps(1, new CComponent(CComponent::building, bld->tid, bld->bid));
CRClickPopup::createAndPush(bld->Description(), comps);
}
@ -271,7 +269,7 @@ CDwellingInfoBox::CDwellingInfoBox(int centerX, int centerY, const CGTownInstanc
{
if(creature->cost[i])
{
resPicture.push_back(new CPicture(graphics->resources32->ourImages[i].bitmap, 0, 0, false));
resPicture.push_back(new CAnimImage("RESOURCE", i, 0, 0, 0));
resAmount.push_back(new CLabel(0,0, FONT_SMALL, CENTER, Colors::Cornsilk, boost::lexical_cast<std::string>(creature->cost[i])));
}
}
@ -303,12 +301,12 @@ void CHeroGSlot::hover (bool on)
std::string temp;
if(hero)
{
if(highlight)//view NNN
if(selection)//view NNN
{
temp = CGI->generaltexth->tcommands[4];
boost::algorithm::replace_first(temp,"%s",hero->name);
}
else if(other->hero && other->highlight)//exchange
else if(other->hero && other->selection)//exchange
{
temp = CGI->generaltexth->tcommands[7];
boost::algorithm::replace_first(temp,"%s",hero->name);
@ -330,7 +328,7 @@ void CHeroGSlot::hover (bool on)
}
else //we are empty slot
{
if(other->highlight && other->hero) //move NNNN
if(other->selection && other->hero) //move NNNN
{
temp = CGI->generaltexth->tcommands[6];
boost::algorithm::replace_first(temp,"%s",other->hero->name);
@ -352,12 +350,12 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
owner->garr->splitting = false;
owner->garr->highlighted = NULL;
if(hero && highlight)
if(hero && selection)
{
setHighlight(false);
LOCPLINT->openHeroWindow(hero);
}
else if(other->hero && other->highlight)
else if(other->hero && other->selection)
{
bool allow = true;
if(upg) //moving hero out of town - check if it is allowed
@ -394,20 +392,10 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
void CHeroGSlot::deactivate()
{
highlight = false;
delChildNUll(selection, true);
CIntObject::deactivate();
}
void CHeroGSlot::showAll(SDL_Surface * to)
{
if(hero) //there is hero
blitAt(graphics->portraitLarge[hero->portrait],pos,to);
else if(!upg && owner->showEmpty) //up garrison
blitAt(graphics->flags->ourImages[LOCPLINT->castleInt->town->getOwner()].bitmap,pos,to);
if(highlight)
blitAt(graphics->bigImgs[-1],pos,to);
}
CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner)
{
used = LCLICK | HOVER;
@ -416,9 +404,10 @@ CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSl
pos.y += y;
pos.w = 58;
pos.h = 64;
hero = h;
upg = updown;
highlight = false;
selection = nullptr;
image = nullptr;
set(h);
}
CHeroGSlot::~CHeroGSlot()
@ -427,7 +416,17 @@ CHeroGSlot::~CHeroGSlot()
void CHeroGSlot::setHighlight( bool on )
{
highlight = on;
if (active && selection)
selection->deactivate();
OBJ_CONSTRUCTION_CAPTURING_ALL;
delChildNUll(selection, true);
if (on)
selection = new CAnimImage("TWCRPORT", 1, 0);
if (active && selection)
selection->activate();
if(owner->garrisonedHero->hero && owner->visitingHero->hero) //two heroes in town
{
for(size_t i = 0; i<owner->garr->splitButtons.size(); i++) //splitting enabled when slot higlighted
@ -435,6 +434,26 @@ void CHeroGSlot::setHighlight( bool on )
}
}
void CHeroGSlot::set(const CGHeroInstance *newHero)
{
if (active && image)
image->deactivate();
OBJ_CONSTRUCTION_CAPTURING_ALL;
if (image)
delChild(image);
hero = newHero;
if (newHero)
image = new CAnimImage("PortraitsLarge", newHero->portrait, 0, 0, 0);
else if(!upg && owner->showEmpty) //up garrison
image = new CAnimImage("CREST58", LOCPLINT->castleInt->town->getOwner(), 0, 0, 0);
else
image = NULL;
if (active && image)
image->activate();
}
template <class ptr>
class SORTHELP
{
@ -797,9 +816,7 @@ void CCastleBuildings::enterBlacksmith(int ArtifactID)
void CCastleBuildings::enterBuilding(int building)
{
std::vector<CComponent*> comps(1,
new CComponent(CComponent::building, town->subID,building,
LOCPLINT->castleInt->bicons->ourImages[building].bitmap, false));
std::vector<CComponent*> comps(1, new CComponent(CComponent::building, town->subID, building));
LOCPLINT->showInfoDialog(
CGI->buildh->buildings[town->subID].find(building)->second->Description(),comps);
@ -836,9 +853,7 @@ void CCastleBuildings::enterDwelling(int level)
void CCastleBuildings::enterFountain(int building)
{
std::vector<CComponent*> comps(1,
new CComponent(CComponent::building,town->subID,building,
LOCPLINT->castleInt->bicons->ourImages[building].bitmap,false));
std::vector<CComponent*> comps(1, new CComponent(CComponent::building,town->subID,building));
std::string descr = CGI->buildh->buildings[town->subID].find(building)->second->Description();
if ( building == 21)//we need description for mystic pond as well
@ -918,6 +933,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos):
town(Town)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
LOCPLINT->castleInt = this;
used |= KEYBOARD;
builds = new CCastleBuildings(town);
@ -953,7 +969,6 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos):
vstd::amax(townlist->from, 0);
vstd::amin(townlist->from, LOCPLINT->towns.size() - townlist->SIZE);
LOCPLINT->castleInt = this;
recreateIcons();
CCS->musich->playMusic(CCS->musich->townMusics[town->subID], -1);
@ -1277,13 +1292,13 @@ HeroSlots::HeroSlots(const CGTownInstance * Town, Point garrPos, Point visitPos,
void HeroSlots::update()
{
garrisonedHero->hero = town->garrisonHero;
visitingHero->hero = town->visitingHero;
garrisonedHero->set(town->garrisonHero);
visitingHero->set(town->visitingHero);
}
void HeroSlots::splitClicked()
{
if(!!town->visitingHero && town->garrisonHero && (visitingHero->highlight || garrisonedHero->highlight))
if(!!town->visitingHero && town->garrisonHero && (visitingHero->selection || garrisonedHero->selection))
{
LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id);
}
@ -1468,7 +1483,7 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
{
if(building->resources[i])
{
resPicture.push_back(new CPicture(graphics->resources32->ourImages[i].bitmap, 0, 0, false));
resPicture.push_back(new CAnimImage("RESOURCE", i));
resAmount.push_back(new CLabel(0,0, FONT_SMALL, CENTER, Colors::Cornsilk,
boost::lexical_cast<std::string>(building->resources[i])));
}
@ -1836,7 +1851,7 @@ CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, i
else
buy->block(true);
gold = new CPicture(graphics->resources32->ourImages[6].bitmap,148,244, false);
new CAnimImage("RESOURCE", 6, 0, 148, 244);
}
void CBlacksmithDialog::close()

View File

@ -66,7 +66,7 @@ class CDwellingInfoBox : public CIntObject
CLabel *available;
CLabel *costPerTroop;
std::vector<CPicture *> resPicture;
std::vector<CAnimImage *> resPicture;
std::vector<CLabel *> resAmount;
public:
CDwellingInfoBox(int centerX, int centerY, const CGTownInstance *Town, int level);
@ -81,14 +81,16 @@ public:
HeroSlots *owner;
const CGHeroInstance *hero;
int upg; //0 - up garrison, 1 - down garrison
bool highlight; //indicates id the slot is highlighted
CAnimImage *image;
CAnimImage *selection; //selection border. NULL if not selected
void setHighlight(bool on);
void set(const CGHeroInstance *newHero);
void hover (bool on);
void clickLeft(tribool down, bool previousState);
void deactivate();
void showAll(SDL_Surface * to);
CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner); //c-tor
~CHeroGSlot(); //d-tor
};
@ -282,7 +284,7 @@ class CBuildWindow: public CIntObject
CTextBox * buildingState;
CGStatusBar *statusBar;
std::vector<CPicture *> resPicture;
std::vector<CAnimImage *> resPicture;
std::vector<CLabel *> resAmount;
std::string getTextForState(int state);
@ -384,7 +386,6 @@ class CBlacksmithDialog : public CIntObject
CPicture *background;
CPicture *animBG;
CCreatureAnim * anim;
CPicture * gold;
CLabel * title;
CLabel * costText;
CLabel * costValue;

View File

@ -123,6 +123,7 @@ CCreatureWindow::CCreatureWindow(const CStackInstance &st, int Type, boost::func
void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *StackNode, const CGHeroInstance *HeroOwner)
{
creatureArtifact = NULL; //may be set later
artifactImage = NULL;
stack = Stack;
c = stack->type;
if(!StackNode)
@ -207,7 +208,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
luck = new MoraleLuckBox(false, genRect(42, 42, 387, 100));
luck->set(stack);
new CPicture(graphics->pskillsm->ourImages[4].bitmap, 387, 51, false); //exp icon - Print it always?
new CAnimImage("PSKIL42", 4, 0, 387, 51); //exp icon - Print it always?
if (type) //not in fort window
{
if (GameConstants::STACK_EXP)
@ -259,7 +260,7 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode *
if (GameConstants::STACK_ARTIFACT)
{
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT);
setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT));
if (type > BATTLE) //artifact buttons inactive in battle
{
//TODO: disable buttons if no artifact is equipped
@ -390,12 +391,6 @@ void CCreatureWindow::showAll(SDL_Surface * to)
BOOST_FOREACH(CBonusItem* b, bonusItems)
b->showAll (to);
if (GameConstants::STACK_ARTIFACT)
{
if (creatureArtifact)
blitAt(graphics->artDefs->ourImages[creatureArtifact->artType->id].bitmap, 466 + pos.x, 100 + pos.y, to);
}
}
void CCreatureWindow::show(SDL_Surface * to)
@ -411,10 +406,24 @@ void CCreatureWindow::sliderMoved(int newpos)
redraw();
}
void CCreatureWindow::setArt(const CArtifactInstance *creatureArtifact)
{
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT);
if (creatureArtifact)
{
if (artifactImage == NULL)
addChild(artifactImage = new CAnimImage("ARTIFACT", creatureArtifact->artType->id, 0, 466, 100), true);
else
artifactImage->setFrame(creatureArtifact->artType->id);
}
else
delChildNUll(artifactImage);
}
void CCreatureWindow::scrollArt(int dir)
{
//TODO: get next artifact
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT);
setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT));
}
void CCreatureWindow::passArtifactToHero()
@ -432,13 +441,11 @@ void CCreatureWindow::passArtifactToHero()
void CCreatureWindow::artifactRemoved (const ArtifactLocation &artLoc)
{
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); //TODO: select next from the list (for Commanders)
redraw();
setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT)); //TODO: select next from the list (for Commanders)
}
void CCreatureWindow::artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)
{
creatureArtifact = stack->getArt(ArtifactPosition::CREATURE_SLOT); //TODO: select next from the list (for Commanders)
redraw();
setArt(stack->getArt(ArtifactPosition::CREATURE_SLOT)); //TODO: select next from the list (for Commanders)
}
void CCreatureWindow::clickRight(tribool down, bool previousState)

View File

@ -62,6 +62,9 @@ public:
CAdventureMapButton *dismiss, *upgrade, *ok;
CAdventureMapButton * leftArtRoll, * rightArtRoll; //artifact selection
CAdventureMapButton * passArtToHero;
CAnimImage *artifactImage;
void setArt(const CArtifactInstance *creatureArtifact);
void artifactRemoved (const ArtifactLocation &artLoc);
void artifactMoved (const ArtifactLocation &artLoc, const ArtifactLocation &destLoc);

View File

@ -1,5 +1,6 @@
#include "StdInc.h"
#include "CAnimation.h"
#include "CAdvmapInterface.h"
#include "../CCallback.h"
#include "CGameInfo.h"
@ -69,38 +70,37 @@ void CHeroSwitcher::clickLeft(tribool down, bool previousState)
{
if(!down)
{
const CGHeroInstance * buf = LOCPLINT->getWHero(id);
if(!buf)
return;
GH.popIntTotally(getOwner());
const CGHeroInstance * buf = hero;
GH.popIntTotally(parent);
GH.pushInt(new CHeroWindow(buf));
}
}
CHeroWindow * CHeroSwitcher::getOwner()
CHeroSwitcher::CHeroSwitcher(Point _pos, const CGHeroInstance * _hero):
hero(_hero)
{
return dynamic_cast<CHeroWindow*>(parent);
}
CHeroSwitcher::CHeroSwitcher(int serial)
{
pos = Rect(612, 87 + serial * 54, 48, 32) + pos;
id = serial;
OBJ_CONSTRUCTION_CAPTURING_ALL;
pos += _pos;
used = LCLICK;
image = new CAnimImage("PortraitsSmall", hero->portrait);
pos.w = image->pos.w;
pos.h = image->pos.h;
}
CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
: heroWArt(this, hero)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
garr = NULL;
garr = nullptr;
curHero = hero;
player = LOCPLINT->playerID;//hero->tempOwner;
listSelection = nullptr;
background = new CPicture("HeroScr4.BMP");
background->colorizeAndConvert(player);
background->colorize(LOCPLINT->playerID);
pos = background->center();
new CAnimImage("CREST58", LOCPLINT->playerID, 0, 606, 8);
//artifs = new CArtifactsOfHero(pos.topLeft(), true);
ourBar = new CGStatusBar(7, 559, "ADROLLVR.bmp", 660); // new CStatusBar(pos.x+72, pos.y+567, "ADROLLVR.bmp", 660);
@ -116,15 +116,13 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
tacticsButton = new CHighlightableButton(0, 0, map_list_of(0,CGI->generaltexth->heroscrn[26])(3,CGI->generaltexth->heroscrn[25]), CGI->generaltexth->heroscrn[31], false, "hsbtns8.def", NULL, 539, 483, SDLK_b);
//right list of heroes
for(int g=0; g<8; ++g)
heroListMi.push_back(new CHeroSwitcher(g));
flags = CDefHandler::giveDefEss("CREST58.DEF");
for(int i=0; i < std::min(LOCPLINT->cb->howManyHeroes(false), 8); i++)
heroList.push_back(new CHeroSwitcher(Point(612, 87 + i * 54), LOCPLINT->cb->getHeroBySerial(i, false)));
//areas
portraitArea = new LRClickableAreaWText(Rect(18, 18, 58, 64));
portraitImage = new CAnimImage("PortraitsLarge", 0, 0, 19, 19);
for(int v=0; v<GameConstants::PRIMARY_SKILLS; ++v)
{
@ -135,6 +133,8 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
primSkillAreas.push_back(area);
}
specImage = new CAnimImage("UN44", 0, 0, 18, 180);
specArea = new LRClickableAreaWText(Rect(18, 180, 136, 42), CGI->generaltexth->heroscrn[27]);
expArea = new LRClickableAreaWText(Rect(18, 228, 136, 42), CGI->generaltexth->heroscrn[9]);
morale = new MoraleLuckBox(true, Rect(175,179,53,45));
@ -145,33 +145,22 @@ CHeroWindow::CHeroWindow(const CGHeroInstance *hero)
{
Rect r = Rect(i%2 == 0 ? 18 : 162, 276 + 48 * (i/2), 136, 42);
secSkillAreas.push_back(new LRClickableAreaWTextComp(r, CComponent::secskill));
secSkillImages.push_back(new CAnimImage("SECSKILL", 0, 0, r.x, r.y));
}
//////////////////////////////////////////////////////////////////////////???????????????
// pos.x += 65;
// pos.y += 8;
//
//primary skills & exp and mana
new CPicture(graphics->pskillsm->ourImages[0].bitmap, 32, 111, false);
new CPicture(graphics->pskillsm->ourImages[1].bitmap, 102, 111, false);
new CPicture(graphics->pskillsm->ourImages[2].bitmap, 172, 111, false);
new CPicture(graphics->pskillsm->ourImages[5].bitmap, 242, 111, false);
new CPicture(graphics->pskillsm->ourImages[4].bitmap, 20, 230, false);
new CPicture(graphics->pskillsm->ourImages[3].bitmap, 162, 230, false);
new CAnimImage("PSKIL42", 0, 0, 32, 111, false);
new CAnimImage("PSKIL42", 1, 0, 102, 111, false);
new CAnimImage("PSKIL42", 2, 0, 172, 111, false);
new CAnimImage("PSKIL42", 3, 0, 162, 230, false);
new CAnimImage("PSKIL42", 4, 0, 20, 230, false);
new CAnimImage("PSKIL42", 5, 0, 242, 111, false);
update(hero);
}
CHeroWindow::~CHeroWindow()
{
delete flags;
//SDL_FreeSurface(curBack);
//curBack = NULL;
curHero = NULL;
//artifs->dispose();
}
void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= false*/)
{
if(!hero) //something strange... no hero? it shouldn't happen
@ -181,9 +170,9 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
}
assert(hero == curHero);
//assert(hero->tempOwner == LOCPLINT->playerID || hero->tempOwner == NEUTRAL_PLAYER); //for now we won't show hero windows for non-our heroes
specArea->text = CGI->generaltexth->hTxts[curHero->subID].longBonus;
specImage->setFrame(curHero->subID);
tacticsButton->callback.clear();
tacticsButton->callback2.clear();
@ -191,6 +180,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
dismissButton->hoverTexts[0] = boost::str(boost::format(CGI->generaltexth->heroscrn[16]) % curHero->name % curHero->type->heroClass->name);
portraitArea->hoverText = boost::str(boost::format(CGI->generaltexth->allTexts[15]) % curHero->name % curHero->type->heroClass->name);
portraitArea->text = curHero->getBiography();
portraitImage->setFrame(curHero->portrait);
{
CAdventureMapButton * split = NULL;
@ -210,8 +200,12 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
arts->setHero(curHero);
artSets.push_back(arts);
}
}
int serial = LOCPLINT->cb->getHeroSerial(curHero, false);
delChildNUll(listSelection);
if (serial >= 0)
listSelection = new CPicture("HPSYYY", 612, 33 + serial * 54);
}
//primary skills support
for(size_t g=0; g<primSkillAreas.size(); ++g)
@ -228,6 +222,7 @@ void CHeroWindow::update(const CGHeroInstance * hero, bool redrawNeeded /*= fals
secSkillAreas[g]->bonusValue = level;
secSkillAreas[g]->text = CGI->generaltexth->skillInfoTexts[skill][level-1];
secSkillAreas[g]->hoverText = boost::str(boost::format(CGI->generaltexth->heroscrn[21]) % CGI->generaltexth->levels[level-1] % CGI->generaltexth->skillName[skill]);
secSkillImages[g]->setFrame(skill*3 + level + 2);
}
//printing experience - original format does not support ui64
@ -296,8 +291,6 @@ void CHeroWindow::questlog()
void CHeroWindow::showAll(SDL_Surface * to)
{
CIntObject::showAll(to);
//blitting portrait
blitAtLoc(graphics->portraitLarge[curHero->portrait], 19, 19, to);
//printing hero's name
printAtMiddleLoc(curHero->name, 190, 38, FONT_BIG, Colors::Jasmine, to);
@ -345,42 +338,14 @@ void CHeroWindow::showAll(SDL_Surface * to)
printAtMiddleLoc(primarySkill.str(), 53 + 70 * m, 166, FONT_SMALL, Colors::Cornsilk, to);
}
blitAtLoc(flags->ourImages[player].bitmap, 606, 8, to);
//hero list blitting
for(int slotPos=0, g=0; g<LOCPLINT->wanderingHeroes.size(); ++g)
{
const CGHeroInstance * cur = LOCPLINT->wanderingHeroes[g];
if (cur->inTownGarrison)
// Only display heroes that are not in garrison
continue;
blitAtLoc(graphics->portraitSmall[cur->portrait], 611, 87+slotPos*54, to);
//printing yellow border
if(cur->name == curHero->name)
{
for(int f=0; f<graphics->portraitSmall[cur->portrait]->w; ++f)
{
for(int h=0; h<graphics->portraitSmall[cur->portrait]->h; ++h)
if(f==0 || h==0 || f==graphics->portraitSmall[cur->portrait]->w-1 || h==graphics->portraitSmall[cur->portrait]->h-1)
CSDL_Ext::SDL_PutPixelWithoutRefresh(to, pos.x + 611+f, pos.y + 87+slotPos*54+h, 240, 220, 120);
}
}
slotPos ++;
}
//secondary skills
for(size_t v=0; v<std::min(secSkillAreas.size(), curHero->secSkills.size()); ++v)
{
blitAtLoc(graphics->abils44->ourImages[curHero->secSkills[v].first*3+3+curHero->secSkills[v].second-1].bitmap, v%2 ? 161 : 18, 276 + 48 * (v/2), to);
printAtLoc(CGI->generaltexth->levels[curHero->secSkills[v].second-1], v%2 ? 212 : 68, 280 + 48 * (v/2), FONT_SMALL, Colors::Cornsilk, to);
printAtLoc(CGI->generaltexth->skillName[curHero->secSkills[v].first], v%2 ? 212 : 68, 300 + 48 * (v/2), FONT_SMALL, Colors::Cornsilk, to);
}
//printing special ability
blitAtLoc(graphics->un44->ourImages[curHero->subID].bitmap, 18, 180, to);
printAtLoc(CGI->generaltexth->jktexts[5].substr(1, CGI->generaltexth->jktexts[5].size()-2), 69, 183, FONT_SMALL, Colors::Jasmine, to);
printAtLoc(CGI->generaltexth->hTxts[curHero->subID].bonusName, 69, 205, FONT_SMALL, Colors::Cornsilk, to);

View File

@ -29,13 +29,12 @@ class CArtifactsOfHero;
/// Button which switches hero selection
class CHeroSwitcher : public CIntObject
{
const CGHeroInstance * hero;
CAnimImage *image;
public:
int id;
CHeroWindow * getOwner();
virtual void clickLeft(tribool down, bool previousState);
CHeroSwitcher(int serial);
CHeroSwitcher(Point pos, const CGHeroInstance * hero);
};
//helper class for calculating values of hero bonuses without bonuses from picked up artifact
@ -51,45 +50,45 @@ public:
class CHeroWindow: public CWindowWithGarrison, public CWindowWithArtifacts
{
enum ELabel {};
std::map<ELabel, CLabel*> labels;
CPicture *background;
CGStatusBar * ourBar; //heroWindow's statusBar
//general graphics
CDefEssential *flags;
//buttons
//CAdventureMapButton * gar4button; //splitting
std::vector<CHeroSwitcher *> heroListMi; //new better list of heroes
std::vector<CHeroSwitcher *> heroList; //list of heroes
CPicture * listSelection; //selection border
//clickable areas
LRClickableAreaWText * portraitArea;
CAnimImage * portraitImage;
std::vector<LRClickableAreaWTextComp *> primSkillAreas;
LRClickableAreaWText * expArea;
LRClickableAreaWText * spellPointsArea;
LRClickableAreaWText * specArea;//speciality
CAnimImage *specImage;
MoraleLuckBox * morale, * luck;
std::vector<LRClickableAreaWTextComp *> secSkillAreas;
std::vector<CAnimImage *> secSkillImages;
CHeroWithMaybePickedArtifact heroWArt;
public:
const CGHeroInstance * curHero;
CAdventureMapButton * quitButton, * dismissButton, * questlogButton; //general
CHighlightableButton *tacticsButton; //garrison / formation handling;
CHighlightableButtonsGroup *formations;
int player;
public:
const CGHeroInstance * curHero;
CHeroWindow(const CGHeroInstance *hero); //c-tor
~CHeroWindow(); //d-tor
void update(const CGHeroInstance * hero, bool redrawNeeded = false); //sets main displayed hero
void showAll(SDL_Surface * to); //shows and activates adv. map interface
// void redrawCurBack(); //redraws curBAck from scratch
void quit(); //stops displaying hero window and disposes
void showAll(SDL_Surface * to);
void quit(); //stops displaying hero window and disposes
void dismissCurrent(); //dissmissed currently displayed hero (curHero)
void questlog(); //show quest log in hero window
void switchHero(); //changes displayed hero
void switchHero(); //changes displayed hero
//friends
friend void CArtPlace::clickLeft(tribool down, bool previousState);

View File

@ -24,11 +24,9 @@
*
*/
extern SDL_Surface * screen;
//extern SDL_Surface * screen;
using namespace NMessage;
const int COMPONENT_TO_SUBTITLE = 5;
const int COMPONENT_TO_SUBTITLE = 17;
const int BETWEEN_COMPS_ROWS = 10;
const int BEFORE_COMPONENTS = 30;
const int SIDE_MARGIN = 30;
@ -41,14 +39,38 @@ template <typename T, typename U> std::pair<T,U> max(const std::pair<T,U> &x, co
return ret;
}
namespace NMessage
//One image component + subtitles below it
class ComponentResolved : public CIntObject
{
std::vector<std::vector<SDL_Surface*> > * txt;
public:
CComponent *comp;
//blit component with image centered at this position
void showAll(SDL_Surface * to);
//ComponentResolved(); //c-tor
ComponentResolved(CComponent *Comp); //c-tor
~ComponentResolved(); //d-tor
};
// Full set of components for blitting on dialog box
struct ComponentsToBlit
{
std::vector< std::vector<ComponentResolved*> > comps;
int w, h;
void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret);
ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, SDL_Surface* _or); //c-tor
~ComponentsToBlit(); //d-tor
};
namespace
{
CDefHandler * ok, *cancel;
std::vector<std::vector<SDL_Surface*> > piecesOfBox; //in colors of all players
SDL_Surface * background = NULL;
}
void CMessage::init()
{
{
@ -72,14 +94,13 @@ void CMessage::init()
}
delete bluePieces;
}
NMessage::background = BitmapHandler::loadBitmap("DIBOXBCK.BMP");
background = BitmapHandler::loadBitmap("DIBOXBCK.BMP");
SDL_SetColorKey(background,SDL_SRCCOLORKEY,SDL_MapRGB(background->format,0,255,255));
}
ok = CDefHandler::giveDef("IOKAY.DEF");
cancel = CDefHandler::giveDef("ICANCEL.DEF");
}
void CMessage::dispose()
{
for (int i=0;i<GameConstants::PLAYER_LIMIT;i++)
@ -93,7 +114,8 @@ void CMessage::dispose()
delete ok;
delete cancel;
}
SDL_Surface * CMessage::drawBox1(int w, int h, int playerColor) //draws box for window
SDL_Surface * CMessage::drawDialogBox(int w, int h, int playerColor)
{
//prepare surface
SDL_Surface * ret = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, screen->format->BitsPerPixel, screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
@ -319,37 +341,7 @@ std::vector<std::vector<SDL_Surface*> > * CMessage::drawText(std::vector<std::st
} //ends for(int i=0; i<brtext->size();i++)
return txtg;
}
//CSimpleWindow * CMessage::genWindow(std::string text, int player, bool centerOnMouse, int Lmar, int Rmar, int Tmar, int Bmar)
//{
// CSimpleWindow * ret = new CSimpleWindow();
// int fontHeight;
// std::vector<std::string> brtext = breakText(text,32);
// std::vector<std::vector<SDL_Surface*> > * txtg = drawText(&brtext, fontHeight);
// std::pair<int,int> txts = getMaxSizes(txtg, fontHeight);
// ret->bitmap = drawBox1(txts.first+Lmar+Rmar,txts.second+Tmar+Bmar,player);
// ret->pos.h = ret->bitmap->h;
// ret->pos.w = ret->bitmap->w;
// if (centerOnMouse)
// {
// ret->pos.x = GH.current->motion.x - ret->pos.w/2;
// ret->pos.y = GH.current->motion.y - ret->pos.h/2;
// // Put the window back on screen if necessary
// vstd::amax(ret->pos.x, 0);
// vstd::amax(ret->pos.y, 0);
// vstd::amin(ret->pos.x, conf.cc.resx - ret->pos.w);
// vstd::amin(ret->pos.y, conf.cc.resy - ret->pos.h);
// }
// else
// {
// // Center on screen
// ret->pos.x = screen->w/2 - (ret->pos.w/2);
// ret->pos.y = screen->h/2 - (ret->pos.h/2);
// }
// int curh = ret->bitmap->h/2 - (fontHeight*txtg->size())/2;
// blitTextOnSur(txtg,fontHeight,curh,ret->bitmap);
// delete txtg;
// return ret;
//}
SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline/*=30*/, int imgToBmp/*=55*/ )
{
int curh;
@ -367,7 +359,7 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_
+ 5 // to sibtitle
+ (*txtg)[0][0]->h
+ 30;
SDL_Surface *ret = drawBox1(boxs.first,boxs.second,player);
SDL_Surface *ret = drawDialogBox(boxs.first,boxs.second,player);
blitTextOnSur(txtg,fontHeight,curh,ret);
curh += imgToBmp;
blitAt(bitmap,(ret->w/2)-(bitmap->w/2),curh,ret);
@ -380,8 +372,6 @@ SDL_Surface * CMessage::drawBoxTextBitmapSub( int player, std::string text, SDL_
void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
{
SDL_Surface * _or = NULL;
//const Font &f = *graphics->fonts[FONT_MEDIUM];
//int fontHeight = f.height;
if(dynamic_cast<CSelWindow*>(ret)) //it's selection window, so we'll blit "or" between components
_or = FNT_RenderText(FONT_MEDIUM,CGI->generaltexth->allTexts[4],Colors::Cornsilk);
@ -405,7 +395,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
ComponentsToBlit comps(ret->components,500,_or);
if (ret->components.size())
winSize.second += 30 + comps.h; //space to first component
winSize.second += 10 + comps.h; //space to first component
int bw = 0;
if (ret->buttons.size())
@ -426,12 +416,11 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
vstd::amin(winSize.first, screen->w - 150);
ret->bitmap = drawBox1 (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player);
ret->bitmap = drawDialogBox (winSize.first + 2*SIDE_MARGIN, winSize.second + 2*SIDE_MARGIN, player);
ret->pos.h=ret->bitmap->h;
ret->pos.w=ret->bitmap->w;
ret->center();
int curh = SIDE_MARGIN;
int xOffset = (ret->pos.w - ret->text->pos.w)/2;
@ -463,10 +452,7 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player)
}
}
for(size_t i=0; i<ret->components.size(); i++)
{
ret->components[i]->pos.x += ret->pos.x;
ret->components[i]->pos.y += ret->pos.y;
}
ret->components[i]->moveBy(Point(ret->pos.x, ret->pos.y));
if(_or)
SDL_FreeSurface(_or);
@ -534,29 +520,43 @@ void CMessage::drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int
CSDL_Ext::blitSurface(box[3], NULL, ret, &dstR);
}
ComponentResolved::ComponentResolved()
ComponentResolved::ComponentResolved( CComponent *Comp ):
comp(Comp)
{
comp = NULL;
img = NULL;
txt = NULL;
txtFontHeight = 0;
}
//Temporary assign ownership on comp
if (parent)
parent->removeChild(this);
if (comp->parent)
{
comp->parent->addChild(this);
comp->parent->removeChild(comp);
}
ComponentResolved::ComponentResolved( CComponent *Comp )
{
comp = Comp;
img = comp->getImg();
std::vector<std::string> brtext = CMessage::breakText(comp->subtitle,14); //text
txt = CMessage::drawText(&brtext,txtFontHeight,FONT_SMALL);
addChild(comp);
defActions = 255 - DISPOSE;
pos.x = pos.y = 0;
int textHeight = 0;
std::vector<std::string> textLines = CMessage::breakText(comp->subtitle, 14); //text
txt = CMessage::drawText(&textLines, textHeight, FONT_SMALL);
//calculate dimensions
std::pair<int,int> textSize = CMessage::getMaxSizes(txt, txtFontHeight);
comp->pos.w = std::max(textSize.first, img->w); //bigger of: subtitle width and image width
comp->pos.h = img->h + COMPONENT_TO_SUBTITLE + textSize.second;
std::pair<int,int> textSize = CMessage::getMaxSizes(txt, textHeight);
pos.w = std::max<int>(textSize.first, comp->pos.w); //bigger of: subtitle width and image width
pos.h = comp->pos.h + COMPONENT_TO_SUBTITLE + textSize.second;
comp->moveTo(Point((pos.w - comp->pos.w)/2, 0));
}
ComponentResolved::~ComponentResolved()
{
if (parent)
{
removeChild(comp);
parent->addChild(comp);
}
for(size_t i = 0; i < txt->size(); i++)
for(size_t j = 0; j < (*txt)[i].size(); j++)
if((*txt)[i][j])
@ -564,6 +564,22 @@ ComponentResolved::~ComponentResolved()
delete txt;
}
void ComponentResolved::showAll(SDL_Surface *to)
{
tlog0 << "Blitting at "<< pos.x << " " << pos.y << "\n";
int fontHeight;
if (graphics->fontsTrueType[FONT_SMALL])
fontHeight = TTF_FontHeight(graphics->fontsTrueType[FONT_SMALL]);
else
fontHeight = graphics->fonts[FONT_SMALL]->height;
CIntObject::showAll(to);
comp->showAll(to);
int textY = pos.y + comp->pos.h + COMPONENT_TO_SUBTITLE;
CMessage::blitTextOnSur(txt, fontHeight, textY, to, pos.x + pos.w/2 );
}
ComponentsToBlit::~ComponentsToBlit()
{
for(size_t i=0; i<comps.size(); i++)
@ -586,12 +602,12 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw,
{
ComponentResolved *cur = new ComponentResolved(SComps[i]);
int toadd = (cur->comp->pos.w + 12 + (_or ? _or->w : 0));
int toadd = (cur->pos.w + 12 + (_or ? _or->w : 0));
if (curw + toadd > maxw)
{
curr++;
vstd::amax(w,curw);
curw = cur->comp->pos.w;
curw = cur->pos.w;
comps.resize(curr+1);
}
else
@ -605,10 +621,11 @@ ComponentsToBlit::ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw,
for(size_t i=0;i<comps.size();i++)
{
int maxh = 0;
int maxHeight = 0;
for(size_t j=0;j<comps[i].size();j++)
vstd::amax(maxh,comps[i][j]->comp->pos.h);
h += maxh + BETWEEN_COMPS_ROWS;
vstd::amax(maxHeight, comps[i][j]->pos.h);
h += maxHeight + BETWEEN_COMPS_ROWS;
}
}
@ -616,44 +633,33 @@ void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh,
{
for (size_t i=0;i<comps.size();i++)//for each row
{
int totalw=0, maxh=0;
int totalw=0, maxHeight=0;
for(size_t j=0;j<(comps)[i].size();j++)//find max height & total width in this row
{
ComponentResolved *cur = (comps)[i][j];
totalw += cur->comp->pos.w;
vstd::amax(maxh,cur->comp->getImg()->h);//subtitles height will added later
}
if(_or)
{
totalw += (inter*2+_or->w) * ((comps)[i].size() - 1);
}
else//add space between comps in this row
{
totalw += (inter) * ((comps)[i].size() - 1);
totalw += cur->pos.w;
vstd::amax(maxHeight, cur->pos.h);
}
int startHeight = curh;
int middleh = curh + maxh/2;//axis for image aligment
int curw = (ret->w/2)-(totalw/2);
//add space between comps in this row
if(_or)
totalw += (inter*2+_or->w) * ((comps)[i].size() - 1);
else
totalw += (inter) * ((comps)[i].size() - 1);
int middleh = curh + maxHeight/2;//axis for image aligment
int curw = ret->w/2 - totalw/2;
for(size_t j=0;j<(comps)[i].size();j++)
{
ComponentResolved *cur = (comps)[i][j];
cur->moveTo(Point(curw, curh));
//blit img
int imgX = curw + ( cur->comp->pos.w - cur->comp->getImg()->w ) / 2;
int imgY = startHeight;
blitAt(cur->img, imgX, imgY, ret);
cur->comp->pos.x = imgX;
cur->comp->pos.y = imgY;
//blit subtitle
int textX = imgX + cur->comp->getImg()->w/2;
int textY = startHeight + cur->comp->getImg()->h + COMPONENT_TO_SUBTITLE;
CMessage::blitTextOnSur(cur->txt, cur->txtFontHeight, textY, ret, textX );
//blit component
cur->showAll(ret);
curw += cur->pos.w;
//if there is subsequent component blit "or"
curw += cur->comp->pos.w;
if(j<((comps)[i].size()-1))
{
if(_or)
@ -664,8 +670,7 @@ void ComponentsToBlit::blitCompsOnSur( SDL_Surface * _or, int inter, int &curh,
}
curw+=inter;
}
vstd::amax(curh, textY);
}
curh += BETWEEN_COMPS_ROWS;
curh += maxHeight + BETWEEN_COMPS_ROWS;
}
}

View File

@ -1,6 +1,7 @@
#pragma once
#include "FontBase.h"
#include "UIFramework/Geometries.h"
/*
@ -15,59 +16,39 @@
struct SDL_Surface;
enum EWindowType {infoOnly, infoOK, yesOrNO};
class CPreGame;
class MapSel;
class CSimpleWindow;
class CInfoWindow;
class CDefHandler;
class CComponent;
class CSelWindow;
class CSelectableComponent;
namespace NMessage
{
extern CDefHandler * ok, *cancel;
extern std::vector<std::vector<SDL_Surface*> > piecesOfBox; //in colors of all players
extern SDL_Surface * background ;
}
struct ComponentResolved
{
CComponent *comp;
SDL_Surface *img;
std::vector<std::vector<SDL_Surface*> > * txt;
int txtFontHeight;
ComponentResolved(); //c-tor
ComponentResolved(CComponent *Comp); //c-tor
~ComponentResolved(); //d-tor
};
struct ComponentsToBlit
{
std::vector< std::vector<ComponentResolved*> > comps;
int w, h;
void blitCompsOnSur(SDL_Surface * _or, int inter, int &curh, SDL_Surface *ret);
ComponentsToBlit(std::vector<CComponent*> & SComps, int maxw, SDL_Surface* _or); //c-tor
~ComponentsToBlit(); //d-tor
};
class ComponentResolved;
/// Class which draws formatted text messages and generates chat windows
class CMessage
{
public:
//Function usd only in CMessage.cpp
static std::pair<int,int> getMaxSizes(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight);
static std::vector<std::vector<SDL_Surface*> > * drawText(std::vector<std::string> * brtext, int &fontHeigh, EFonts font = FONT_MEDIUM);
static SDL_Surface * blitTextOnSur(std::vector<std::vector<SDL_Surface*> > * txtg, int fontHeight, int & curh, SDL_Surface * ret, int xCenterPos=-1); //xPos==-1 works as if ret->w/2
static void drawIWindow(CInfoWindow * ret, std::string text, int player);
static CSimpleWindow * genWindow(std::string text, int player, bool centerOnMouse=false, int Lmar=35, int Rmar=35, int Tmar=35, int Bmar=35);//supports h3 text formatting; player sets color of window, Lmar/Rmar/Tmar/Bmar are Left/Right/Top/Bottom margins
static SDL_Surface * drawBox1(int w, int h, int playerColor=1);
/// Draw border on exiting surface
static void drawBorder(int playerColor, SDL_Surface * ret, int w, int h, int x=0, int y=0);
static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charperline=30, int imgToBmp=55);
/// Draw simple dialog box (borders and background only)
static SDL_Surface * drawDialogBox(int w, int h, int playerColor=1);
/// Draw simple dialog box and blit bitmap with text on it
static SDL_Surface * drawBoxTextBitmapSub(int player, std::string text, SDL_Surface* bitmap, std::string sub, int charPerline=30, int imgToBmp=55);
static void drawIWindow(CInfoWindow * ret, std::string text, int player);
/// split text in lines
static std::vector<std::string> breakText(std::string text, size_t maxLineSize=30, const boost::function<int(char)> &charMetric = boost::function<int(char)>(), bool allowLeadingWhitespace = false);
static std::vector<std::string> breakText(std::string text, size_t maxLineWidth, EFonts font);
/// constructor
static void init();
/// destructor
static void dispose();
};

View File

@ -1766,7 +1766,7 @@ void InfoCard::clickRight( tribool down, bool previousState )
void InfoCard::showTeamsPopup()
{
SDL_Surface *bmp = CMessage::drawBox1(256, 90 + 50 * SEL->current->mapHeader->howManyTeams);
SDL_Surface *bmp = CMessage::drawDialogBox(256, 90 + 50 * SEL->current->mapHeader->howManyTeams);
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[657], 128, 30, FONT_MEDIUM, Colors::Jasmine, bmp); //{Team Alignments}
for(int i = 0; i < SEL->current->mapHeader->howManyTeams; i++)
@ -2390,7 +2390,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState )
if(val == -1 || which == BONUS) //random or bonus box
{
bmp = CMessage::drawBox1(256, 190);
bmp = CMessage::drawDialogBox(256, 190);
std::string *description = NULL;
switch(which)
@ -2462,7 +2462,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState )
}
else if(which == TOWN)
{
bmp = CMessage::drawBox1(256, 319);
bmp = CMessage::drawDialogBox(256, 319);
title = &CGI->generaltexth->allTexts[80];
CSDL_Ext::printAtMiddle(CGI->generaltexth->allTexts[79], 135, 137, FONT_MEDIUM, Colors::Jasmine, bmp);
@ -2491,7 +2491,7 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState )
else if(val >= 0)
{
const CHero *h = CGI->heroh->heroes[val];
bmp = CMessage::drawBox1(320, 255);
bmp = CMessage::drawDialogBox(320, 255);
title = &CGI->generaltexth->allTexts[77];
CSDL_Ext::printAtMiddle(*title, 167, 36, FONT_MEDIUM, Colors::Jasmine, bmp);

View File

@ -629,7 +629,8 @@ static si64 lod_seek(URLContext *context, si64 pos, int whence)
return -1;//video->offset;
}
static URLProtocol lod_protocol = {
static URLProtocol lod_protocol =
{
protocol_name,
lod_open,
lod_read,
@ -653,6 +654,9 @@ CVideoPlayer::CVideoPlayer()
av_register_all();
// Register our protocol 'lod' so we can directly read from mmaped memory
// TODO: URL protocol marked as deprecated in favor of avioContext
// VCMI should to it if URL protocol will be removed from ffmpeg or
// when new avioContext will be available in all distros (ETA: late 2012)
#ifdef WITH_AV_REGISTER_PROTOCOL2
av_register_protocol2(&lod_protocol, sizeof(lod_protocol));
#else
@ -682,40 +686,39 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
data = vidh.extract(fname, length);
if (data) {
std::string filePath;
if (data)
{
filePath.resize(100);
// Create our URL name with the 'lod' protocol as a prefix and a
// back pointer to our object. Should be 32 and 64 bits compatible.
char url[100];
sprintf(url, "%s:0x%016llx", protocol_name, (unsigned long long)(uintptr_t)this);
#if LIBAVFORMAT_VERSION_MAJOR < 54
int avfopen = av_open_input_file(&format, url, NULL, 0, NULL);
#else
int avfopen = avformat_open_input(&format, url, NULL, NULL);
#endif
if (avfopen != 0) {
return false;
}
} else {
// File is not in a container
#if LIBAVFORMAT_VERSION_MAJOR < 54
int avfopen = av_open_input_file(&format, (GameConstants::DATA_DIR + "/Data/video/" + fname).c_str(), NULL, 0, NULL);
#else
int avfopen = avformat_open_input(&format, (GameConstants::DATA_DIR + "/Data/video/" + fname).c_str(), NULL, NULL);
#endif
if (avfopen != 0) {
// tlog1 << "Video file not found: " GameConstants::DATA_DIR + "/Data/video/" + fname << std::endl;
return false;
}
sprintf(&filePath[0], "%s:0x%016llx", protocol_name, (unsigned long long)(uintptr_t)this);
}
else
filePath = GameConstants::DATA_DIR + "/Data/video/" + fname;
#if LIBAVFORMAT_VERSION_MAJOR < 53
int avfopen = av_open_input_file(&format, filePath.c_str(), NULL, 0, NULL);
#else
int avfopen = avformat_open_input(&format, filePath.c_str(), NULL, NULL);
#endif
if (avfopen != 0)
{
return false;
}
// Retrieve stream information
#if LIBAVCODEC_VERSION_MAJOR < 53
if (av_find_stream_info(format) < 0)
#else
if (avformat_find_stream_info(format, NULL) < 0)
#endif
return false;
// Find the first video stream
stream = -1;
for(ui32 i=0; i<format->nb_streams; i++) {
for(ui32 i=0; i<format->nb_streams; i++)
{
#if LIBAVCODEC_VERSION_MAJOR < 53
if (format->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
#else
@ -737,13 +740,19 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
// Find the decoder for the video stream
codec = avcodec_find_decoder(codecContext->codec_id);
if (codec == NULL) {
if (codec == NULL)
{
// Unsupported codec
return false;
}
// Open codec
if (avcodec_open(codecContext, codec) <0 ) {
#if LIBAVCODEC_VERSION_MAJOR < 53
if ( avcodec_open(codecContext, codec) < 0 )
#else
if ( avcodec_open2(codecContext, codec, NULL) < 0 )
#endif
{
// Could not open codec
codec = NULL;
return false;
@ -753,10 +762,13 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
frame = avcodec_alloc_frame();
// Allocate a place to put our YUV image on that screen
if (useOverlay) {
if (useOverlay)
{
overlay = SDL_CreateYUVOverlay(codecContext->width, codecContext->height,
SDL_YV12_OVERLAY, screen);
} else {
}
else
{
dest = CSDL_Ext::newSurface(codecContext->width, codecContext->height);
destRect.x = destRect.y = 0;
destRect.w = codecContext->width;
@ -767,11 +779,14 @@ bool CVideoPlayer::open(std::string fname, bool loop, bool useOverlay)
return false;
// Convert the image into YUV format that SDL uses
if (overlay) {
if (overlay)
{
sws = sws_getContext(codecContext->width, codecContext->height,
codecContext->pix_fmt, codecContext->width, codecContext->height,
PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);
} else {
}
else
{
PixelFormat screenFormat = PIX_FMT_NONE;
switch(screen->format->BytesPerPixel)
@ -806,22 +821,30 @@ bool CVideoPlayer::nextFrame()
if (sws == NULL)
return false;
while(!frameFinished) {
while(!frameFinished)
{
int ret = av_read_frame(format, &packet);
if (ret < 0) {
if (ret < 0)
{
// Error. It's probably an end of file.
if (doLoop && !gotError) {
if (doLoop && !gotError)
{
// Rewind
if (av_seek_frame(format, stream, 0, 0) < 0)
break;
gotError = true;
} else {
}
else
{
break;
}
} else {
}
else
{
// Is this a packet from the video stream?
if (packet.stream_index == stream) {
if (packet.stream_index == stream)
{
// Decode video frame
#ifdef WITH_AVCODEC_DECODE_VIDEO2
avcodec_decode_video2(codecContext, frame, &frameFinished, &packet);
@ -831,7 +854,8 @@ bool CVideoPlayer::nextFrame()
#endif
// Did we get a video frame?
if (frameFinished) {
if (frameFinished)
{
AVPicture pict;
if (overlay) {
@ -849,7 +873,9 @@ bool CVideoPlayer::nextFrame()
0, codecContext->height, pict.data, pict.linesize);
SDL_UnlockYUVOverlay(overlay);
} else {
}
else
{
pict.data[0] = (ui8 *)dest->pixels;
pict.linesize[0] = dest->pitch;
@ -894,7 +920,8 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
refreshCount = refreshWait;
if (nextFrame())
show(x,y,dst,update);
else {
else
{
open(fname);
nextFrame();
@ -904,7 +931,8 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
show(x, y--, dst, update);
}
}
else {
else
{
redraw(x, y, dst, update);
}
@ -914,35 +942,45 @@ void CVideoPlayer::update( int x, int y, SDL_Surface *dst, bool forceRedraw, boo
void CVideoPlayer::close()
{
fname = "";
if (sws) {
if (sws)
{
sws_freeContext(sws);
sws = NULL;
}
if (overlay) {
if (overlay)
{
SDL_FreeYUVOverlay(overlay);
overlay = NULL;
}
if (dest) {
if (dest)
{
SDL_FreeSurface(dest);
dest = NULL;
}
if (frame) {
if (frame)
{
av_free(frame);
frame = NULL;
}
if (codec) {
if (codec)
{
avcodec_close(codecContext);
codec = NULL;
codecContext = NULL;
}
if (format) {
if (format)
{
#if LIBAVCODEC_VERSION_MAJOR < 53
av_close_input_file(format);
format = NULL;
#else
avformat_close_input(&format);
#endif
}
}
@ -956,7 +994,8 @@ bool CVideoPlayer::playVideo(int x, int y, SDL_Surface *dst, bool stopOnKey)
pos.x = x;
pos.y = y;
while(nextFrame()) {
while(nextFrame())
{
if(stopOnKey && keyDown())
return false;

View File

@ -674,106 +674,18 @@ void CInfoPopup::init(int x, int y)
vstd::amin(pos.y, screen->h - bitmap->h);
}
void CComponent::init(Etype Type, int Subtype, int Val)
CComponent::CComponent(Etype Type, int Subtype, int Val):
image(nullptr)
{
std::ostringstream oss;
switch (Type)
{
case artifact:
description = CGI->arth->artifacts[Subtype]->Description();
subtitle = CGI->arth->artifacts[Subtype]->Name();
break;
case primskill:
oss << std::showpos << Val << " ";
if(Subtype < 4)
{
description = CGI->generaltexth->arraytxt[2+Subtype];
oss << CGI->generaltexth->primarySkillNames[Subtype];
}
else if(Subtype == 5) //spell points
{
description = CGI->generaltexth->allTexts[149];
oss << CGI->generaltexth->allTexts[387];
}
else
{
tlog1 << "Wrong subtype=" << Subtype << std::endl;
}
subtitle = oss.str();
break;
case building:
description = CGI->buildh->buildings[Subtype][Val]->Description();
subtitle = CGI->buildh->buildings[Subtype][Val]->Name();
break;
case secskill44: case secskill:
subtitle += CGI->generaltexth->levels[Val-1] + " " + CGI->generaltexth->skillName[Subtype];
description = CGI->generaltexth->skillInfoTexts[Subtype][Val-1];
break;
case morale:
description = CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)];
break;
case luck:
description = CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)];
break;
case resource:
description = CGI->generaltexth->allTexts[242];
oss << Val;
subtitle = oss.str();
break;
case spell:
description = CGI->spellh->spells[Subtype]->descriptions[Val];
subtitle = CGI->spellh->spells[Subtype]->name;
break;
case creature:
subtitle = (Val? boost::lexical_cast<std::string>(Val) + " " : "") + CGI->creh->creatures[Subtype]->*(Val != 1 ? &CCreature::namePl : &CCreature::nameSing);
break;
case experience:
description = CGI->generaltexth->allTexts[241];
oss << Val ;
if(Subtype && Val==1)
{
subtitle = CGI->generaltexth->allTexts[442];
}
else
{
subtitle = oss.str();
}
break;
case hero:
subtitle = description = CGI->heroh->heroes[Subtype]->name;
break;
case flag:
subtitle = CGI->generaltexth->capColors[Subtype];
break;
}
type = Type;
subtype = Subtype;
val = Val;
if(!img)
{
free = false;
if(type == CComponent::building)
setSurface(graphics->buildingPics[subtype],val);
}
SDL_Surface * temp = this->getImg();
if(!temp)
{
tlog1 << "Error: cannot find graphic for component with id=" << type << " subid=" << subtype << " val=" << val << std::endl;
return;
}
pos.w = temp->w;
pos.h = temp->h;
}
CComponent::CComponent(Etype Type, int Subtype, int Val, SDL_Surface *sur, bool freeSur)
{
img = sur;
free = freeSur;
used |= RCLICK;
init(Type,Subtype,Val);
}
CComponent::CComponent(const Component &c)
CComponent::CComponent(const Component &c):
image(nullptr)
{
img = NULL;
used |= RCLICK;
if(c.id == Component::EXPERIENCE)
init(experience,c.subtype,c.val);
else if(c.id == Component::SPELL)
@ -785,84 +697,143 @@ CComponent::CComponent(const Component &c)
subtitle += CGI->generaltexth->allTexts[3].substr(2,CGI->generaltexth->allTexts[3].length()-2);
}
CComponent::CComponent()
CComponent::CComponent():
image(nullptr)
{
img = NULL;
used |= RCLICK;
}
CComponent::~CComponent()
void CComponent::init(Etype Type, int Subtype, int Val)
{
if (free && img)
SDL_FreeSurface(img);
}
SDL_Surface * CComponent::setSurface(std:: string defname, int imagepos)
{
if (img)
tlog1<<"CComponent::setSurface: Warning - surface is already set!\n";
CDefEssential * def = CDefHandler::giveDefEss(defname);
free = true;
img = def->ourImages[imagepos].bitmap;
img->refcount++;//to preserve surface whed def is deleted
delete def;
return img;
type = Type;
subtype = Subtype;
val = Val;
subtitle = getSubtitle();
description = getDescription();
setSurface(getFileName(), getIndex());
pos.w = image->pos.w;
pos.h = image->pos.h;
}
//NOTE: whole method can be removed after 0.89+1 release
void CComponent::show(SDL_Surface * to)
{
blitAt(getImg(),pos.x,pos.y,to);
//In some places components position set manually instead of moveBy - it should be fixed
if (pos.x != image->pos.x
|| pos.y != image->pos.y)
{
tlog0 << "Error: Component position may be broken. Please report\n";
image->moveTo(pos.topLeft());
CIntObject::showAll(to);
}
else
CIntObject::show(to);
}
SDL_Surface * CComponent::getImg() const
std::string CComponent::getFileName()
{
switch(type)
{
case primskill: return "PSKILL";
case secskill: return "SECSK82";
case resource: return "RESOUR82";
case creature: return "TWCRPORT";
case artifact: return "ARTIFACT";
case experience: return "PSKILL";
case secskill44: return "SECSKILL";
case spell: return "SPELLSCR";
case morale: return "IMRL82";
case luck: return "ILCK82";
case building: return graphics->buildingPics[subtype];
case hero: return "PortraitsLarge";
case flag: return "TWCRPORT";
}
assert(0);
return 0;
}
size_t CComponent::getIndex()
{
switch(type)
{
case primskill: return subtype;
case secskill: return subtype*3 + 3 + val - 1;
case resource: return subtype;
case creature: return subtype+2;
case artifact: return subtype;
case experience: return 4;
case secskill44: return subtype*3 + 3 + val - 1;
case spell: return subtype;
case morale: return val+3;
case luck: return val+3;
case building: return val;
case hero: return subtype;
case flag: return subtype;
}
assert(0);
return 0;
}
std::string CComponent::getDescription()
{
if (img)
return img;
switch (type)
{
case artifact:
return graphics->artDefs->ourImages[subtype].bitmap;
case primskill:
return graphics->pskillsb->ourImages[subtype].bitmap;
case secskill44:
return graphics->abils44->ourImages[subtype*3 + 3 + val - 1].bitmap;
case secskill:
return graphics->abils82->ourImages[subtype*3 + 3 + val - 1].bitmap;
case resource:
return graphics->resources->ourImages[subtype].bitmap;
case experience:
return graphics->pskillsb->ourImages[4].bitmap;
case morale:
return graphics->morale82->ourImages[val+3].bitmap;
case luck:
return graphics->luck82->ourImages[val+3].bitmap;
case spell:
return graphics->spellscr->ourImages[subtype].bitmap;
case building:
assert(0); //img should have been set
//return setSurface(graphics->buildingPics[subtype],val);
case creature:
return graphics->bigImgs[subtype];
case hero:
return graphics->portraitLarge[subtype];
case flag:
return graphics->flags->ourImages[subtype].bitmap;
case primskill: return (subtype < 4)? CGI->generaltexth->arraytxt[2+subtype] //Primary skill
: CGI->generaltexth->allTexts[149]; //mana
case secskill: return CGI->generaltexth->skillInfoTexts[subtype][val-1];
case resource: return CGI->generaltexth->allTexts[242];
case creature: return "";
case artifact: return CGI->arth->artifacts[subtype]->Description();
case experience: return CGI->generaltexth->allTexts[241];
case secskill44: return CGI->generaltexth->skillInfoTexts[subtype][val-1];
case spell: return CGI->spellh->spells[subtype]->descriptions[val];
case morale: return CGI->generaltexth->heroscrn[ 4 - (val>0) + (val<0)];
case luck: return CGI->generaltexth->heroscrn[ 7 - (val>0) + (val<0)];
case building: return CGI->buildh->buildings[subtype][val]->Description();
case hero: return CGI->heroh->heroes[subtype]->name;
case flag: return "";
}
return NULL;
assert(0);
return 0;
}
std::string CComponent::getSubtitle()
{
//FIXME: some of these are horrible (e.g creature)
switch(type)
{
case primskill: return boost::str(boost::format("%+d %s") % val % (subtype < 4 ? CGI->generaltexth->primarySkillNames[subtype] : CGI->generaltexth->allTexts[387]));
case secskill: return CGI->generaltexth->levels[val-1] + " " + CGI->generaltexth->skillName[subtype];
case resource: return boost::lexical_cast<std::string>(val);
case creature: return (val? boost::lexical_cast<std::string>(val) + " " : "") + CGI->creh->creatures[subtype]->*(val != 1 ? &CCreature::namePl : &CCreature::nameSing);
case artifact: return CGI->arth->artifacts[subtype]->Name();
case experience: return (subtype && val==1) ? CGI->generaltexth->allTexts[442] : boost::lexical_cast<std::string>(val);
case secskill44: return CGI->generaltexth->levels[val-1] + " " + CGI->generaltexth->skillName[subtype];
case spell: return CGI->spellh->spells[subtype]->name;
case morale: return "";
case luck: return "";
case building: return CGI->buildh->buildings[subtype][val]->Name();
case hero: return CGI->heroh->heroes[subtype]->name;
case flag: return CGI->generaltexth->capColors[subtype];
}
assert(0);
return "";
}
void CComponent::setSurface(std::string defName, int imgPos)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
delChildNUll(image);
image = new CAnimImage(defName, imgPos);
}
void CComponent::clickRight(tribool down, bool previousState)
{
if(description.size())
adventureInt->handleRightClick(description,down);
}
void CComponent::activate()
{
activateRClick();
}
void CComponent::deactivate()
{
deactivateRClick();
}
void CSelectableComponent::clickLeft(tribool down, bool previousState)
{
@ -872,35 +843,30 @@ void CSelectableComponent::clickLeft(tribool down, bool previousState)
onSelect();
}
}
void CSelectableComponent::init()
{
selected = false;
}
CSelectableComponent::CSelectableComponent(const Component &c, boost::function<void()> OnSelect)
:CComponent(c),onSelect(OnSelect)
CSelectableComponent::CSelectableComponent(const Component &c, boost::function<void()> OnSelect):
CComponent(c),onSelect(OnSelect)
{
used |= LCLICK | KEYBOARD;
init();
}
CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, boost::function<void()> OnSelect)
:CComponent(Type,Sub,Val),onSelect(OnSelect)
CSelectableComponent::CSelectableComponent(Etype Type, int Sub, int Val, boost::function<void()> OnSelect):
CComponent(Type,Sub,Val),onSelect(OnSelect)
{
used |= LCLICK | KEYBOARD;
init();
}
CSelectableComponent::~CSelectableComponent()
{
}
void CSelectableComponent::activate()
{
activateKeys();
CComponent::activate();
activateLClick();
}
void CSelectableComponent::deactivate()
{
deactivateKeys();
CComponent::deactivate();
deactivateLClick();
}
void CSelectableComponent::select(bool on)
{
if(on != selected)
@ -913,12 +879,13 @@ void CSelectableComponent::select(bool on)
return;
}
}
void CSelectableComponent::show(SDL_Surface * to)
{
blitAt(getImg(),pos.x,pos.y,to);
CComponent::show(to);
if(selected)
{
CSDL_Ext::drawBorder(to, Rect::around(Rect(pos.x, pos.y, getImg()->w, getImg()->h)), int3(239,215,123));
CSDL_Ext::drawBorder(to, Rect::around(Rect(pos.x, pos.y, image->pos.w, image->pos.h)), int3(239,215,123));
}
printAtMiddleWB(subtitle,pos.x+pos.w/2,pos.y+pos.h+25,FONT_SMALL,12,Colors::Cornsilk,to);
@ -932,9 +899,10 @@ void CSelWindow::selectionChange(unsigned to)
if (!pom)
continue;
pom->select(i==to);
blitAt(pom->getImg(),pom->pos.x-pos.x,pom->pos.y-pos.y,bitmap);
}
redraw();
}
CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, const std::vector<CSelectableComponent*> &comps, const std::vector<std::pair<std::string,CFunctionList<void()> > > &Buttons, int askID)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
@ -965,9 +933,6 @@ CSelWindow::CSelWindow(const std::string &Text, int player, int charperline, con
comps[i]->assignedKeys.insert(SDLK_1+i);
}
CMessage::drawIWindow(this, Text, player);
BOOST_FOREACH(CComponent *c, components)
c->subtitle = "";//workaround - erase subtitles since they were hard-blitted by function drawing window
}
void CSelWindow::madeChoice()
@ -1971,8 +1936,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<u
for(int i=0;i<comps.size();i++)
{
comps[i]->pos.x = curx+pos.x;
comps[i]->pos.y = 326+pos.y;
comps[i]->moveTo(Point(pos.x + curx, pos.y + 326));
if( i < (comps.size()-1) )
{
curx += 44+21; //skill width + margin to "or"
@ -2021,7 +1985,10 @@ void CLevelWindow::show(SDL_Surface * to)
blitAt(graphics->portraitLarge[heroPortrait],170+pos.x,66+pos.y,to);
ok->showAll(to);
for(int i=0;i<comps.size();i++)
{
comps[i]->showAll(to);
comps[i]->show(to);
}
}
void CMinorResDataBar::show(SDL_Surface * to)
@ -5552,17 +5519,16 @@ void CPuzzleWindow::show(SDL_Surface * to)
void CTransformerWindow::CItem::showAll(SDL_Surface * to)
{
SDL_Surface * backgr = graphics->bigImgs[parent->army->getCreature(id)->idNumber];
blitAt(backgr, pos.x, pos.y, to);
CIntObject::showAll(to);
printAtMiddle(boost::lexical_cast<std::string>(size),pos.x+28, pos.y+76,FONT_SMALL,Colors::Cornsilk,to);//stack size
}
void CTransformerWindow::CItem::move()
{
if (left)
pos.x += 289;
moveBy(Point(289, 0));
else
pos.x -= 289;
moveBy(Point(-289, 0));
left = !left;
}
@ -5578,6 +5544,7 @@ void CTransformerWindow::CItem::clickLeft(tribool down, bool previousState)
CTransformerWindow::CItem::CItem(CTransformerWindow * _parent, int _size, int _id):
id(_id), size(_size), parent(_parent)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
used = LCLICK;
left = true;
pos.w = 58;
@ -5585,6 +5552,7 @@ CTransformerWindow::CItem::CItem(CTransformerWindow * _parent, int _size, int _i
pos.x += 45 + (id%3)*83 + id/6*83;
pos.y += 109 + (id/3)*98;
icon = new CAnimImage("TWCRPORT", parent->army->getCreature(id)->idNumber);
}
CTransformerWindow::CItem::~CItem()
@ -5713,11 +5681,13 @@ void CUniversityWindow::CItem::showAll(SDL_Surface * to)
printAtMiddleLoc (CGI->generaltexth->skillName[ID], 22, -13, FONT_SMALL, Colors::Cornsilk,to);//Name
printAtMiddleLoc (CGI->generaltexth->levels[0], 22, 57, FONT_SMALL, Colors::Cornsilk,to);//Level(always basic)
CPicture::showAll(to);
CIntObject::showAll(to);
}
CUniversityWindow::CItem::CItem(CUniversityWindow * _parent, int _ID, int X, int Y):
CPicture (graphics->abils44->ourImages[_ID*3+3].bitmap,X,Y,false),ID(_ID), parent(_parent)
CAnimImage ("SECSKILL", ID*3+3, 0, X, Y),
ID(_ID),
parent(_parent)
{
used = LCLICK | RCLICK | HOVER;
}
@ -6194,6 +6164,7 @@ CThievesGuildWindow::~CThievesGuildWindow()
void MoraleLuckBox::set(const IBonusBearer *node)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
const int textId[] = {62, 88}; //eg %s \n\n\n {Current Luck Modifiers:}
const int noneTxtId = 108; //Russian version uses same text for neutral morale\luck
const int neutralDescr[] = {60, 86}; //eg {Neutral Morale} \n\n Neutral morale means your armies will neither be blessed with extra attacks or freeze in combat.
@ -6205,7 +6176,6 @@ void MoraleLuckBox::set(const IBonusBearer *node)
int mrlt = -9;
TModDescr mrl;
if (node)
{
node->getModifiersWDescr(mrl, bonusType[morale]);
@ -6233,23 +6203,21 @@ void MoraleLuckBox::set(const IBonusBearer *node)
text += "\n" + mrl[it].second;
}
}
}
void MoraleLuckBox::showAll(SDL_Surface * to)
{
CDefEssential *def;
std::string imageName;
if (small)
def = morale ? graphics->morale30 : graphics->luck30;
imageName = morale ? "IMRL30": "ILCK30";
else
def = morale ? graphics->morale42 : graphics->luck42;
SDL_Surface *img = def->ourImages[bonusValue + 3].bitmap;
blitAt(img, Rect(img).centerIn(pos), to); //put img in the center of our pos
imageName = morale ? "IMRL42" : "ILCK42";
delChildNUll(image);
image = new CAnimImage(imageName, bonusValue + 3);
image->moveBy(Point(pos.w/2 - image->pos.w/2, pos.h/2 - image->pos.h/2));//center icon
}
MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small)
:morale(Morale),
small(Small)
MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small):
image(NULL),
morale(Morale),
small(Small)
{
bonusValue = 0;
pos = r + pos;

View File

@ -1,6 +1,6 @@
#pragma once
#include "CAnimation.h"
#include "FunctionList.h"
#include "../lib/ResourceSet.h"
#include "../lib/GameConstants.h"
@ -161,6 +161,15 @@ public:
/// common popup window component
class CComponent : public virtual CIntObject
{
size_t getIndex();
std::string getFileName();
std::string getDescription();
std::string getSubtitle();
protected:
CAnimImage *image; //our image
void setSurface(std::string defName, int imgPos);
public:
enum Etype
{
@ -172,22 +181,14 @@ public:
std::string description; //r-click
std::string subtitle; //TODO: comment me
SDL_Surface *img; //our image
bool free; //should surface be freed on delete
SDL_Surface * setSurface(std::string defName, int imgPos);
void init(Etype Type, int Subtype, int Val);
CComponent(Etype Type, int Subtype, int Val, SDL_Surface *sur=NULL, bool freeSur=false); //c-tor
virtual void init(Etype Type, int Subtype, int Val);
CComponent(Etype Type, int Subtype, int Val); //c-tor
CComponent(const Component &c); //c-tor
CComponent();; //c-tor
virtual ~CComponent(); //d-tor
CComponent(); //c-tor
void clickRight(tribool down, bool previousState); //call-in
SDL_Surface * getImg() const;
virtual void show(SDL_Surface * to);
virtual void activate();
virtual void deactivate();
void show(SDL_Surface * to);
};
class CSelectableComponent : public CComponent, public CKeyShortcut
@ -202,8 +203,6 @@ public:
CSelectableComponent(const Component &c, boost::function<void()> OnSelect = 0); //c-tor
~CSelectableComponent(); //d-tor
virtual void show(SDL_Surface * to);
void activate();
void deactivate();
void select(bool on);
};
@ -777,12 +776,12 @@ public:
class MoraleLuckBox : public LRClickableAreaWTextComp
{
CAnimImage *image;
public:
bool morale; //true if morale, false if luck
bool small;
void set(const IBonusBearer *node);
void showAll(SDL_Surface * to);
MoraleLuckBox(bool Morale, const Rect &r, bool Small=false);
~MoraleLuckBox();
@ -1022,6 +1021,7 @@ public:
bool left;//position of the item
int size; //size of creature stack
CTransformerWindow * parent;
CAnimImage *icon;
void move();
void showAll(SDL_Surface * to);
@ -1047,7 +1047,7 @@ public:
class CUniversityWindow : public CIntObject
{
class CItem : public CPicture
class CItem : public CAnimImage
{
public:
int ID;//id of selected skill

View File

@ -8,7 +8,7 @@
// faction: its faction (0 to 8)
// The following properties are optional:
// upgrade: number of the creature to upgrade to
// upgrades: id of the creatures to upgrade to
// projectile_defname: if the creature is a shooter, graphics for the projectile
// projectile_spin: if the creature is a shooter, indicate whether the projectile spins
// turret_shooter: indicates whether the shooter appears in the castle turrets
@ -23,7 +23,7 @@
"level": 1,
"name": [ "Pikeman" ],
"faction": 0,
"upgrade": 1,
"upgrades": [1],
"ability_add": [ [ "CHARGE_IMMUNITY", 0, 0, 0 ] ], //pikeman immunity to Champion charge bonus
"defname": "CPKMAN.DEF"
},
@ -42,7 +42,7 @@
"level": 2,
"name": [ "Archer", "LightCrossbowman" ],
"faction": 0,
"upgrade": 3,
"upgrades": [3],
"defname": "CLCBOW.DEF",
"projectile_defname": "PLCBOWX.DEF",
"projectile_spin": false,
@ -65,7 +65,7 @@
"name": [ "Griffin" ],
"faction": 0,
"ability_add": [ [ "ADDITIONAL_RETALIATION", 1, 0, 0 ] ], //griffins retaliate twice
"upgrade": 5,
"upgrades": [5],
"defname": "CGRIFF.DEF"
},
@ -83,7 +83,7 @@
"level": 4,
"name": [ "Swordsman" ],
"faction": 0,
"upgrade": 7,
"upgrades": [7],
"defname": "CSWORD.DEF"
},
@ -100,7 +100,7 @@
"level": 5,
"name": [ "Monk" ],
"faction": 0,
"upgrade": 9,
"upgrades": [9],
"defname": "CMONKK.DEF",
"projectile_defname": "CPRZEAX.DEF",
"projectile_spin": false
@ -121,7 +121,7 @@
"level": 6,
"name": [ "Cavalier" ],
"faction": 0,
"upgrade": 11,
"upgrades": [11],
"defname": "CCAVLR.DEF"
},
@ -140,7 +140,7 @@
"faction": 0,
"ability_add": [ [ "HATE", 50, 55, 0 ], //angels hate archdevils
[ "HATE", 50, 54, 0 ] ], //angels hate devils
"upgrade": 13,
"upgrades": [13],
"defname": "CANGEL.DEF"
},
@ -162,7 +162,7 @@
"level": 1,
"name": [ "Centaur" ],
"faction": 1,
"upgrade": 15,
"upgrades": [15],
"defname": "CCENTR.DEF"
},
@ -180,7 +180,7 @@
"name": [ "Dwarf" ],
"faction": 1,
"ability_add": [ [ "MAGIC_RESISTANCE", 20, 0, 0 ] ], //dwarf's magic resistance 20%
"upgrade": 17,
"upgrades": [17],
"defname": "CDWARF.DEF"
},
@ -198,7 +198,7 @@
"level": 3,
"name": [ "WoodElf" ],
"faction": 1,
"upgrade": 19,
"upgrades": [19],
"defname": "CELF.DEF",
"projectile_defname": "PELFX.DEF",
"projectile_spin": false,
@ -221,7 +221,7 @@
"name": [ "Pegasus" ],
"faction": 1,
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ENEMY", 2, 0, 0 ] ], //pegasus makes spell cost higher for enemy mage
"upgrade": 21,
"upgrades": [21],
"defname": "CPEGAS.DEF"
},
@ -240,7 +240,7 @@
"name": [ "Treefolk" ],
"faction": 1,
"ability_add": [ [ "SPELL_AFTER_ATTACK", 100, 72, 0 ] ], //dendroids cast bind
"upgrade": 23,
"upgrades": [23],
"defname": "CTREE.DEF"
},
@ -260,7 +260,7 @@
"faction": 1,
"ability_add": [ [ "SPELL_RESISTANCE_AURA", 0, 55, 0 ], //unicorn
[ "SPELL_AFTER_ATTACK", 20, 62, 0 ] ], //unicorns cast blind with 20% probability
"upgrade": 25,
"upgrades": [25],
"defname": "CUNICO.DEF"
},
@ -282,7 +282,7 @@
"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ], //green dragon is a dragon
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //green dragon's breath
[ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ] ], //green dragon's spell immunity
"upgrade": 27,
"upgrades": [27],
"defname": "CGDRAG.DEF"
},
@ -302,7 +302,7 @@
"level": 1,
"name": [ "ApprenticeGremlin" ],
"faction": 2,
"upgrade": 29,
"upgrades": [29],
"defname": "CGREMA.DEF"
},
@ -322,7 +322,7 @@
"name": [ "StoneGargoyle" ],
"faction": 2,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ], //stone gargoyles are non-living
"upgrade": 31,
"upgrades": [31],
"defname": "CGARGO.DEF"
},
@ -342,7 +342,7 @@
"faction": 2,
"ability_add": [ [ "SPELL_DAMAGE_REDUCTION", 50, -1, 0 ], //stone golems reduce dmg from spells
[ "NON_LIVING", 0, 0, 0 ] ], //stone golems are non-living
"upgrade": 33,
"upgrades": [33],
"defname": "CSGOLE.DEF"
},
@ -362,7 +362,7 @@
"name": [ "Mage" ],
"faction": 2,
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ] ], //mages reduce spell cost
"upgrade": 35,
"upgrades": [35],
"defname": "CMAGE.DEF",
"projectile_defname": "PMAGEX.DEF",
"projectile_spin": false,
@ -374,7 +374,7 @@
"level": 4,
"name": [ "ArchMage" ],
"faction": 2,
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ]], //archmages reduce spell cost
"ability_add": [ [ "CHANGES_SPELL_COST_FOR_ALLY", 2, 0, 0 ]], //archmages reduce spell cost
"defname": "CAMAGE.DEF",
"projectile_defname": "PMAGEX.DEF",
"projectile_spin": false
@ -387,7 +387,7 @@
"faction": 2,
"ability_add": [ [ "HATE", 50, 53, 0 ], //master genies hate efreets
[ "HATE", 50, 52, 0 ] ], //genies hate efreet sultans
"upgrade": 37,
"upgrades": [37],
"defname": "CGENIE.DEF"
},
@ -410,7 +410,7 @@
"name": [ "NagaSentinel" ],
"faction": 2,
"ability_add": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //nagas block retaliation
"upgrade": 39,
"upgrades": [39],
"defname": "CNAGA.DEF"
},
@ -429,7 +429,7 @@
"name": [ "LesserTitan" ],
"faction": 2,
"ability_add": [ ["MIND_IMMUNITY", 0, 0, 0] ], //giants are immune to mind spells
"upgrade": 41,
"upgrades": [41],
"defname": "CLTITA.DEF"
},
@ -450,7 +450,7 @@
"level": 1,
"name": [ "Imp" ],
"faction": 3,
"upgrade": 43,
"upgrades": [43],
"defname": "CIMP.DEF"
},
@ -468,7 +468,7 @@
"level": 2,
"name": [ "Gog" ],
"faction": 3,
"upgrade": 45,
"upgrades": [45],
"defname": "CGOG.DEF",
"projectile_defname": "CPRGOGX.DEF",
"projectile_spin": false,
@ -491,7 +491,7 @@
"level": 3,
"name": [ "HellHound" ],
"faction": 3,
"upgrade": 47,
"upgrades": [47],
"ability_remove": [ "FLYING" ],
"defname": "CHHOUN.DEF"
},
@ -512,7 +512,7 @@
"level": 4,
"name": [ "Single-HornedDemon" ],
"faction": 3,
"upgrade": 49,
"upgrades": [49],
"defname": "COHDEM.DEF"
},
@ -529,7 +529,7 @@
"level": 5,
"name": [ "PitFiend" ],
"faction": 3,
"upgrade": 51,
"upgrades": [51],
"defname": "CPFIEN.DEF"
},
@ -538,7 +538,7 @@
"level": 5,
"name": [ "PitFoe" ],
"faction": 3,
"ability_add": [ [ "DAEMON_SUMMONING", 50, 48, 0 ],
"ability_add": [ [ "DAEMON_SUMMONING", 50, 48, 0 ],
[ "CASTS", 1, 0, 0] ], //pit lord
"defname": "CPFOE.DEF"
},
@ -552,7 +552,7 @@
[ "HATE", 50, 36, 0 ],
[ "FLYING", 0, 0, 0 ], //efreeti hate master genies
[ "FIRE_IMMUNITY", 0, 0, 0 ] ], //efreeti hate genies
"upgrade": 53,
"upgrades": [53],
"defname": "CEFREE.DEF"
},
@ -578,7 +578,7 @@
[ "HATE", 50, 12, 0 ],
[ "ENEMY_LUCK_DECREASING", 1, 0, 0 ], //devils //devils hate archangles
[ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //devils //devils hate angels
"upgrade": 55,
"upgrades": [55],
"defname": "CDEVIL.DEF"
},
@ -599,7 +599,7 @@
"level": 1,
"name": [ "Skeleton" ],
"faction": 4,
"upgrade": 57,
"upgrades": [57],
"defname": "CSKELE.DEF"
},
@ -616,7 +616,7 @@
"level": 2,
"name": [ "Zombie" ],
"faction": 4,
"upgrade": 59,
"upgrades": [59],
"defname": "CZOMBI.DEF"
},
@ -634,7 +634,7 @@
"name": [ "Wight" ],
"faction": 4,
"ability_add": [ [ "FULL_HP_REGENERATION", 0, 1, 0 ] ], //wight
"upgrade": 61,
"upgrades": [61],
"defname": "CWIGHT.DEF"
},
@ -654,7 +654,7 @@
"name": [ "Vampire" ],
"faction": 4,
"ability_add": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ] ], //vampires //vampire lords
"upgrade": 63,
"upgrades": [63],
"defname": "CVAMP.DEF"
},
@ -674,7 +674,7 @@
"name": [ "Lich" ],
"faction": 4,
"ability_add": [ [ "SPELL_LIKE_ATTACK", 0, 76, 0 ] ], //liches
"upgrade": 65,
"upgrades": [65],
"defname": "CLICH.DEF",
"projectile_defname": "PLICH.DEF",
"projectile_spin": false,
@ -698,7 +698,7 @@
"name": [ "BlackKnight" ],
"faction": 4,
"ability_add": [ [ "SPELL_AFTER_ATTACK", 20, 42, 0 ] ], //black knights
"upgrade": 67,
"upgrades": [67],
"defname": "CBKNIG.DEF"
},
@ -718,7 +718,7 @@
"name": [ "BoneDragon" ],
"faction": 4,
"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ] ], //bone dragon is a dragon
"upgrade": 69,
"upgrades": [69],
"defname": "CNDRGN.DEF"
},
@ -738,7 +738,7 @@
"name": [ "Troglodyte" ],
"faction": 5,
"ability_add": [ [ "SPELL_IMMUNITY", 0, 62, 0 ] ], //troglodytes are immune to blind
"upgrade": 71,
"upgrades": [71],
"defname": "CTROGL.DEF"
},
@ -757,7 +757,7 @@
"name": [ "Harpy" ],
"faction": 5,
"ability_add": [ [ "RETURN_AFTER_STRIKE", 0, 0, 0 ] ], //Harpies return after attack
"upgrade": 73,
"upgrades": [73],
"defname": "CHARPY.DEF"
},
@ -776,7 +776,7 @@
"level": 3,
"name": [ "Beholder" ],
"faction": 5,
"upgrade": 75,
"upgrades": [75],
"defname": "CBEHOL.DEF",
"projectile_defname": "SMBALX.DEF",
"projectile_spin": false
@ -785,7 +785,7 @@
{
"id": 75,
"level": 3,
"name": [ "EvilEye", "M75" ],
"name": [ "EvilEye", "M75" ],
"faction": 5,
"defname": "CEVEYE.DEF",
"projectile_defname": "SMBALX.DEF",
@ -798,7 +798,7 @@
"name": [ "Medusa", "Medusae" ],
"faction": 5,
"ability_add": [ [ "SPELL_AFTER_ATTACK", 20, 70, 2000 ] ], //medusas //minotaurs
"upgrade": 77,
"upgrades": [77],
"defname": "CMEDUS.DEF",
"projectile_defname": "PMEDUSX.DEF",
"projectile_spin": false,
@ -822,7 +822,7 @@
"name": [ "Minotaur" ],
"faction": 5,
"ability_add": [ [ "SELF_MORALE", 0, 0, 0 ] ],
"upgrade": 79,
"upgrades": [79],
"defname": "CMINOT.DEF"
},
@ -840,7 +840,7 @@
"level": 6,
"name": [ "Manticore" ],
"faction": 5,
"upgrade": 81,
"upgrades": [81],
"defname": "CMCORE.DEF"
},
@ -861,7 +861,7 @@
"ability_add": [ [ "DRAGON_NATURE", 0, 0, 0 ], //red dragon is a dragon
[ "TWO_HEX_ATTACK_BREATH", 0, 0, 0 ], //Red Dragon has breath attack
[ "LEVEL_SPELL_IMMUNITY", 3, 0, 0 ] ], //red dragon's spell immunity
"upgrade": 83,
"upgrades": [83],
"defname": "CRDRGN.DEF"
},
@ -883,7 +883,7 @@
"level": 1,
"name": [ "Goblin" ],
"faction": 6,
"upgrade": 85,
"upgrades": [85],
"defname": "CGOBLI.DEF"
},
@ -900,7 +900,7 @@
"level": 2,
"name": [ "GoblinWolfRider" ],
"faction": 6,
"upgrade": 87,
"upgrades": [87],
"defname": "CBWLFR.DEF"
},
@ -918,7 +918,7 @@
"level": 3,
"name": [ "Orc" ],
"faction": 6,
"upgrade": 89,
"upgrades": [89],
"defname": "CORC.DEF",
"projectile_defname": "PORCHX.DEF",
"projectile_spin": true,
@ -940,7 +940,7 @@
"level": 4,
"name": [ "Ogre" ],
"faction": 6,
"upgrade": 91,
"upgrades": [91],
"defname": "COGRE.DEF"
},
@ -960,7 +960,7 @@
"level": 5,
"name": [ "Roc" ],
"faction": 6,
"upgrade": 93,
"upgrades": [93],
"defname": "CROC.DEF"
},
@ -979,7 +979,7 @@
"level": 6,
"name": [ "Cyclops" ],
"faction": 6,
"upgrade": 95,
"upgrades": [95],
"defname": "CCYCLR.DEF",
"projectile_defname": "PCYCLBX.DEF",
"projectile_spin": true
@ -1001,7 +1001,7 @@
"name": [ "YoungBehemoth" ],
"faction": 6,
"ability_add": [ [ "ENEMY_DEFENCE_REDUCTION", 40, 0, 0 ] ], //behemots
"upgrade": 97,
"upgrades": [97],
"defname": "CYBEHE.DEF"
},
@ -1019,7 +1019,7 @@
"level": 1,
"name": [ "Gnoll" ],
"faction": 7,
"upgrade": 99,
"upgrades": [99],
"defname": "CGNOLL.DEF"
},
@ -1036,7 +1036,7 @@
"level": 2,
"name": [ "PrimitiveLizardman" ],
"faction": 7,
"upgrade": 101,
"upgrades": [101],
"defname": "CPLIZA.DEF",
"projectile_defname": "PPLIZAX.DEF",
"projectile_spin": false,
@ -1058,7 +1058,7 @@
"level": 5,
"name": [ "CopperGorgon" ],
"faction": 7,
"upgrade": 103,
"upgrades": [103],
"defname": "CCGORG.DEF"
},
@ -1077,7 +1077,7 @@
"name": [ "Dragonflies", "DragonFly", "SerpentFly" ],
"faction": 7,
"ability_add": [ [ "SPELL_AFTER_ATTACK", 100, 78, 0 ] ], //serpent fly
"upgrade": 105,
"upgrades": [105],
"defname": "CDRFLY.DEF"
},
@ -1097,7 +1097,7 @@
"name": [ "Basilisk" ],
"faction": 7,
"ability_add": [ [ "SPELL_AFTER_ATTACK", 20, 70, 0 ] ], //basilisks
"upgrade": 107,
"upgrades": [107],
"defname": "CBASIL.DEF"
},
@ -1115,7 +1115,7 @@
"level": 6,
"name": [ "Wyvern" ],
"faction": 7,
"upgrade": 109,
"upgrades": [109],
"defname": "CWYVER.DEF"
},
@ -1135,7 +1135,7 @@
"faction": 7,
"ability_add": [ [ "BLOCKS_RETALIATION", 0, 0, 0 ], //hydras
[ "ATTACKS_ALL_ADJACENT", 0, 0, 0 ] ], //hydras
"upgrade": 111,
"upgrades": [111],
"defname": "CHYDRA.DEF"
},
@ -1162,7 +1162,7 @@
[ "NON_LIVING", 0, 0, 0 ],
[ "MORE_DAMAGE_FROM_SPELL", 100, 19, 0 ], //air elementals are vulnerable to chain lightning
[ "MORE_DAMAGE_FROM_SPELL", 100, 17, 0 ] ], //air elementals are vulnerable to lightning bolt //air elementals are non-living
"upgrade": 127,
"upgrades": [127],
"defname": "CAELEM.DEF"
},
@ -1179,7 +1179,7 @@
[ "SPELL_IMMUNITY", 0, 17, 0 ], //earth elementals are immune to lightning bolt
[ "NON_LIVING", 0, 0, 0 ],
[ "MORE_DAMAGE_FROM_SPELL", 100, 23, 0 ] ], //earth elementals are vulnerable to meteor shower
"upgrade": 125,
"upgrades": [125],
"defname": "CEELEM.DEF"
},
@ -1196,7 +1196,7 @@
[ "MORE_DAMAGE_FROM_SPELL", 100, 20, 0 ], //fire elementals are vulnerable to frost ring
[ "MORE_DAMAGE_FROM_SPELL", 100, 16, 0 ], //fire elementals are vulnerable to ice bolt
[ "FIRE_IMMUNITY", 0, 0, 0 ] ], //fire elementals are immune to fire spells
"upgrade": 129,
"upgrades": [129],
"defname": "CFELEM.DEF"
},
@ -1217,7 +1217,7 @@
[ "MORE_DAMAGE_FROM_SPELL", 100, 21, 0 ], //water elementals are vulnerable to fireball
[ "MORE_DAMAGE_FROM_SPELL", 100, 13, 0 ], //water elementals are vulnerable to fire wall
[ "DOUBLE_WIDE", 0, 0, 0 ] ],
"upgrade": 123,
"upgrades": [123],
"defname": "CWELEM.DEF"
},
@ -1246,7 +1246,7 @@
"level": 1,
"name": [ "Pixie", "Pixies" ],
"faction": 8,
"upgrade": 119,
"upgrades": [119],
"defname": "CPIXIE.DEF"
},
@ -1265,7 +1265,7 @@
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] ], //magic elementals shouldn't get morale
"ability_remove": [ "DOUBLE_WIDE" ],
"upgrade": 121,
"upgrades": [121],
"defname": "CPSYEL.DEF"
},
@ -1285,11 +1285,11 @@
"level": 3,
"name": [ "IceElemental" ],
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ],
[ "DOUBLE_WIDE", 0, 0, 0 ], //ice elemental should be treated as double-wide
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 32, 0 ]],
[ "SPELLCASTER", 2, 32, 0 ]],
"defname": "CICEE.DEF",
"projectile_defname": "PICEE.DEF",
"projectile_spin": false
@ -1315,7 +1315,7 @@
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ], //storm elementals shouldn't get morale
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 30, 0 ]],
[ "SPELLCASTER", 2, 30, 0 ]],
"defname": "CSTORM.DEF",
"projectile_defname": "CPRGTIX.DEF",
"projectile_spin": false,
@ -1326,11 +1326,11 @@
"id": 129,
"level": 4,
"name": [ "ElectricityElemental" ],
"faction": 8,
"faction": 8,
"ability_add": [ [ "NON_LIVING", 0, 0, 0 ] , //energy elementals shouldn't get morale //Crystal Dragons do not fly
[ "CREATURE_ENCHANT_POWER", 6, 0, 0 ],
[ "CASTS", 3, 0, 0 ],
[ "SPELLCASTER", 2, 31, 0 ]],
[ "SPELLCASTER", 2, 31, 0 ]],
"defname": "CNRG.DEF"
},
@ -1339,7 +1339,7 @@
"level": 7,
"name": [ "Firebird" ],
"faction": 8,
"upgrade": 131,
"upgrades": [131],
"defname": "CFBIRD.DEF"
},
@ -1426,7 +1426,7 @@
"level": 4,
"name": [ "Sharpshooter" ],
"faction": -1,
"ability_add": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],
"ability_add": [ [ "NO_WALL_PENALTY", 0, 0, 0 ],
[ "NO_DISTANCE_PENALTY", 0, 0, 0 ] ], //Sharpshooter
"defname": "CSHARP.DEF",
"projectile_defname": "PELFX.DEF",
@ -1982,7 +1982,7 @@
}
],
// something hacking
// something hacking
"unused_creatures": [ 122, 124, 126, 128, 145, 146, 147, 148, 149, 160,
161, 162, 163, 174, 175, 176, 177, 178, 179, 180,
181, 182, 183, 184, 185, 186, 187, 188, 189, 190,

View File

@ -437,9 +437,10 @@ void CCreatureHandler::loadCreatures()
c->faction = creature["faction"].Float();
c->animDefName = creature["defname"].String();
value = &creature["upgrade"];
if (!value->isNull())
c->upgrades.insert(value->Float());
BOOST_FOREACH(const JsonNode &value, creature["upgrades"].Vector())
{
c->upgrades.insert(value.Float());
}
value = &creature["projectile_defname"];
if (!value->isNull())
@ -472,7 +473,8 @@ void CCreatureHandler::loadCreatures()
}
}
BOOST_FOREACH(const JsonNode &creature, config["unused_creatures"].Vector()) {
BOOST_FOREACH(const JsonNode &creature, config["unused_creatures"].Vector())
{
notUsedMonsters += creature.Float();
}

View File

@ -1148,13 +1148,21 @@ int CPlayerSpecificInfoCallback::getMyColor() const
return player;
}
int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero) const
int CPlayerSpecificInfoCallback::getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned) const
{
//boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
for (size_t i=0; i<gs->players[player].heroes.size();i++)
if (hero->inTownGarrison && !includeGarrisoned)
return -1;
size_t index = 0;
auto & heroes = gs->players[player].heroes;
for (auto curHero= heroes.begin(); curHero!=heroes.end(); curHero++)
{
if (gs->players[player].heroes[i]==hero)
return i;
if (includeGarrisoned || !(*curHero)->inTownGarrison)
index++;
if (*curHero == hero)
return index;
}
return -1;
}

View File

@ -226,7 +226,7 @@ public:
int getMyColor() const;
std::vector <const CGTownInstance *> getTownsInfo(bool onlyOur = true) const; //true -> only owned; false -> all visible
int getHeroSerial(const CGHeroInstance * hero)const;
int getHeroSerial(const CGHeroInstance * hero, bool includeGarrisoned=true) const;
const CGTownInstance* getTownBySerial(int serialId) const; // serial id is [0, number of towns)
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