1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-03 13:01:33 +02:00

* VCMI won't crash when r-click neutral stack during the battle

* water won't blink behind shipyard in the Castle
* in the townlist in castle selected town will by placed on the 2nd place (not 3rd)
* fixed memory leaks
* properly displaying two-hex creatures in recruit/split/info window
* minor improvements
This commit is contained in:
Michał W. Urbańczyk 2008-06-04 13:00:56 +00:00
parent 61ce0c915c
commit 7e12926baa
6 changed files with 102 additions and 46 deletions

View File

@ -904,11 +904,13 @@ void CBattleHex::clickRight(boost::logic::tribool down)
{
pom = new StackState();
const CGHeroInstance *h = myst.owner == myInterface->attackingHeroInstance->tempOwner ? myInterface->attackingHeroInstance : myInterface->defendingHeroInstance;
if(h)
{
pom->attackBonus = h->primSkills[0];
pom->defenseBonus = h->primSkills[1];
pom->luck = h->getCurrentLuck();
pom->morale = h->getCurrentMorale();
}
(new CCreInfoWindow(myst.creature->idNumber,0,pom,boost::function<void()>(),boost::function<void()>()))
->activate();
}

View File

@ -232,7 +232,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
townlist->genList();
townlist->selected = getIndexOf(townlist->items,Town);
if((townlist->selected+1) > townlist->SIZE)
townlist->from = townlist->selected - townlist->SIZE + 1;
townlist->from = townlist->selected - townlist->SIZE + 2;
CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
exit->bitmapOffset = 4;
@ -343,7 +343,7 @@ void CCastleInterface::buildingClicked(int building)
crs.push_back(std::make_pair(town->town->basicCreatures[building-30],amount));
CRecrutationWindow *rw = new CRecrutationWindow(crs,this);
CRecrutationWindow *rw = new CRecrutationWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
rw->activate();
}
else
@ -468,7 +468,7 @@ void CCastleInterface::show(SDL_Surface * to)
//blit buildings
for(int i=0;i<buildings.size();i++)
{
int frame = (animval)%(buildings[i]->max - buildings[i]->offset);
int frame = ((animval)%(buildings[i]->max - buildings[i]->offset)) + buildings[i]->offset;
if(frame)
{
blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
@ -606,10 +606,29 @@ void CCastleInterface::recreateBuildings()
vortex->max = 10;
}
}
}
void CCastleInterface::recruit(int ID, int amount)
//code for the shipyard in the Castle
else if((town->subID == 0) && (town->builtBuildings.find(6)!=town->builtBuildings.end()))
{
LOCPLINT->cb->recruitCreatures(town,ID,amount);
CBuildingRect *shipyard = NULL;
for(int i=0;i<buildings.size();i++)
{
if(buildings[i]->str->ID==6)
{
shipyard=buildings[i];
break;
}
}
if(town->builtBuildings.find(8)!=town->builtBuildings.end()) //there is citadel
{
shipyard->offset = 1;
shipyard->max = shipyard->def->ourImages.size();
}
else
{
shipyard->offset = 0;
shipyard->max = 1;
}
}
}
void CHallInterface::CResDataBar::show(SDL_Surface * to)
{

View File

@ -28,7 +28,7 @@ public:
void mouseMoved (SDL_MouseMotionEvent & sEvent);
};
class CCastleInterface : public IShowable, public IActivable, public IRecruit
class CCastleInterface : public IShowable, public IActivable
{
public:
bool showing;
@ -64,7 +64,6 @@ public:
void addBuilding(int bid);
void removeBuilding(int bid);
void recreateBuildings();
void recruit(int ID, int amount);
};
class CHallInterface : public IShowable, public IActivable

View File

