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

Golems Factory and Elemental Conflux creature generators supported. Minor improvements. Updated changelog.

This commit is contained in:
Michał W. Urbańczyk 2009-07-26 10:43:22 +00:00
parent 9fd4b5bb62
commit e358845873
12 changed files with 152 additions and 75 deletions

View File

@ -83,7 +83,7 @@ public:
virtual void init(ICallback * CB){};
virtual void receivedResource(int type, int val){};
virtual void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID){};
virtual void showRecruitmentDialog(const CGDwelling *dwelling, int level){}
virtual void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level){}
virtual void showShipyardDialog(const IShipyard *obj){} //obj may be town or shipyard; state: 0 - can buid, 1 - lack of resources, 2 - dest tile is blocked, 3 - no water
//virtual void showSelDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
//virtual void showYesNoDialog(const std::string &text, const std::vector<Component*> &components, ui32 askID){};
@ -93,7 +93,7 @@ public:
virtual void tileRevealed(const std::set<int3> &pos){};
virtual void newObject(const CGObjectInstance * obj){}; //eg. ship built in shipyard
virtual void yourTurn(){};
virtual void availableCreaturesChanged(const CGTownInstance *town){};
virtual void availableCreaturesChanged(const CGDwelling *town){};
virtual void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain){};//if gain hero received bonus, else he lost it
virtual void requestRealized(PackageApplied *pa){};
virtual void heroExchangeStarted(si32 hero1, si32 hero2){};

View File

@ -1,4 +1,4 @@
0.72 -> 0.73
0.72 -> 0.73 (scheguled on 1 Sep) as for r1044
GENERAL:
* infowindow popup will be completely on screen
* fixed possible crash with in game console
@ -16,6 +16,11 @@ GENERAL:
* corrected some exp/level values
* primary skills cannot be negative
* support for 3 new artifacts: Ring of Vitality, Ring of Life, Vial of Lifeblood
* fixed timed events reappearing
* saving system options
* saving hero direction
* r-click popups on enemy heroes and towns
* hero leveling formula matches the H3
ADVENTURE INTERFACE:
* Garrisoning, then removing hero from garrison move him at the end of the heroes list
@ -29,7 +34,17 @@ BATTLES:
* number of units in stack in battle should now fit the box
* non-living and undead creatures have now always 0 morale
* partial handling of advmap objects changing battle background (like clover field) (their existence should change the background but nothing else)
* fixed displaying luck effect animation
* displaying luck effect animation
* support for battleground overlays:
- cursed ground
- magic plains
- fiery fields
- rock lands
- magic clouds
- lucid pools
- holy ground
- clover field
- evil fog
TOWNS:
* fixes for horde buildings
@ -39,6 +54,7 @@ TOWNS:
HERO WINDOW:
* garrisoned heroes won't be shown on the list
* artifacts will be present on morale/luck bonuses list
PREGAME:
* saves are sorted primary by map format, secondary by name
@ -46,9 +62,18 @@ PREGAME:
OBJECTS:
* Fixed primary/secondary skill levels given by a scholar.
* fixed crash when there was flaggable building next to map edge
* partial support for adventure map creature dwellings
* fixed problems with 3-tiles monoliths
* fixed crash with flaggable building next to map edge
* fixed some descriptions for events
* New objects supported:
- Buoy
- Creature Generators
- Flotsam
- Mermaid
- Ocean bottle
- Sea Chest
- Shipwreck Survivor
- Sirens
0.71 -> 0.72 (Jun 1 2009)
GENERAL:

View File

