1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-12 02:28:11 +02:00

Mostly working building and requirements

This commit is contained in:
Michał W. Urbańczyk 2008-03-23 01:01:17 +00:00
parent f5cd675c6a
commit ac82c2fe5a
6 changed files with 201 additions and 75 deletions

View File

@ -523,13 +523,15 @@ bool CCallback::buildBuilding(const CGTownInstance *town, int buildingID)
{
CGTownInstance * t = const_cast<CGTownInstance *>(town);
CBuilding *b = CGI->buildh->buildings[t->subID][buildingID];
//TODO: check if we are allowed to build
if(0/*not allowed*/)//TODO: check if we are allowed to build
return false;
t->builtBuildings.insert(buildingID);
for(int i=0;i<7;i++)
gs->players[player].resources[i]-=b->resources[i];
t->builded++;
CGI->playerint[CGI->state->players[player].serial]->buildChanged(town,buildingID,1);
return true;
}

View File

@ -13,7 +13,7 @@
#include "hch/CGeneralTextHandler.h"
extern TTF_Font * GEOR16;
CBuildingRect::CBuildingRect(Structure *Str)
:str(Str)
:str(Str), moi(false)
{
def = CGI->spriteh->giveDef(Str->defName);
pos.x = str->pos.x;
@ -48,12 +48,16 @@ void CBuildingRect::activate()
Hoverable::activate();
ClickableL::activate();
ClickableR::activate();
}
void CBuildingRect::deactivate()
{
Hoverable::deactivate();
ClickableL::deactivate();
ClickableR::deactivate();
if(moi)
MotionInterested::deactivate();
moi=false;
}
bool CBuildingRect::operator<(const CBuildingRect & p2) const
{
@ -67,11 +71,15 @@ void CBuildingRect::hover(bool on)
Hoverable::hover(on);
if(on)
{
MotionInterested::activate();
if(!moi)
MotionInterested::activate();
moi = true;
}
else
{
MotionInterested::deactivate();
if(moi)
MotionInterested::deactivate();
moi = false;
if(LOCPLINT->castleInt->hBuild == this)
{
LOCPLINT->castleInt->hBuild = NULL;
@ -214,60 +222,10 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, bool Activate)
CSDL_Ext::blueToPlayersAdv(townInt,LOCPLINT->playerID);
exit->bitmapOffset = 4;
std::set< std::pair<int,int> > s; //group - id
//buildings
for (std::set<int>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
{
if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
{
if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
{
Structure * st = CGI->townh->structures[town->subID][*i];
if(st->group<0) //no group - just add it
{
buildings.push_back(new CBuildingRect(st));
}
else
{
std::set< std::pair<int,int> >::iterator obecny=s.end();
for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
{
if(seti->first == st->group)
{
obecny = seti;
break;
}
}
if(obecny != s.end())
{
if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
{
for(int itpb = 0; itpb<buildings.size(); itpb++)
{
if(buildings[itpb]->str->ID == obecny->second)
{
delete buildings[itpb];
buildings.erase(buildings.begin() + itpb);
obecny->second = st->ID;
buildings.push_back(new CBuildingRect(st));
}
}
}
}
else
{
buildings.push_back(new CBuildingRect(st));
s.insert(std::pair<int,int>(st->group,st->ID));
}
}
}
else continue;
}
else
break;
}
recreateBuildings();
//garrison
@ -511,6 +469,83 @@ void CCastleInterface::deactivate()
buildings[i]->deactivate();
}
void CCastleInterface::addBuilding(int bid)
{
//TODO: lepiej by bylo tylko dodawac/usuwac co trzeba pamietajac o grupach
recreateBuildings();
}
void CCastleInterface::removeBuilding(int bid)
{
//TODO: lepiej by bylo tylko dodawac/usuwac co trzeba pamietajac o grupach
recreateBuildings();
}
void CCastleInterface::recreateBuildings()
{
for(int i=0;i<buildings.size();i++)
{
if(showing)
buildings[i]->deactivate();
delete buildings[i];
}
buildings.clear();
hBuild = NULL;
std::set< std::pair<int,int> > s; //group - id
for (std::set<int>::const_iterator i=town->builtBuildings.begin();i!=town->builtBuildings.end();i++)
{
if(CGI->townh->structures.find(town->subID) != CGI->townh->structures.end()) //we have info about structures in this town
{
if(CGI->townh->structures[town->subID].find(*i)!=CGI->townh->structures[town->subID].end()) //we have info about that structure
{
Structure * st = CGI->townh->structures[town->subID][*i];
if(st->group<0) //no group - just add it
{
buildings.push_back(new CBuildingRect(st));
}
else
{
std::set< std::pair<int,int> >::iterator obecny=s.end();
for(std::set< std::pair<int,int> >::iterator seti = s.begin(); seti!=s.end(); seti++) //check if we have already building from same group
{
if(seti->first == st->group)
{
obecny = seti;
break;
}
}
if(obecny != s.end())
{
if((*(CGI->townh->structures[town->subID][obecny->second])) < (*(CGI->townh->structures[town->subID][st->ID]))) //we have to replace old building with current one
{
for(int itpb = 0; itpb<buildings.size(); itpb++)
{
if(buildings[itpb]->str->ID == obecny->second)
{
delete buildings[itpb];
buildings.erase(buildings.begin() + itpb);
obecny->second = st->ID;
buildings.push_back(new CBuildingRect(st));
}
}
}
}
else
{
buildings.push_back(new CBuildingRect(st));
s.insert(std::pair<int,int>(st->group,st->ID));
}
}
}
else continue;
}
else
break;
}
}
void CHallInterface::CResDataBar::show(SDL_Surface * to)
{
@ -600,7 +635,7 @@ void CHallInterface::CBuildingBox::show(SDL_Surface * to)
pom2 = 2;
pom = 2;
break;
case 0: case 5:
case 0: case 5: case 8:
pom2 = 1;
pom = 2;
break;
@ -682,7 +717,7 @@ CHallInterface::CHallInterface(CCastleInterface * owner)
if(owner->town->forbiddenBuildings.find(CGI->buildh->hall[owner->town->subID].second[i][j][k])!=owner->town->forbiddenBuildings.end())
boxes[i][boxes[i].size()-1]->state = 2; //forbidden
else if(owner->town->builded >= MAX_BUILDING_PER_TURN)
boxes[i][boxes[i].size()-1]->state = 5; //already built
boxes[i][boxes[i].size()-1]->state = 5; //building limit
//checking resources
CBuilding * pom = CGI->buildh->buildings[owner->town->subID][CGI->buildh->hall[owner->town->subID].second[i][j][k]];
@ -698,7 +733,7 @@ CHallInterface::CHallInterface(CCastleInterface * owner)
ri++ )
{
if(owner->town->builtBuildings.find(*ri)==owner->town->builtBuildings.end())
boxes[i][boxes[i].size()-1]->state = 5; //lack of requirements - cannot build
boxes[i][boxes[i].size()-1]->state = 8; //lack of requirements - cannot build
}
//TODO: check if capital is already built, check if there is water for shipyard
@ -736,6 +771,7 @@ CHallInterface::~CHallInterface()
void CHallInterface::close()
{
deactivate();
delete this;
LOCPLINT->castleInt->activate();
LOCPLINT->castleInt->showAll();
}
@ -771,22 +807,31 @@ void CHallInterface::deactivate()
void CHallInterface::CBuildWindow::activate()
{
LOCPLINT->objsToBlit.push_back(this);
ClickableR::activate();
if(mode)
return;
buy->activate();
cancel->activate();
ClickableR::activate();
LOCPLINT->objsToBlit.push_back(this);
}
void CHallInterface::CBuildWindow::deactivate()
{
LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
ClickableR::deactivate();
if(mode)
return;
buy->deactivate();
cancel->deactivate();
ClickableR::deactivate();
LOCPLINT->objsToBlit.erase(std::find(LOCPLINT->objsToBlit.begin(),LOCPLINT->objsToBlit.end(),this));
}
void CHallInterface::CBuildWindow::Buy()
{
LOCPLINT->cb->buildBuilding(LOCPLINT->castleInt->town,bid);
close();
deactivate();
delete this;
delete LOCPLINT->castleInt->hallInt;
LOCPLINT->castleInt->hallInt = NULL;
LOCPLINT->castleInt->activate();
LOCPLINT->castleInt->showAll();
}
void CHallInterface::CBuildWindow::close()
{
@ -805,20 +850,70 @@ void CHallInterface::CBuildWindow::show(SDL_Surface * to)
SDL_Rect pom = genRect(bitmap->h-1,bitmap->w-1,pos.x,pos.y);
SDL_Rect poms = pom; poms.x=0;poms.y=0;
SDL_BlitSurface(bitmap,&poms,to?to:ekran,&pom);
buy->show();
cancel->show();
if(!mode)
{
buy->show();
cancel->show();
}
}
std::string getTextForState(int state)
std::string CHallInterface::CBuildWindow::getTextForState(int state)
{
std::string ret;
if(state<7)
return CGI->townh->hcommands[state];
ret = CGI->townh->hcommands[state];
switch (state)
{
case 4:
ret.replace(ret.find_first_of("%s"),2,CGI->buildh->buildings[tid][bid]->name);
break;
case 7:
return CGI->generaltexth->allTexts[219]; //all prereq. are met
default:
return "Error, wrong state!";
case 8:
{
ret = CGI->generaltexth->allTexts[52];
std::set<int> used;
used.insert(bid);
std::set<int> reqs;
for(std::set<int>::iterator i=CGI->townh->requirements[tid][bid].begin();i!=CGI->townh->requirements[tid][bid].end();i++)
if (LOCPLINT->castleInt->town->builtBuildings.find(*i) == LOCPLINT->castleInt->town->builtBuildings.end())
reqs.insert(*i);
while(true)
{
int czystych=0;
for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
{
if(used.find(*i)==used.end()) //we haven't added requirements for this building
{
used.insert(*i);
for(
std::set<int>::iterator j=CGI->townh->requirements[tid][*i].begin();
j!=CGI->townh->requirements[tid][*i].end();
j++
)
{
if(LOCPLINT->castleInt->town->builtBuildings.find(*j) == //this building is not built
LOCPLINT->castleInt->town->builtBuildings.end())
reqs.insert(*j);
}
}
else
{
czystych++;
}
}
if(czystych==reqs.size())
break;
}
bool first=true;
for(std::set<int>::iterator i=reqs.begin();i!=reqs.end();i++)
{
ret+=(((first)?(" "):(", ")) + CGI->buildh->buildings[tid][*i]->name);
first = false;
}
}
}
return ret;
}
CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mode)
:tid(Tid),bid(Bid),mode(Mode), state(State)
@ -859,13 +954,19 @@ CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mod
if(it==4)
ah+=75;
}
buy = new AdventureMapButton<CBuildWindow>("","",&CBuildWindow::Buy,pos.x+45,pos.y+446,"IBUY30.DEF",this,true,NULL,false);
cancel = new AdventureMapButton<CBuildWindow>("","",&CBuildWindow::close,pos.x+290,pos.y+445,"ICANCEL.DEF",this,true,NULL,false);
if(!mode)
{
buy = new AdventureMapButton<CBuildWindow>("","",&CBuildWindow::Buy,pos.x+45,pos.y+446,"IBUY30.DEF",this,true,NULL,false);
cancel = new AdventureMapButton<CBuildWindow>("","",&CBuildWindow::close,pos.x+290,pos.y+445,"ICANCEL.DEF",this,true,NULL,false);
}
activate();
}
CHallInterface::CBuildWindow::~CBuildWindow()
{
SDL_FreeSurface(bitmap);
delete buy;
delete cancel;
if(!mode)
{
delete buy;
delete cancel;
}
}