@ -35,6 +35,7 @@ struct BattleAction
struct StackState
{
StackState(){attackBonus=defenseBonus=healthBonus=speedBonus=morale=luck=shotsLeft=currentHealth=0;};
int attackBonus, defenseBonus, healthBonus, speedBonus;
int currentHealth;
int shotsLeft;

View File

@ -2662,6 +2662,28 @@ void CTownList::draw()
}
CCreaturePic::CCreaturePic(CCreature *cre)
:c(cre)
{
anim = new CCreatureAnimation(cre->animDefName);
}
CCreaturePic::~CCreaturePic()
{
delete anim;
}
int CCreaturePic::blitPic(SDL_Surface *to, int x, int y, bool nextFrame)
{
blitAt(CGI->creh->backgrounds[c->faction],x,y);//curx-50,pos.y+130-65);
SDL_Rect dst = genRect(130,100,x,y);
if(c->isDoubleWide())
x-=15;
return anim->nextFrameMiddle(to,x+70,y+45,true,nextFrame,false,&dst);
}
SDL_Surface * CCreaturePic::getPic(bool nextFrame)
{
//TODO: write
return NULL;
}
void CRecrutationWindow::close()
{
deactivate();
@ -2677,7 +2699,7 @@ void CRecrutationWindow::Max()
}
void CRecrutationWindow::Buy()
{
rec->recruit(creatures[which].ID,slider->value);
recruit(creatures[which].ID,slider->value);
close();
}
void CRecrutationWindow::Cancel()
@ -2762,15 +2784,13 @@ void CRecrutationWindow::show(SDL_Surface * to)
curx = pos.x + 192 + 102 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
for(int i=0;i<creatures.size();i++)
{
blitAt(CGI->creh->backgrounds[CGI->creh->creatures[creatures[i].ID].faction],curx-50,pos.y+130-65);
SDL_Rect dst = genRect(130,100,curx-50,pos.y+130-65);
creatures[i].anim->nextFrameMiddle(screen,curx+20,pos.y+110,true,!(c%2),false,&dst);
creatures[i].pic->blitPic(screen,curx-50,pos.y+130-65,!(c%2));
curx += 120;
}
c++;
}
CRecrutationWindow::CRecrutationWindow(std::vector<std::pair<int,int> > &Creatures, IRecruit *irec) //creatures - pairs<creature_ID,amount>
:rec(irec)
CRecrutationWindow::CRecrutationWindow(const std::vector<std::pair<int,int> > &Creatures, const boost::function<void(int,int)> &Recruit) //creatures - pairs<creature_ID,amount>
:recruit(Recruit)
{
which = 0;
creatures.resize(Creatures.size());
@ -2782,7 +2802,7 @@ CRecrutationWindow::CRecrutationWindow(std::vector<std::pair<int,int> > &Creatur
for(int j=0;j<CGI->creh->creatures[Creatures[i].first].cost.size();j++)
if(CGI->creh->creatures[Creatures[i].first].cost[j])
creatures[i].res.push_back(std::make_pair(j,CGI->creh->creatures[Creatures[i].first].cost[j]));
creatures[i].anim = new CCreatureAnimation(CGI->creh->creatures[Creatures[i].first].animDefName);
creatures[i].pic = new CCreaturePic(&CGI->creh->creatures[Creatures[i].first]);
amounts[i] = CGI->creh->creatures[Creatures[i].first].maxAmount(LOCPLINT->cb->getResourceAmount());
}
SDL_Surface *hhlp = CGI->bitmaph->loadBitmap("TPRCRT.bmp");
@ -2832,6 +2852,13 @@ CRecrutationWindow::CRecrutationWindow(std::vector<std::pair<int,int> > &Creatur
}//(int x, int y, int totalw, T*Owner,void(T::*Moved)(int to), int Capacity, int Amount, int Value, bool Horizontal)
CRecrutationWindow::~CRecrutationWindow()
{
for(int i=0;i<creatures.size();i++)
{
delete creatures[i].pic;
}
delete max;
delete buy;
delete cancel;
SDL_FreeSurface(bitmap);
delete slider;
}
@ -2852,8 +2879,8 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner)
slider = new CSlider(pos.x+21,pos.y+194,257,boost::bind(&CSplitWindow::sliderMoved,this,_1),1,max,0,true);
a1 = max;
a2 = 0;
anim = new CCreatureAnimation(CGI->creh->creatures[cid].animDefName);
anim->setType(1);
anim = new CCreaturePic(&CGI->creh->creatures[cid]);
anim->anim->setType(1);
std::string title = CGI->generaltexth->allTexts[256];
boost::algorithm::replace_first(title,"%s",CGI->creh->creatures[cid].namePl);
@ -2862,6 +2889,10 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner)
CSplitWindow::~CSplitWindow()
{
SDL_FreeSurface(bitmap);
delete ok;
delete cancel;
delete slider;
delete anim;
}
void CSplitWindow::activate()
{
@ -2910,27 +2941,20 @@ void CSplitWindow::show(SDL_Surface * to)
printAtMiddle(pom,pos.x+70,pos.y+237,GEOR16,zwykly,screen);
itoa(a2,pom,10);
printAtMiddle(pom,pos.x+233,pos.y+237,GEOR16,zwykly,screen);
blitAt(CGI->creh->backgrounds[CGI->creh->creatures[c].faction],pos.x+20,pos.y+54);
anim->nextFrameMiddle(screen,pos.x+20+70,pos.y+54+55,true,false,false);
blitAt(CGI->creh->backgrounds[CGI->creh->creatures[c].faction],pos.x+177,pos.y+54);
anim->nextFrameMiddle(screen,pos.x+177+70,pos.y+54+55,true,false,false);
anim->blitPic(screen,pos.x+20,pos.y+54,false);
anim->blitPic(screen,pos.x+177,pos.y+54,false);
}
void CSplitWindow::keyPressed (SDL_KeyboardEvent & key)
{
//TODO: zeby sie dalo recznie wpisywac
//TODO: make manual typing possible
}
void CCreInfoWindow::show(SDL_Surface * to)
{
char pom[15];
blitAt(bitmap,pos.x,pos.y,screen);
blitAt(CGI->creh->backgrounds[c->faction],pos.x+21,pos.y+48,screen);
anim->nextFrameMiddle(screen,pos.x+90,pos.y+95,true,false,false);
anim->blitPic(screen,pos.x+21,pos.y+48,(type) && anf);
anf=!anf;
if(upgrade)
upgrade->show();
if(dismiss)
@ -2951,8 +2975,8 @@ CCreInfoWindow::CCreInfoWindow
pos.h = bitmap->h;
blueToPlayersAdv(bitmap,LOCPLINT->playerID);
SDL_SetColorKey(bitmap,SDL_SRCCOLORKEY,SDL_MapRGB(bitmap->format,0,255,255));
anim = new CCreatureAnimation(c->animDefName);
anim->setType(1);
anim = new CCreaturePic(c);
if(!type) anim->anim->setType(1);
char pom[25];int hlp=0;
printAtMiddle(c->namePl,149,30,GEOR13,zwykly,bitmap); //creature name
@ -3034,9 +3058,13 @@ CCreInfoWindow::~CCreInfoWindow()
{
SDL_FreeSurface(bitmap);
delete anim;
delete upgrade;
delete ok;
delete dismiss;
}
void CCreInfoWindow::activate()
{
if(!type)
ClickableR::activate();
LOCPLINT->objsToBlit.push_back(this);
if(ok)
@ -3074,6 +3102,7 @@ void CCreInfoWindow::keyPressed (SDL_KeyboardEvent & key)
}
void CCreInfoWindow::deactivate()
{
if(!type)
ClickableR::deactivate();
LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
if(ok)

View File

@ -449,10 +449,15 @@ public:
void draw();
};
class IRecruit
class CCreaturePic //draws 100x130 picture with creature on background, use nextFrame=true to get animation
{
public:
virtual void recruit(int ID, int amount)=0;
CCreature *c;
CCreatureAnimation *anim;
CCreaturePic(CCreature *cre);
~CCreaturePic();
int blitPic(SDL_Surface *to, int x, int y, bool nextFrame);
SDL_Surface * getPic(bool nextFrame);
};
class CRecrutationWindow : public IShowable, public ClickableL
@ -461,13 +466,13 @@ public:
struct creinfo
{
SDL_Rect pos;
CCreaturePic *pic;
int ID, amount; //creature ID and available amount
CCreatureAnimation *anim;
std::vector<std::pair<int,int> > res; //res_id - cost_per_unit
};
std::vector<int> amounts; //how many creatures we can afford
std::vector<creinfo> creatures;
IRecruit *rec;
boost::function<void(int,int)> recruit; //void (int ID, int amount) <-- call to recruit creatures
CSlider *slider;
AdventureMapButton *max, *buy, *cancel;
SDL_Surface *bitmap;
@ -482,7 +487,7 @@ public:
void activate();
void deactivate();
void show(SDL_Surface * to = NULL);
CRecrutationWindow(std::vector<std::pair<int,int> > & Creatures, IRecruit *irec); //creatures - pairs<creature_ID,amount>
CRecrutationWindow(const std::vector<std::pair<int,int> > & Creatures, const boost::function<void(int,int)> & Recruit); //creatures - pairs<creature_ID,amount>
~CRecrutationWindow();
};
@ -491,7 +496,7 @@ class CSplitWindow : public IShowable, public KeyInterested
public:
CGarrisonInt *gar;
CSlider *slider;
CCreatureAnimation *anim;
CCreaturePic *anim;
AdventureMapButton *ok, *cancel;
SDL_Surface *bitmap;
int a1, a2, c;
@ -513,9 +518,10 @@ class CCreInfoWindow : public IShowable, public KeyInterested, public ClickableR
public:
int type;//0 - rclick popup; 1 - normal window
SDL_Surface *bitmap;
bool anf;
boost::function<void()> dsm;
CCreatureAnimation *anim;
CCreaturePic *anim;
CCreature *c;
AdventureMapButton *dismiss, *upgrade, *ok;