@ -968,15 +968,16 @@ CRecruitmentWindow * CCastleInterface::showRecruitmentWindow( int building )
int level = building-30;
assert(level >= 0 && level <= 6);
std::vector<std::pair<int,int > > crs;
int amount = town->creatures[level].first;
//std::vector<std::pair<int,int > > crs;
//int amount = town->creatures[level].first;
const std::vector<ui32> &cres = town->creatures[level].second;
//const std::vector<ui32> &cres = town->creatures[level].second;
for(size_t i = 0; i < cres.size(); i++)
crs.push_back(std::make_pair((int)cres[i],amount));
//for(size_t i = 0; i < cres.size(); i++)
// crs.push_back(std::make_pair((int)cres[i],amount));
//CRecruitmentWindow *rw = new CRecruitmentWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
CRecruitmentWindow *rw = new CRecruitmentWindow(crs,boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
CRecruitmentWindow *rw = new CRecruitmentWindow(town, level, town, boost::bind(&CCallback::recruitCreatures,LOCPLINT->cb,town,_1,_2));
LOCPLINT->pushInt(rw);
return rw;
}

View File

@ -1500,15 +1500,21 @@ void CPlayerInterface::updateWater()
}
void CPlayerInterface::availableCreaturesChanged( const CGTownInstance *town )
void CPlayerInterface::availableCreaturesChanged( const CGDwelling *town )
{
boost::unique_lock<boost::recursive_mutex> un(*pim);
if(castleInt)
if(castleInt && town->ID == TOWNI_TYPE)
{
CFortScreen *fs = dynamic_cast<CFortScreen*>(listInt.front());
if(fs)
fs->draw(castleInt,false);
}
else if(listInt.size() && (town->ID == 17 || town->ID == 20)) //external dwelling
{
CRecruitmentWindow *crw = dynamic_cast<CRecruitmentWindow*>(listInt.front());
if(crw)
crw->initCres();
}
}
void CPlayerInterface::heroBonusChanged( const CGHeroInstance *hero, const HeroBonus &bonus, bool gain )
@ -1723,18 +1729,11 @@ const CGHeroInstance * CPlayerInterface::getWHero( int pos )
return wanderingHeroes[pos];
}
void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, int level)
void CPlayerInterface::showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level)
{
waitWhileDialog();
boost::unique_lock<boost::recursive_mutex> un(*pim);
std::vector<std::pair<int,int> > cres;
for(int i = 0; i < dwelling->creatures.size(); i++)
{
if(i == level || level < 0)
for(size_t j = 0; j < dwelling->creatures[i].second.size(); j++)
cres.push_back( std::make_pair(dwelling->creatures[i].second[j],dwelling->creatures[i].first));
}
CRecruitmentWindow *cr = new CRecruitmentWindow(cres, boost::bind(&CCallback::recruitCreatures, cb, dwelling, _1, _2));
CRecruitmentWindow *cr = new CRecruitmentWindow(dwelling, level, dst, boost::bind(&CCallback::recruitCreatures, cb, dwelling, _1, _2));
pushInt(cr);
}

View File

@ -162,7 +162,7 @@ public:
void heroVisitsTown(const CGHeroInstance* hero, const CGTownInstance * town);
void receivedResource(int type, int val);
void showInfoDialog(const std::string &text, const std::vector<Component*> &components, int soundID);
void showRecruitmentDialog(const CGDwelling *dwelling, int level);
void showRecruitmentDialog(const CGDwelling *dwelling, const CArmedInstance *dst, int level);
void showShipyardDialog(const IShipyard *obj); //obj may be town or shipyard;
void showBlockingDialog(const std::string &text, const std::vector<Component> &components, ui32 askID, int soundID, bool selection, bool cancel); //Show a dialog, player must take decision. If selection then he has to choose between one of given components, if cancel he is allowed to not choose. After making choice, CCallback::selectionMade should be called with number of selected component (1 - n) or 0 for cancel (if allowed) and askID.
void showGarrisonDialog(const CArmedInstance *up, const CGHeroInstance *down, boost::function<void()> &onEnd);
@ -170,7 +170,7 @@ public:
void tileRevealed(const std::set<int3> &pos); //called when fog of war disappears from given tiles
void newObject(const CGObjectInstance * obj);
void yourTurn();
void availableCreaturesChanged(const CGTownInstance *town);
void availableCreaturesChanged(const CGDwelling *town);
void heroBonusChanged(const CGHeroInstance *hero, const HeroBonus &bonus, bool gain);//if gain hero received bonus, else he lost it
void requestRealized(PackageApplied *pa);
void heroExchangeStarted(si32 hero1, si32 hero2);