View File

@ -11,6 +11,7 @@ template <typename T> class AdventureMapButton;
class CBuildingRect : public Hoverable, public MotionInterested, public ClickableL, public ClickableR//, public TimeInterested
{
public:
bool moi; //motion interested is active
Structure* str;
CDefHandler* def;
SDL_Surface* border;
@ -58,6 +59,9 @@ public:
void splitF();
void activate();
void deactivate();
void addBuilding(int bid);
void removeBuilding(int bid);
void recreateBuildings();
};
class CHallInterface : public IShowable, public IActivable
@ -76,7 +80,7 @@ public:
{
public:
int BID;
int state;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build
int state;// 0 - no more than one capitol, 1 - lack of water, 2 - forbidden, 3 - Add another level to Mage Guild, 4 - already built, 5 - cannot build, 6 - cannot afford, 7 - build, 8 - lack of requirements
//(-1) - forbidden in this town, 0 - possible, 1 - lack of res, 2 - requirements/buildings per turn limit, (3) - already exists
void hover(bool on);
void clickLeft (tribool down);
@ -99,6 +103,7 @@ public:
void activate();
void deactivate();
std::string getTextForState(int state);
void clickRight (tribool down);
void show(SDL_Surface * to=NULL);
void Buy();

View File

@ -41,6 +41,7 @@ public:
virtual void receivedResource(int type, int val){};
virtual void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID)=0{};
virtual void garrisonChanged(const CGObjectInstance * obj){};
virtual void buildChanged(const CGTownInstance *town, int buildingID, int what){}; //what: 1 - built, 2 - demolished
//battle call-ins
virtual void battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, bool side){}; //called by engine when battle starts; side=0 - left, side=1 - right
virtual void battlefieldPrepared(int battlefieldType, std::vector<CObstacle*> obstacles){}; //called when battlefield is prepared, prior the battle beginning

View File

@ -1856,6 +1856,22 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
}
}
}
void CPlayerInterface::buildChanged(const CGTownInstance *town, int buildingID, int what) //what: 1 - built, 2 - demolished
{
if(curint!=castleInt)
return;
if(castleInt->town!=town)
return;
switch(what)
{
case 1:
castleInt->addBuilding(buildingID);
break;
case 2:
castleInt->removeBuilding(buildingID);
break;
}
}
void CPlayerInterface::battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side) //called by engine when battle starts; side=0 - left, side=1 - right
{

View File

@ -308,6 +308,7 @@ public:
void showSelDialog(std::string text, std::vector<CSelectableComponent*> & components, int askID);
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
void garrisonChanged(const CGObjectInstance * obj);
void buildChanged(const CGTownInstance *town, int buildingID, int what); //what: 1 - built, 2 - demolished
//battles
void battleStart(CCreatureSet * army1, CCreatureSet * army2, int3 tile, CGHeroInstance *hero1, CGHeroInstance *hero2, tribool side); //called by engine when battle starts; side=0 - left, side=1 - right