1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

Next part of town configuration:

- town screen is mostly implemented, has some minor issues
- factions are now separate from towns, neutrals have faction with id=9
- more constants to GameConstants: town-specific buildings, strings for terrains and resources
- replaced most access to builtBuildings with isBuilt() method
- replaced id's with enums for town subtype and buildings id's
This commit is contained in:
Ivan Savenko
2012-09-05 12:49:23 +00:00
parent 44cc848edc
commit 0ca9f64573
36 changed files with 1475 additions and 1471 deletions

View File

@@ -1138,7 +1138,7 @@ void CGameHandler::newTurn()
bool deityOfFireBuilt = false;
BOOST_FOREACH(const CGTownInstance *t, gs->map->towns)
{
if(t->subID == 3 && vstd::contains(t->builtBuildings, EBuilding::GRAIL))
if(t->hasBuilt(EBuilding::GRAIL, ETownType::INFERNO))
{
deityOfFireBuilt = true;
break;
@@ -1231,7 +1231,7 @@ void CGameHandler::newTurn()
hth.id = h->id;
hth.move = h->maxMovePoints(gs->map->getTile(h->getPosition(false)).tertype != TerrainTile::water);
if(h->visitedTown && vstd::contains(h->visitedTown->builtBuildings,0)) //if hero starts turn in town with mage guild
if(h->visitedTown && h->visitedTown->hasBuilt(EBuilding::MAGES_GUILD_1)) //if hero starts turn in town with mage guild
hth.mana = std::max(h->mana, h->manaLimit()); //restore all mana
else
hth.mana = std::max((si32)(0), std::max(h->mana, std::min((si32)(h->mana + h->manaRegain()), h->manaLimit())));
@@ -1258,11 +1258,11 @@ void CGameHandler::newTurn()
handleTownEvents(t, n, newCreas);
if(newWeek) //first day of week
{
if(t->subID == 5 && vstd::contains(t->builtBuildings, EBuilding::SPECIAL_3))
if(t->hasBuilt(EBuilding::PORTAL_OF_SUMMON, ETownType::DUNGEON))
setPortalDwelling(t, true, (n.specialWeek == NewTurn::PLAGUE ? true : false)); //set creatures for Portal of Summoning
if(!firstTurn)
if (t->subID == 1 && player < GameConstants::PLAYER_LIMIT && vstd::contains(t->builtBuildings, EBuilding::SPECIAL_3))//dwarven treasury
if (t->hasBuilt(EBuilding::TREASURY, ETownType::RAMPART) && player < GameConstants::PLAYER_LIMIT)
n.res[player][Res::GOLD] += hadGold[player]/10; //give 10% of starting gold
SetAvailableCreatures sac;
@@ -1307,7 +1307,7 @@ void CGameHandler::newTurn()
}
if(!firstTurn && player < GameConstants::PLAYER_LIMIT)//not the first day and town not neutral
{
if(vstd::contains(t->builtBuildings, EBuilding::RESOURCE_SILO)) //there is resource silo
if(t->hasBuilt(EBuilding::RESOURCE_SILO)) //there is resource silo
{
if(t->town->primaryRes == 127) //we'll give wood and ore
{
@@ -1322,7 +1322,7 @@ void CGameHandler::newTurn()
n.res[player][Res::GOLD] += t->dailyIncome();
}
if(vstd::contains(t->builtBuildings, EBuilding::GRAIL) && t->subID == 2)
if(t->hasBuilt(EBuilding::GRAIL, ETownType::TOWER))
{
// Skyship, probably easier to handle same as Veil of darkness
//do it every new day after veils apply
@@ -1579,7 +1579,7 @@ void CGameHandler::giveSpells( const CGTownInstance *t, const CGHeroInstance *h
cs.learn = true;
for(int i=0; i<std::min(t->mageGuildLevel(),h->getSecSkillLevel(CGHeroInstance::WISDOM)+2);i++)
{
if (t->subID == 8 && vstd::contains(t->builtBuildings, EBuilding::GRAIL)) //Aurora Borealis
if (t->hasBuilt(EBuilding::GRAIL, ETownType::CONFLUX)) //Aurora Borealis
{
std::vector<ui16> spells;
getAllowedSpells(spells, i);
@@ -1795,9 +1795,9 @@ bool CGameHandler::teleportHero(si32 hid, si32 dstid, ui8 source, ui8 asker/* =
const CGTownInstance *from = h->visitedTown;
if(((h->getOwner() != t->getOwner())
&& complain("Cannot teleport hero to another player"))
|| ((!from || from->subID!=3 || !vstd::contains(from->builtBuildings, EBuilding::SPECIAL_3))
|| ((!from || from->hasBuilt(EBuilding::CASTLE_GATE, ETownType::INFERNO))
&& complain("Hero must be in town with Castle gate for teleporting"))
|| ((t->subID!=3 || !vstd::contains(t->builtBuildings, EBuilding::SPECIAL_3))
|| (t->hasBuilt(EBuilding::CASTLE_GATE, ETownType::INFERNO)
&& complain("Cannot teleport hero to town without Castle gate in it")))
return false;
int3 pos = t->visitablePos();
@@ -1818,7 +1818,7 @@ void CGameHandler::setOwner(int objid, ui8 owner)
if(owner < GameConstants::PLAYER_LIMIT && getTown(objid)) //town captured
{
const CGTownInstance * town = getTown(objid);
if (town->subID == 5 && vstd::contains(town->builtBuildings, 22))
if (town->hasBuilt(EBuilding::PORTAL_OF_SUMMON, ETownType::DUNGEON))
setPortalDwelling(town, true, false);
if (!gs->getPlayer(owner)->towns.size())//player lost last town
@@ -1837,7 +1837,7 @@ void CGameHandler::setOwner(int objid, ui8 owner)
{
BOOST_FOREACH(const CGTownInstance *t, gs->getPlayer(owner)->towns)
{
if (t->subID == 5 && vstd::contains(t->builtBuildings, 22))
if (t->hasBuilt(EBuilding::PORTAL_OF_SUMMON, ETownType::DUNGEON))
setPortalDwelling(t);//set initial creatures for all portals of summoning
}
}
@@ -2421,27 +2421,34 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid, bool force /*=false*/ )
if(!force)
{
if (gs->canBuildStructure(t,bid) != 7)
COMPLAIN_RET("Cannot build that building!");
if(bid == 26) //grail
switch (b->mode)
{
if(!t->visitingHero || !t->visitingHero->hasArt(2))
COMPLAIN_RET("Cannot build grail - hero doesn't have it")
else
removeArtifact(ArtifactLocation(t->visitingHero, t->visitingHero->getArtPos(2, false)));
case CBuilding::BUILD_NORMAL :
case CBuilding::BUILD_AUTO :
if (gs->canBuildStructure(t,bid) != EBuildingState::ALLOWED)
COMPLAIN_RET("Cannot build that building!");
break;
case CBuilding::BUILD_SPECIAL:
COMPLAIN_RET("This building can not be constructed!");
break;
case CBuilding::BUILD_GRAIL :
if(b->mode == CBuilding::BUILD_GRAIL) //needs grail
{
if(!t->visitingHero || !t->visitingHero->hasArt(2))
COMPLAIN_RET("Cannot build this without grail!")
else
removeArtifact(ArtifactLocation(t->visitingHero, t->visitingHero->getArtPos(2, false)));
}
break;
}
}
NewStructures ns;
ns.tid = tid;
//we have upgr. dwelling, upgr. horde will be builded as well
if ( (bid == 18) && (vstd::contains(t->builtBuildings,(t->town->hordeLvl[0]+37))) )
ns.bid.insert(19);
else if ( (bid == 24) && (vstd::contains(t->builtBuildings,(t->town->hordeLvl[1]+37))) )
ns.bid.insert(25);
else if(bid >= EBuilding::DWELL_FIRST) //dwelling
if(bid >= EBuilding::DWELL_FIRST) //dwelling
{
int level = (bid - EBuilding::DWELL_FIRST) % GameConstants::CREATURES_PER_TOWN;
int upgradeNumber = (bid - EBuilding::DWELL_FIRST) / GameConstants::CREATURES_PER_TOWN;
@@ -2451,14 +2458,6 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid, bool force /*=false*/ )
CCreature * crea = VLC->creh->creatures[t->town->creatures[level][upgradeNumber]];
if (vstd::iswithin(bid, EBuilding::DWELL_UP_FIRST, EBuilding::DWELL_UP_LAST))
{
if ( (bid-37 == t->town->hordeLvl[0]) && (vstd::contains(t->builtBuildings,18)) )
ns.bid.insert(19);//we have horde, will be upgraded as well as dwelling
if ( (bid-37 == t->town->hordeLvl[1]) && (vstd::contains(t->builtBuildings,24)) )
ns.bid.insert(25);
}
SetAvailableCreatures ssi;
ssi.tid = tid;
ssi.creatures = t->creatures;
@@ -2467,19 +2466,34 @@ bool CGameHandler::buildStructure( si32 tid, si32 bid, bool force /*=false*/ )
ssi.creatures[level].second.push_back(crea->idNumber);
sendAndApply(&ssi);
}
else if(bid == 11)
ns.bid.insert(27);
else if(bid == 12)
ns.bid.insert(28);
else if(bid == 13)
ns.bid.insert(29);
else if ( t->subID == 5 && bid == 22 )
else if ( t->subID == ETownType::DUNGEON && bid == EBuilding::MANA_VORTEX )
{
setPortalDwelling(t);
}
ns.bid.insert(bid);
ns.builded = force?t->builded:(t->builded+1);
BOOST_FOREACH(auto & build, t->town->buildings)
{
if (build.second->mode == CBuilding::BUILD_AUTO
&& !vstd::contains(t->builtBuildings, build.second->bid))
{
bool canBuild = true;
BOOST_FOREACH(int requires, build.second->requirements)
{
if (!vstd::contains(t->builtBuildings, requires)
&& !vstd::contains(ns.bid, requires))
{
canBuild = false;
break;
}
}
if (canBuild)
ns.bid.insert(build.second->bid);
}
}
sendAndApply(&ns);
//reveal ground for lookout tower
@@ -2866,7 +2880,7 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
CGTownInstance *town = hero->visitedTown;
if(aid==0) //spellbook
{
if((!vstd::contains(town->builtBuildings,si32(EBuilding::MAGES_GUILD_1)) && complain("Cannot buy a spellbook, no mage guild in the town!"))
if((!town->hasBuilt(EBuilding::MAGES_GUILD_1) && complain("Cannot buy a spellbook, no mage guild in the town!"))
|| (getResource(hero->getOwner(), Res::GOLD) < GameConstants::SPELLBOOK_GOLD_COST && complain("Cannot buy a spellbook, not enough gold!") )
|| (hero->getArt(ArtifactPosition::SPELLBOOK) && complain("Cannot buy a spellbook, hero already has a one!"))
)
@@ -2881,18 +2895,21 @@ bool CGameHandler::buyArtifact( ui32 hid, si32 aid )
else if(aid < 7 && aid > 3) //war machine
{
int price = VLC->arth->artifacts[aid]->price;
if((hero->getArt(9+aid) && complain("Hero already has this machine!"))
|| (!vstd::contains(town->builtBuildings,si32(EBuilding::BLACKSMITH)) && complain("No blackismith!"))
|| (gs->getPlayer(hero->getOwner())->resources[Res::GOLD] < price && complain("Not enough gold!")) //no gold
|| ((!(town->subID == 6 && vstd::contains(town->builtBuildings,si32(EBuilding::SPECIAL_3) ) )
&& town->town->warMachine!= aid ) && complain("This machine is unavailable here!")))
if(( hero->getArt(9+aid) && complain("Hero already has this machine!"))
|| (gs->getPlayer(hero->getOwner())->resources[Res::GOLD] < price && complain("Not enough gold!")))
{
return false;
}
giveResource(hero->getOwner(),Res::GOLD,-price);
giveHeroNewArtifact(hero, VLC->arth->artifacts[aid], 9+aid);
return true;
if ((town->hasBuilt(EBuilding::BLACKSMITH) && town->town->warMachine == aid )
|| ((town->hasBuilt(EBuilding::BALLISTA_YARD, ETownType::STRONGHOLD)) && aid == 4))
{
giveResource(hero->getOwner(),Res::GOLD,-price);
giveHeroNewArtifact(hero, VLC->arth->artifacts[aid], 9+aid);
return true;
}
else
COMPLAIN_RET("This machine is unavailable here!");
}
return false;
}
@@ -3136,7 +3153,7 @@ bool CGameHandler::hireHero(const CGObjectInstance *obj, ui8 hid, ui8 player)
if(t) //tavern in town
{
if( (!vstd::contains(t->builtBuildings,EBuilding::TAVERN) && complain("No tavern!"))
if( (!t->hasBuilt(EBuilding::TAVERN) && complain("No tavern!"))
|| (t->visitingHero && complain("There is visiting hero - no place!")))
return false;
}
@@ -3731,8 +3748,7 @@ void CGameHandler::playerMessage( ui8 player, const std::string &message )
{
BOOST_FOREACH (auto & build, town->town->buildings)
{
if (!vstd::contains(town->builtBuildings, build.first)
&& !build.second->Name().empty())
if (!town->hasBuilt(build.first) && !build.second->Name().empty())
{
buildStructure(town->id, build.first, true);
}
@@ -4739,7 +4755,7 @@ void CGameHandler::handleTownEvents(CGTownInstance * town, NewTurn &n, std::map<
}
for(std::set<si32>::iterator i = ev->buildings.begin(); i!=ev->buildings.end();i++)
if ( !vstd::contains(town->builtBuildings, *i))
if ( town->hasBuilt(*i))
{
buildStructure(town->id, *i, true);
iw.components.push_back(Component(Component::BUILDING, town->subID, *i, 0));
@@ -4902,14 +4918,14 @@ bool CGameHandler::buildBoat( ui32 objid )
return false;
}
else if(obj->o->ID == GameConstants::TOWNI_TYPE
&& !vstd::contains((static_cast<const CGTownInstance*>(obj))->builtBuildings,6))
&& !static_cast<const CGTownInstance*>(obj)->hasBuilt(EBuilding::SHIPYARD))
{
complain("Cannot build boat in the town - no shipyard!");
return false;
}
//TODO use "real" cost via obj->getBoatCost
if(getResource(obj->o->tempOwner, 6) < 1000 || getResource(obj->o->tempOwner, 0) < 10)
if(getResource(obj->o->tempOwner, Res::GOLD) < 1000 || getResource(obj->o->tempOwner, Res::WOOD) < 10)
{
complain("Not enough resources to build a boat!");
return false;