View File

@ -1588,7 +1588,7 @@ void CTownList::draw(SDL_Surface * to)
}
CCreaturePic::CCreaturePic(CCreature *cre, bool Big)
CCreaturePic::CCreaturePic(const CCreature *cre, bool Big)
:c(cre),big(Big)
{
anim = new CCreatureAnimation(cre->animDefName);
@ -1629,8 +1629,12 @@ void CRecruitmentWindow::Max()
}
void CRecruitmentWindow::Buy()
{
recruit(creatures[which].ID,slider->value);
close();
recruit(creatures[which].ID, slider->value);
if(level >= 0)
close();
else
slider->moveTo(0);
}
void CRecruitmentWindow::Cancel()
{
@ -1654,25 +1658,25 @@ void CRecruitmentWindow::clickLeft(tribool down)
slider->moveTo(newAmount);
else
slider->moveTo(slider->value);
curx = 192 + 51 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
curx = 192 + 51 - (102*creatures.size()/2) - (13*(creatures.size()-1)/2);
for(int j=0;j<creatures.size();j++)
{
if(which==j)
drawBorder(bitmap,curx,64,102,132,int3(255,0,0));
else
drawBorder(bitmap,curx,64,102,132,int3(239,215,123));
curx += 120;
curx += 115;
}
break;
}
curx += 120;
curx += 115;
}
}
void CRecruitmentWindow::clickRight( boost::logic::tribool down )
{
if(down)
{
int curx = 192 + 51 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
int curx = 192 + 51 - (102*creatures.size()/2) - (13*(creatures.size()-1)/2);
for(int i=0;i<creatures.size();i++)
{
if(isItIn(&genRect(132,102,pos.x+curx,pos.y+64),LOCPLINT->current->motion.x,LOCPLINT->current->motion.y))
@ -1681,7 +1685,7 @@ void CRecruitmentWindow::clickRight( boost::logic::tribool down )
LOCPLINT->pushInt(popup);
break;
}
curx += 120;
curx += 115;
}
}
}
@ -1735,35 +1739,24 @@ void CRecruitmentWindow::show(SDL_Surface * to)
curx+=32;
}
curx = pos.x + 192 + 102 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
curx = pos.x + 192 + 102 - (102*creatures.size()/2) - (13*(creatures.size()-1)/2);
for(int i=0; i<creatures.size(); ++i)
{
creatures[i].pic->blitPic(to, curx-50, pos.y+130-65, !(animCounter%4));
curx += 120;
curx += 115;
}
++animCounter;
bar->show(to);
}
CRecruitmentWindow::CRecruitmentWindow(const std::vector<std::pair<int,int> > &Creatures, const boost::function<void(int,int)> &Recruit) //creatures - pairs<creature_ID,amount>
:recruit(Recruit), which(Creatures.size()-1)
CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> &Recruit)
:recruit(Recruit), dwelling(Dwelling), dst(Dst), level(Level)
{
creatures.resize(Creatures.size());
amounts.resize(Creatures.size());
for(int i=0;i<creatures.size();i++)
{
creatures[i].amount = Creatures[i].second;
creatures[i].ID = Creatures[i].first;
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].pic = new CCreaturePic(&CGI->creh->creatures[Creatures[i].first]);
amounts[i] = CGI->creh->creatures[Creatures[i].first].maxAmount(LOCPLINT->cb->getResourceAmount());
}
which = 0;
SDL_Surface *hhlp = BitmapHandler::loadBitmap("TPRCRT.bmp");
graphics->blueToPlayersAdv(hhlp,LOCPLINT->playerID);
bitmap = SDL_ConvertSurface(hhlp,screen->format,0); //na 8bitowej mapie by sie psulo //it wouldn't work on 8bpp map
bitmap = SDL_ConvertSurface(hhlp,screen->format,0);
SDL_SetColorKey(bitmap,SDL_SRCCOLORKEY,SDL_MapRGB(bitmap->format,0,255,255));
SDL_FreeSurface(hhlp);
pos.x = screen->w/2 - bitmap->w/2;
@ -1774,8 +1767,10 @@ CRecruitmentWindow::CRecruitmentWindow(const std::vector<std::pair<int,int> > &C
max = new AdventureMapButton(CGI->generaltexth->zelp[553],boost::bind(&CRecruitmentWindow::Max,this),pos.x+134,pos.y+313,"IRCBTNS.DEF",SDLK_m);
buy = new AdventureMapButton(CGI->generaltexth->zelp[554],boost::bind(&CRecruitmentWindow::Buy,this),pos.x+212,pos.y+313,"IBY6432.DEF",SDLK_RETURN);
cancel = new AdventureMapButton(CGI->generaltexth->zelp[555],boost::bind(&CRecruitmentWindow::Cancel,this),pos.x+290,pos.y+313,"ICN6432.DEF",SDLK_ESCAPE);
slider = new CSlider(pos.x+176,pos.y+279,135,boost::bind(&CRecruitmentWindow::sliderMoved,this, _1),1,std::min(amounts[0],creatures[0].amount),0,true);
std::string pom;
slider = new CSlider(pos.x+176,pos.y+279,135,boost::bind(&CRecruitmentWindow::sliderMoved,this, _1),1,0,0,true);
initCres();
printAtMiddle(CGI->generaltexth->allTexts[346],113,231,GEOR13,zwykly,bitmap); //cost per troop t
printAtMiddle(CGI->generaltexth->allTexts[465],205,231,GEOR13,zwykly,bitmap); //available t
printAtMiddle(CGI->generaltexth->allTexts[16],279,231,GEOR13,zwykly,bitmap); //recruit t
@ -1789,7 +1784,7 @@ CRecruitmentWindow::CRecruitmentWindow(const std::vector<std::pair<int,int> > &C
drawBorder(bitmap,289,312,66,34,int3(173,142,66));
//border for creatures
int curx = 192 + 51 - (102*creatures.size()/2) - (18*(creatures.size()-1)/2);
int curx = 192 + 51 - (102*creatures.size()/2) - (13*(creatures.size()-1)/2);
for(int i=0;i<creatures.size();i++)
{
creatures[i].pos.x = curx+1;
@ -1800,7 +1795,7 @@ CRecruitmentWindow::CRecruitmentWindow(const std::vector<std::pair<int,int> > &C
drawBorder(bitmap,curx,64,102,132,int3(255,0,0));
else
drawBorder(bitmap,curx,64,102,132,int3(239,215,123));
curx += 120;
curx += 115;
}
if(!creatures[0].amount || !amounts[0])
@ -1813,10 +1808,7 @@ CRecruitmentWindow::CRecruitmentWindow(const std::vector<std::pair<int,int> > &C
CRecruitmentWindow::~CRecruitmentWindow()
{
for(int i=0;i<creatures.size();i++)
{
delete creatures[i].pic;
}
cleanCres();
delete max;
delete buy;
delete cancel;
@ -1825,6 +1817,44 @@ CRecruitmentWindow::~CRecruitmentWindow()
delete bar;
}
void CRecruitmentWindow::initCres()
{
cleanCres();
for(int i=0; i<dwelling->creatures.size(); i++)
{
if(level >= 0 && i != level)
continue;
for(int j = dwelling->creatures[i].second.size() - 1; j >= 0 ; j--)
{
creatures.resize(creatures.size()+1);
creinfo &cur = creatures.back();
cur.amount = dwelling->creatures[i].first;
cur.ID = dwelling->creatures[i].second[j];
const CCreature *cre = &CGI->creh->creatures[cur.ID];
cur.pic = new CCreaturePic(cre);
for(int k=0; k<cre->cost.size(); k++)
if(cre->cost[k])
cur.res.push_back(std::make_pair(k,cre->cost[k]));
amounts.push_back(cre->maxAmount(LOCPLINT->cb->getResourceAmount()));
}
}
slider->amount = std::min(amounts[which],creatures[which].amount);
}
void CRecruitmentWindow::cleanCres()
{
for(int i=0;i<creatures.size();i++)
{
delete creatures[i].pic;
}
creatures.clear();
amounts.clear();
}
CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int val)
{
last = Last;

View File

@ -45,6 +45,7 @@ class CCreatureAnimation;
class CSelectableComponent;
class CCreatureSet;
class CGObjectInstance;
class CGDwelling;
class CSlider;
struct UpgradeInfo;
template <typename T> struct CondSh;
@ -314,10 +315,10 @@ public:
class CCreaturePic //draws picture with creature on background, use nextFrame=true to get animation
{
public:
CCreature *c; //which creature's picture
const CCreature *c; //which creature's picture
bool big; //big => 100x130; !big => 100x120
CCreatureAnimation *anim; //displayed animation
CCreaturePic(CCreature *cre, bool Big=true); //c-tor
CCreaturePic(const CCreature *cre, bool Big=true); //c-tor
~CCreaturePic(); //d-tor
int blitPic(SDL_Surface *to, int x, int y, bool nextFrame); //prints creature on screen
SDL_Surface * getPic(bool nextFrame); //returns frame of animation
@ -342,6 +343,10 @@ public:
CStatusBar *bar;
int which; //which creature is active
const CGDwelling *dwelling;
int level;
const CArmedInstance *dst;
void close();
void Max();
void Buy();
@ -352,7 +357,9 @@ public:
void activate();
void deactivate();
void show(SDL_Surface * to);
CRecruitmentWindow(const std::vector<std::pair<int,int> > & Creatures, const boost::function<void(int,int)> & Recruit); //creatures - pairs<creature_ID,amount> //c-tor
void cleanCres();
void initCres();
CRecruitmentWindow(const CGDwelling *Dwelling, int Level, const CArmedInstance *Dst, const boost::function<void(int,int)> & Recruit); //creatures - pairs<creature_ID,amount> //c-tor
~CRecruitmentWindow(); //d-tor
};

View File

@ -204,9 +204,9 @@ void NewStructures::applyCl( CClient *cl )
void SetAvailableCreatures::applyCl( CClient *cl )
{
CGTownInstance *t = GS(cl)->getTown(tid);
if(vstd::contains(cl->playerint,t->tempOwner))
cl->playerint[t->tempOwner]->availableCreaturesChanged(t);
const CGDwelling *dw = static_cast<const CGDwelling*>(cl->getObj(tid));
if(vstd::contains(cl->playerint,dw->tempOwner))
cl->playerint[dw->tempOwner]->availableCreaturesChanged(dw);
}
void SetHeroesInTown::applyCl( CClient *cl )
@ -484,9 +484,11 @@ void OpenWindow::applyCl(CClient *cl)
}
break;
case RECRUITMENT_FIRST:
case RECRUITMENT_ALL:
{
const CGDwelling *dw = dynamic_cast<const CGDwelling*>(cl->getObj(id1));
INTERFACE_CALL_IF_PRESENT(dw->tempOwner,showRecruitmentDialog, dw, 0);
const CArmedInstance *dst = dynamic_cast<const CArmedInstance*>(cl->getObj(id2));
INTERFACE_CALL_IF_PRESENT(dw->tempOwner,showRecruitmentDialog, dw, dst, window == RECRUITMENT_FIRST ? 0 : -1);
}
break;
case SHIPYARD_WINDOW:

View File

@ -979,19 +979,25 @@ void CGDwelling::initObj()
case 20:
creatures.resize(4);
if(subID == 0) // Elemental Conflux
if(subID == 1) //Golem Factory
{
creatures[0].second.push_back(32); //Stone Golem
creatures[1].second.push_back(33); //Iron Golem
creatures[2].second.push_back(116); //Gold Golem
creatures[3].second.push_back(117); //Diamond Golem
//guards
army.slots[0].first = 116;
army.slots[0].second = VLC->creh->creatures[116].getRandomAmount(ran);
}
else if(subID == 1) //Golem Factory
else if(subID == 0) // Elemental Conflux
{
creatures[0].second.push_back(112); //Air Elemental
creatures[1].second.push_back(113); //Earth Elemental
creatures[2].second.push_back(114); //Fire Elemental
creatures[3].second.push_back(115); //Water Elemental
//guards
army.slots[0].first = 113;
army.slots[0].second = VLC->creh->creatures[113].getRandomAmount(ran);
}
else
{
@ -1014,9 +1020,9 @@ void CGDwelling::onHeroVisit( const CGHeroInstance * h ) const
bd.player = h->tempOwner;
bd.flags = BlockingDialog::ALLOW_CANCEL;
bd.text.addTxt(MetaString::GENERAL_TXT, 421); //Much to your dismay, the %s is guarded by %s %s. Do you wish to fight the guards?
bd.text.addReplacement(MetaString::CREGENS, subID);
bd.text.addReplacement(ID == 17 ? MetaString::CREGENS : MetaString::CREGENS4, subID);
bd.text.addReplacement(MetaString::ARRAY_TXT, 176 + CCreature::getQuantityID(army.slots.begin()->second.second)*3);
bd.text.addReplacement(MetaString::CRE_PL_NAMES, creatures[0].second[0]);
bd.text.addReplacement(MetaString::CRE_PL_NAMES, army.slots.begin()->second.first);
cb->showBlockingDialog(&bd, boost::bind(&CGDwelling::wantsFight, this, h, _1));
return;
}
@ -1110,12 +1116,14 @@ void CGDwelling::heroAcceptsCreatures( const CGHeroInstance *h, ui32 answer ) co
cb->sendAndApply(&iw);
}
}
else if(ID == 17)
else
{
OpenWindow ow;
ow.id1 = id;
ow.id2 = id;
ow.window = OpenWindow::RECRUITMENT_FIRST;
ow.id2 = h->id;
ow.window = ID == 17
? OpenWindow::RECRUITMENT_FIRST
: OpenWindow::RECRUITMENT_ALL;
cb->sendAndApply(&ow);
}
}

