1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-07-17 01:32:21 +02:00

Next part of Creature Banks script, partial support for once visitable objects in towns.

Can't test it anymore due to new major bug in AI library (vector subscript out of range)
This commit is contained in:
DjWarmonger
2009-08-23 15:02:21 +00:00
parent fe2085fe42
commit 23c917f874
6 changed files with 162 additions and 41 deletions

View File

@ -1272,8 +1272,11 @@ void CGDwelling::fightOver(const CGHeroInstance *h, BattleResult *result) const
int CGTownInstance::getSightRadious() const //returns sight distance int CGTownInstance::getSightRadious() const //returns sight distance
{ {
if (subID == 2 && (builtBuildings.find(21))!=builtBuildings.end()) //town has lookout tower if (subID == 2) //tower
return 20; if ((builtBuildings.find(17)) != builtBuildings.end()) //skyship
return cb->getMapSize().first + cb->getMapSize().second;
else if ((builtBuildings.find(21)) != builtBuildings.end()) //lookout tower
return 20;
return 5; return 5;
} }
@ -1427,7 +1430,9 @@ void CGTownInstance::onHeroVisit(const CGHeroInstance * h) const
cb->setOwner(id, h->tempOwner); cb->setOwner(id, h->tempOwner);
} }
} }
cb->heroVisitCastle(id,h->id); for (std::vector<CGTownBuilding>::const_iterator i = bonusingBuildings.begin(); i != bonusingBuildings.end(); i++)
i->onHeroVisit (h);
cb->heroVisitCastle(id, h->id);
} }
void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const void CGTownInstance::onHeroLeave(const CGHeroInstance * h) const
@ -1447,6 +1452,15 @@ void CGTownInstance::initObj()
if(creatureDwelling(i,true)) if(creatureDwelling(i,true))
creatures[i].second.push_back(town->upgradedCreatures[i]); creatures[i].second.push_back(town->upgradedCreatures[i]);
} }
switch (alignment)
{ //add new visitable objects
case 2: case 3: case 5: case 6:
bonusingBuildings.push_back(*new CTownBonus(23, this));
break;
case 7:
bonusingBuildings.push_back(*new CTownBonus(17, this));
break;
}
} }
int3 CGTownInstance::getSightCenter() const int3 CGTownInstance::getSightCenter() const
@ -1793,6 +1807,57 @@ void CGVisitableOPH::schoolSelected(int heroID, ui32 which) const
cb->changePrimSkill(heroID, base + which-1, +1); //give appropriate skill cb->changePrimSkill(heroID, base + which-1, +1); //give appropriate skill
} }
CTownBonus::CTownBonus (int index, CGTownInstance *TOWN)
{
ID = index;
town = TOWN;
}
void CTownBonus::onHeroVisit (const CGHeroInstance * h) const
{
int heroID = h->id;
if ((town->builtBuildings.find(ID) != town->builtBuildings.end()) && (visitors.find(heroID) == visitors.end()))
{
InfoWindow iw;
switch (ID)
{
case 23:
switch(town->alignment)
{
case 2: //wall
cb->changePrimSkill (heroID, 3, 1);
iw.components.push_back (Component(Component::PRIM_SKILL, 3, 1, 0));
break;
case 3: //order of fire
cb->changePrimSkill (heroID, 2, 1);
iw.components.push_back (Component(Component::PRIM_SKILL, 2, 1, 0));
break;
case 6://hall of valhalla
cb->changePrimSkill (heroID, 0, 1);
iw.components.push_back (Component(Component::PRIM_SKILL, 0, 1, 0));
break;
case 5://academy of battle scholars
cb->changePrimSkill (heroID, 4, 1000);
iw.components.push_back (Component(Component::EXPERIENCE, 0, 1000, 0));
break;
}
break;
case 17:
switch(town->alignment)
{
case 7: //cage of warlords
cb->changePrimSkill (heroID, 1, 1);
iw.components.push_back (Component(Component::PRIM_SKILL, 1, 1, 0));
break;
}
break;
}
iw.player = cb->getOwner(heroID);
iw.text << std::pair<ui8,ui32>(11,66);
//iw.soundID = sound;
cb->showInfoDialog(&iw);
cb->setObjProperty (id, 4, h->id); //add to visitors
}
}
bool CArmedInstance::needsLastStack() const bool CArmedInstance::needsLastStack() const
{ {
return false; return false;
@ -3636,6 +3701,7 @@ void CBank::initObj()
bc = NULL; bc = NULL;
daycounter = 0; daycounter = 0;
multiplier = 1; multiplier = 1;
//reset();
} }
void CBank::reset() void CBank::reset()
{ {
@ -3660,7 +3726,10 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
switch (what) switch (what)
{ {
case 11: //daycounter case 11: //daycounter
daycounter++; if (val == 0)
daycounter = 0;
else
daycounter++;
break; break;
case 12: //multiplier case 12: //multiplier
multiplier = ((float)val)/100; multiplier = ((float)val)/100;
@ -3674,6 +3743,9 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
case 15: case 15:
bc = NULL; bc = NULL;
break; break;
case 16:
artifacts.clear();
break;
case 18: //Artifacts case 18: //Artifacts
{ {
std::vector<CArtifact*> arts; std::vector<CArtifact*> arts;
@ -3698,21 +3770,21 @@ void CBank::setPropertyDer (ui8 what, ui32 val)
} }
} }
void CBank::newTurn() void CBank::newTurn() const
{ {
if (bc == NULL) if (bc == NULL)
{ {
if (daycounter >= 28 || cb->getDate(0) == 1) if (daycounter >= 28 || cb->getDate(0) == 1)
{ {
reset(); cb->setObjProperty (id,11,0); //daycounter 0
daycounter = 0; cb->setObjProperty (id,14,0); //reset
if (ID == 24 && cb->getDate(0) > 1) if (ID == 24 && cb->getDate(0) > 1)
{ {
artifacts.clear(); //derelict ships are usable only once cb->setObjProperty (id,16,0);; //derelict ships are usable only once
} }
} }
else else
daycounter++; cb->setObjProperty (id,11,1); //daycounter++
} }
} }
void CBank::onHeroVisit (const CGHeroInstance * h) const void CBank::onHeroVisit (const CGHeroInstance * h) const
@ -3750,10 +3822,23 @@ void CBank::onHeroVisit (const CGHeroInstance * h) const
{ {
InfoWindow iw; InfoWindow iw;
if (ID == 85) if (ID == 85)
iw.components.push_back (Component (Component::MORALE, 0 , -2, 0)); {
iw.components.push_back (Component (Component::MORALE, 0 , -1, 0));
GiveBonus gbonus;
gbonus.hid = h->id;
gbonus.bonus.duration = HeroBonus::ONE_BATTLE;
gbonus.bonus.source = HeroBonus::OBJECT;
gbonus.bonus.id = ID;
gbonus.bdescr << "\n" << VLC->generaltexth->arraytxt[ID];
gbonus.bonus.type = HeroBonus::MORALE;
gbonus.bonus.val = -1;
cb->giveHeroBonus(&gbonus);
}
iw.soundID = soundBase::GRAVEYARD; iw.soundID = soundBase::GRAVEYARD;
iw.player = h->getOwner(); iw.player = h->getOwner();
iw.text.addTxt (MetaString::ADVOB_TXT, 33); std::string desc = VLC->generaltexth->advobtxt[33];
boost::algorithm::replace_first (desc, "%s", VLC->generaltexth->names[ID]);
iw.text << desc;
cb->showInfoDialog(&iw); cb->showInfoDialog(&iw);
} }
} }

