1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-10-08 23:22:25 +02:00

Implemented abandoned mine. Minor fixes.

This commit is contained in:
Michał W. Urbańczyk
2010-07-31 00:26:34 +00:00
parent af7aebc806
commit d79fa527a7
8 changed files with 138 additions and 38 deletions

View File

@@ -405,6 +405,9 @@ void CGObjectInstance::setProperty( ui8 what, ui32 val )
case ObjProperty::ID:
ID = val;
break;
case ObjProperty::SUBID:
subID = val;
break;
}
setPropertyDer(what, val);
}
@@ -2606,11 +2609,11 @@ const std::string & CGVisitableOPH::getHoverText() const
}
hoverName = VLC->generaltexth->names[ID];
if(pom >= 0)
hoverName += (" " + VLC->generaltexth->xtrainfo[pom]);
hoverName += ("\n" + VLC->generaltexth->xtrainfo[pom]);
const CGHeroInstance *h = cb->getSelectedHero(cb->getCurrentPlayer());
if(h)
{
hoverName += ' ';
hoverName += "\n\n";
hoverName += (vstd::contains(visitors,h->id))
? (VLC->generaltexth->allTexts[352]) //visited
: ( VLC->generaltexth->allTexts[353]); //not visited
@@ -3061,34 +3064,25 @@ void CGCreature::flee( const CGHeroInstance * h ) const
void CGMine::onHeroVisit( const CGHeroInstance * h ) const
{
if(subID == 7) //TODO: support for abandoned mine
return;
if(h->tempOwner == tempOwner) //we're visiting our mine
{
cb->showGarrisonDialog(id,h->id,true,0);
return;
}
if(subID >= 7) //Abandoned mine
{
BlockingDialog ynd(true,false);
ynd.player = h->tempOwner;
ynd.text << std::pair<ui8,ui32>(MetaString::ADVOB_TXT, 84);
cb->showBlockingDialog(&ynd,boost::bind(&CGMine::fight, this, _1, h));
return;
}
//TODO: check if mine is guarded
cb->setOwner(id,h->tempOwner); //not ours? flag it!
MetaString ms;
ms << std::pair<ui8,ui32>(9,subID) << " (" << std::pair<ui8,ui32>(6,23+h->tempOwner) << ")";
cb->setHoverName(id,&ms);
flagMine(h->tempOwner);
int vv=1; //amount of resource per turn
if (subID==0 || subID==2)
vv++;
else if (subID==6)
vv = 1000;
InfoWindow iw;
iw.soundID = soundBase::FLAGMINE;
iw.text << std::pair<ui8,ui32>(10,subID);
iw.player = h->tempOwner;
iw.components.push_back(Component(2,subID,vv,-1));
cb->showInfoDialog(&iw);
}
void CGMine::newTurn() const
@@ -3108,8 +3102,30 @@ void CGMine::newTurn() const
void CGMine::initObj()
{
if(subID >= 7) //Abandoned Mine
{
//set guardians
int howManyTroglodytes = 100 + ran()%100;
CStackInstance troglodytes(70, howManyTroglodytes);
addStack(0, troglodytes);
//after map reading tempOwner placeholds bitmask for allowed resources
std::vector<int> possibleResources;
for (int i = 0; i < 8; i++)
if(tempOwner & 1<<i)
possibleResources.push_back(i);
assert(possibleResources.size());
producedResource = possibleResources[ran()%possibleResources.size()];
tempOwner = NEUTRAL_PLAYER;
hoverName = VLC->generaltexth->mines[7].first + "\n" + VLC->generaltexth->allTexts[202] + " " + troglodytes.getQuantityTXT(false) + " " + troglodytes.type->namePl;
}
else
{
producedResource = subID;
MetaString ms;
ms << std::pair<ui8,ui32>(9,subID);
ms << std::pair<ui8,ui32>(9,producedResource);
if(tempOwner >= PLAYER_LIMIT)
tempOwner = NEUTRAL_PLAYER;
else
@@ -3117,6 +3133,66 @@ void CGMine::initObj()
ms.toString(hoverName);
}
producedQuantity = defaultResProduction();
}
void CGMine::fight(ui32 agreed, const CGHeroInstance *h) const
{
cb->startBattleI(h, this, boost::bind(&CGMine::endBattle, this, _1, h->tempOwner));
}
void CGMine::endBattle(BattleResult *result, ui8 attackingPlayer) const
{
if(result->winner == 0) //attacker won
{
if(subID == 7)
{
InfoWindow iw;
iw.player = attackingPlayer;
iw.text.addTxt(MetaString::ADVOB_TXT, 85);
cb->showInfoDialog(&iw);
}
flagMine(attackingPlayer);
}
}
void CGMine::flagMine(ui8 player) const
{
assert(tempOwner != player);
cb->setOwner(id,player); //not ours? flag it!
MetaString ms;
ms << std::pair<ui8,ui32>(9,subID) << "\n(" << std::pair<ui8,ui32>(6,23+player) << ")";
if(subID == 7)
{
ms << "(%s)";
ms.addReplacement(MetaString::RES_NAMES, producedResource);
}
cb->setHoverName(id,&ms);
InfoWindow iw;
iw.soundID = soundBase::FLAGMINE;
iw.text.addTxt(MetaString::MINE_EVNTS,producedResource); //not use subID, abandoned mines uses default mine texts
iw.player = player;
iw.components.push_back(Component(2,producedResource,producedQuantity,-1));
cb->showInfoDialog(&iw);
}
ui32 CGMine::defaultResProduction()
{
switch(producedResource)
{
case 0: //wood
case 2: //ore
return 2;
case 6: //gold
return 1000;
default:
return 1;
}
}
void CGResource::initObj()
{
blockVisit = true;

View File

@@ -818,14 +818,24 @@ public:
class DLL_EXPORT CGMine : public CArmedInstance
{
public:
ui8 producedResource;
ui32 producedQuantity;
void offerLeavingGuards(const CGHeroInstance *h) const;
void endBattle(BattleResult *result, ui8 attackingPlayer) const;
void fight(ui32 agreed, const CGHeroInstance *h) const;
void onHeroVisit(const CGHeroInstance * h) const;
void flagMine(ui8 player) const;
void newTurn() const;
void initObj();
template <typename Handler> void serialize(Handler &h, const int version)
{
h & static_cast<CArmedInstance&>(*this);
h & producedResource & producedQuantity;
}
ui32 defaultResProduction();
};
class DLL_EXPORT CGVisitableOPW : public CGObjectInstance //objects visitable OPW

View File

@@ -286,3 +286,8 @@ ui32 CStackInstance::getMaxDamage() const
{
return type->damageMax + valOfBonuses(Bonus::CREATURE_DAMAGE, 0) + valOfBonuses(Bonus::CREATURE_DAMAGE, 2);
}
std::string CStackInstance::getQuantityTXT(bool capitalized /*= true*/) const
{
return VLC->generaltexth->arraytxt[174 + getQuantityID()*3 + 2 - capitalized];
}

View File

@@ -40,6 +40,7 @@ public:
void getParents(TCNodes &out, const CBonusSystemNode *source = NULL) const; //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker
int getQuantityID() const;
std::string getQuantityTXT(bool capitalized = true) const;
void init();
CStackInstance();
CStackInstance(TCreature id, TQuantity count, const CArmedInstance *ArmyObj = NULL);

View File

@@ -1668,6 +1668,11 @@ int CGameState::battleGetBattlefieldType(int3 tile)
else if(tile==int3() && !curB)
return -1;
const TerrainTile &t = map->getTile(tile);
//fight in mine -> subterranean
if(const CGMine *mine = dynamic_cast<const CGMine *>(t.visitableObjects.front()))
return 12;
const std::vector <CGObjectInstance*> & objs = map->objects;
for(int g=0; g<objs.size(); ++g)
{
@@ -1701,7 +1706,7 @@ int CGameState::battleGetBattlefieldType(int3 tile)
}
}
switch(map->terrain[tile.x][tile.y][tile.z].tertype)
switch(t.tertype)
{
case TerrainTile::dirt:
return rand()%3+3;

View File

@@ -84,14 +84,23 @@ void DLL_EXPORT BonusList::getBonuses(BonusList &out, const CSelector &selector,
void BonusList::limit(const CBonusSystemNode &node)
{
limit_start:
for(iterator i = begin(); i != end(); i++)
{
if(i->limiter && i->limiter->limit(*i, node))
{
iterator toErase = i;
if(i != begin())
{
i--;
erase(toErase);
}
else
{
erase(toErase);
goto limit_start;
}
}
}
}

View File

@@ -747,7 +747,7 @@ struct InfoWindow : public CPackForClient //103 - displays simple info window
namespace ObjProperty
{
//TODO: move non general properties out to the appropriate objs classes
enum {OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6, AVAILABLE_CREATURE = 7};
enum {OWNER = 1, BLOCKVIS = 2, PRIMARY_STACK_COUNT = 3, VISITORS = 4, VISITED = 5, ID = 6, AVAILABLE_CREATURE = 7, SUBID = 8};
}
struct SetObjectProperty : public CPackForClient//1001

View File

@@ -1653,6 +1653,7 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
break;
}
case 53:
case 220://mine (?)
{
nobj = new CGMine();
nobj->setOwner(bufor[i++]);
@@ -1672,13 +1673,6 @@ void Mapa::readObjects( const unsigned char * bufor, int &i)
nobj = new CGDwelling();
break;
}
case 220://mine (?)
{
nobj = new CGObjectInstance();
nobj->setOwner(bufor[i++]);
i+=3;
break;
}
case 88: case 89: case 90: //spell shrine
{
CGShrine * shr = new CGShrine();