View File

@ -141,6 +141,9 @@ void MetaString::getLocalString(const std::pair<ui8,ui32> &txt, std::string &dst
case CREGENS:
vec = &VLC->generaltexth->creGens;
break;
case CREGENS4:
vec = &VLC->generaltexth->creGens4;
break;
case ADVOB_TXT:
vec = &VLC->generaltexth->advobtxt;
break;

View File

@ -73,7 +73,7 @@ private:
enum EMessage {TEXACT_STRING, TLOCAL_STRING, TNUMBER, TREPLACE_ESTRING, TREPLACE_LSTRING, TREPLACE_NUMBER};
public:
enum {GENERAL_TXT=1, XTRAINFO_TXT, OBJ_NAMES, RES_NAMES, ART_NAMES, ARRAY_TXT, CRE_PL_NAMES, CREGENS, MINE_NAMES,
MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES};
MINE_EVNTS, ADVOB_TXT, ART_EVNTS, SPELL_NAME, SEC_SKILL_NAME, CRE_SING_NAMES, CREGENS4};
std::vector<ui8> message; //vector of EMessage

View File

@ -350,7 +350,9 @@ DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
DLL_EXPORT void SetAvailableCreatures::applyGs( CGameState *gs )
{
gs->getTown(tid)->creatures = creatures;
CGDwelling *dw = dynamic_cast<CGDwelling*>(gs->map->objects[tid]);
assert(dw);
dw->creatures = creatures;
}
DLL_EXPORT void SetHeroesInTown::applyGs( CGameState *gs )