View File

@ -36,6 +36,7 @@ class CHero;
class CBuilding; class CBuilding;
class CSpell; class CSpell;
class CGTownInstance; class CGTownInstance;
class CGTownBuilding;
class CArtifact; class CArtifact;
class CGDefInfo; class CGDefInfo;
class CSpecObjInfo; class CSpecObjInfo;
@ -327,6 +328,50 @@ public:
void wantsFight(const CGHeroInstance *h, ui32 answer) const; void wantsFight(const CGHeroInstance *h, ui32 answer) const;
}; };
class DLL_EXPORT CGVisitableOPH : public CGObjectInstance //objects visitable only once per hero
{
public:
std::set<si32> visitors; //ids of heroes who have visited this obj
si8 ttype; //tree type - used only by trees of knowledge: 0 - give level for free; 1 - take 2000 gold; 2 - take 10 gems
const std::string & getHoverText() const;
void setPropertyDer(ui8 what, ui32 val);//synchr
void onHeroVisit(const CGHeroInstance * h) const;
void onNAHeroVisit(int heroID, bool alreadyVisited) const;
void initObj();
void treeSelected(int heroID, int resType, int resVal, ui64 expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog
void schoolSelected(int heroID, ui32 which) const;
void arenaSelected(int heroID, int primSkill) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & visitors & ttype;
}
};
class DLL_EXPORT CGTownBuilding : IObjectInterface
{
///basic class for town structures handled as map objects
public:
CGTownInstance *town;
virtual void onHeroVisit (const CGHeroInstance * h) const {};
};
class DLL_EXPORT CTownBonus : public CGVisitableOPH, public CGTownBuilding
{
///used for one-time bonusing structures
public:
void onHeroVisit (const CGHeroInstance * h) const;
CTownBonus (int index, CGTownInstance *TOWN);
CTownBonus (){ID = 0; town = NULL;};
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & visitors & town;
}
};
class DLL_EXPORT CGTownInstance : public CGDwelling, public IShipyard class DLL_EXPORT CGTownInstance : public CGDwelling, public IShipyard
{ {
public: public:
@ -338,6 +383,7 @@ public:
ui32 identifier; //special identifier from h3m (only > RoE maps) ui32 identifier; //special identifier from h3m (only > RoE maps)
si32 alignment; si32 alignment;
std::set<si32> forbiddenBuildings, builtBuildings; std::set<si32> forbiddenBuildings, builtBuildings;
std::vector<CGTownBuilding> bonusingBuildings;
std::vector<ui32> possibleSpells, obligatorySpells; std::vector<ui32> possibleSpells, obligatorySpells;
std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild std::vector<std::vector<ui32> > spells; //spells[level] -> vector of spells, first will be available in guild
@ -402,29 +448,6 @@ public:
void onHeroLeave(const CGHeroInstance * h) const; void onHeroLeave(const CGHeroInstance * h) const;
void initObj(); void initObj();
}; };
class DLL_EXPORT CGVisitableOPH : public CGObjectInstance //objects visitable only once per hero
{
public:
std::set<si32> visitors; //ids of heroes who have visited this obj
si8 ttype; //tree type - used only by trees of knowledge: 0 - give level for free; 1 - take 2000 gold; 2 - take 10 gems
const std::string & getHoverText() const;
void setPropertyDer(ui8 what, ui32 val);//synchr
void onHeroVisit(const CGHeroInstance * h) const;
void onNAHeroVisit(int heroID, bool alreadyVisited) const;
void initObj();
void treeSelected(int heroID, int resType, int resVal, ui64 expVal, ui32 result) const; //handle player's anwer to the Tree of Knowledge dialog
void schoolSelected(int heroID, ui32 which) const;
void arenaSelected(int heroID, int primSkill) const;
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CGObjectInstance&>(*this);
h & visitors & ttype;
}
};
class DLL_EXPORT CGPandoraBox : public CArmedInstance class DLL_EXPORT CGPandoraBox : public CArmedInstance
{ {
public: public:
@ -853,7 +876,7 @@ class DLL_EXPORT CBank : public CArmedInstance
void initObj(); void initObj();
void setPropertyDer (ui8 what, ui32 val); void setPropertyDer (ui8 what, ui32 val);
void reset(); void reset();
void newTurn(); void newTurn() const;
void onHeroVisit (const CGHeroInstance * h) const; void onHeroVisit (const CGHeroInstance * h) const;
void fightGuards (const CGHeroInstance *h, ui32 accept) const; void fightGuards (const CGHeroInstance *h, ui32 accept) const;
void endBattle (const CGHeroInstance *h, const BattleResult *result) const; void endBattle (const CGHeroInstance *h, const BattleResult *result) const;

View File

@ -127,6 +127,8 @@ void IGameCallback::getAllTiles (std::set<int3> &tiles, int player/*=-1*/, int l
std::vector<int> floors; std::vector<int> floors;
if(level == -1) if(level == -1)
{ {
for (int xd = 0; xd <= gs->map->width - 1; xd++)
for(int b=0; b<gs->map->twoLevel + 1; ++b) //if gs->map->twoLevel is false then false (0) + 1 is 1, if it's true (1) then we have 2 for(int b=0; b<gs->map->twoLevel + 1; ++b) //if gs->map->twoLevel is false then false (0) + 1 is 1, if it's true (1) then we have 2
{ {
floors.push_back(b); floors.push_back(b);
@ -137,14 +139,14 @@ void IGameCallback::getAllTiles (std::set<int3> &tiles, int player/*=-1*/, int l
for (std::vector<int>::const_iterator i = floors.begin(); i!= floors.end(); i++) for (std::vector<int>::const_iterator i = floors.begin(); i!= floors.end(); i++)
{ {
register int zd = *i;
for (int xd = 0; xd < gs->map->width; xd++) for (int xd = 0; xd < gs->map->width; xd++)
{ {
for (int yd = 0; yd < gs->map->height; yd++) for (int yd = 0; yd < gs->map->height; yd++)
{ {
if ( (getTile (int3 (xd,yd,*i))->tertype == 8 && water == true) if ((getTile (int3 (xd,yd,zd))->tertype == 8 && water)
|| (getTile (int3 (xd,yd,*i))->tertype != 8 && land == true) || (getTile (int3 (xd,yd,zd))->tertype != 8 && land))
) tiles.insert(int3(xd,yd,zd));
tiles.insert(int3(xd,yd,*i));
} }
} }
} }
@ -188,7 +190,14 @@ void IGameCallback::getAllowed(std::vector<CArtifact*> &out, int flags)
getAllowedArts(out,&CArtHandler::relics); getAllowedArts(out,&CArtHandler::relics);
} }
TerrainTile * IGameCallback::getTile( int3 pos ) std::pair<ui16, ui16> IGameCallback::getMapSize()
{
std::pair<ui16, ui16> dimensions;
dimensions.first = gs->map->width;
dimensions.second = gs->map->height;
return dimensions;
}
inline TerrainTile * IGameCallback::getTile( int3 pos )
{ {
if(!gs->map->isInTheMap(pos)) if(!gs->map->isInTheMap(pos))
return NULL; return NULL;

View File

@ -58,6 +58,7 @@ public:
virtual bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact virtual bool isAllowed(int type, int id); //type: 0 - spell; 1- artifact
virtual void getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts); virtual void getAllowedArts(std::vector<CArtifact*> &out, std::vector<CArtifact*> CArtHandler::*arts);
virtual void getAllowed(std::vector<CArtifact*> &out, int flags); //flags: bitfield uses EartClass virtual void getAllowed(std::vector<CArtifact*> &out, int flags); //flags: bitfield uses EartClass
virtual std::pair<ui16, ui16> getMapSize();
virtual TerrainTile * getTile(int3 pos); virtual TerrainTile * getTile(int3 pos);
//do sth //do sth

View File

@ -345,9 +345,11 @@ DLL_EXPORT void SetGarrisons::applyGs( CGameState *gs )
DLL_EXPORT void NewStructures::applyGs( CGameState *gs ) DLL_EXPORT void NewStructures::applyGs( CGameState *gs )
{ {
CGTownInstance*t = gs->getTown(tid); CGTownInstance *t = gs->getTown(tid);
BOOST_FOREACH(si32 id,bid) BOOST_FOREACH(si32 id,bid)
{
t->builtBuildings.insert(id); t->builtBuildings.insert(id);
}
t->builded = builded; t->builded = builded;
} }

View File

@ -22,6 +22,7 @@ void registerTypes1(Serializer &s)
{ {
s.template registerType<CGHeroInstance>(); s.template registerType<CGHeroInstance>();
s.template registerType<CGTownInstance>(); s.template registerType<CGTownInstance>();
s.template registerType<CTownBonus>();
s.template registerType<CGPandoraBox>(); s.template registerType<CGPandoraBox>();
s.template registerType<CGEvent>(); s.template registerType<CGEvent>();
s.template registerType<CGVisitableOPH>(); s.template registerType<CGVisitableOPH>();