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:
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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;
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>();
|
||||||
|
Reference in New Issue
Block a user