mirror of
https://github.com/vcmi/vcmi.git
synced 2025-07-15 01:24:45 +02:00
- Refactored method CGameState::init
This commit is contained in:
@ -699,7 +699,6 @@ int CClient::sendRequest(const CPack *request, PlayerColor player)
|
|||||||
void CClient::campaignMapFinished( shared_ptr<CCampaignState> camp )
|
void CClient::campaignMapFinished( shared_ptr<CCampaignState> camp )
|
||||||
{
|
{
|
||||||
endGame(false);
|
endGame(false);
|
||||||
LOCPLINT = nullptr; //TODO free res
|
|
||||||
|
|
||||||
GH.curInt = CGPreGame::create();
|
GH.curInt = CGPreGame::create();
|
||||||
auto & epilogue = camp->camp->scenarios[camp->mapsConquered.back()].epilog;
|
auto & epilogue = camp->camp->scenarios[camp->mapsConquered.back()].epilog;
|
||||||
|
@ -726,6 +726,7 @@ int CGameState::getDate(Date::EDateType mode) const
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameState::CGameState()
|
CGameState::CGameState()
|
||||||
{
|
{
|
||||||
gs = this;
|
gs = this;
|
||||||
@ -735,6 +736,7 @@ CGameState::CGameState()
|
|||||||
objCaller = new CObjectCallersHandler;
|
objCaller = new CObjectCallersHandler;
|
||||||
globalEffects.setDescription("Global effects");
|
globalEffects.setDescription("Global effects");
|
||||||
}
|
}
|
||||||
|
|
||||||
CGameState::~CGameState()
|
CGameState::~CGameState()
|
||||||
{
|
{
|
||||||
//delete mx;//TODO: crash on Linux (mutex must be unlocked before destruction)
|
//delete mx;//TODO: crash on Linux (mutex must be unlocked before destruction)
|
||||||
@ -762,76 +764,6 @@ BattleInfo * CGameState::setupBattle(int3 tile, const CArmedInstance *armies[2],
|
|||||||
|
|
||||||
void CGameState::init(StartInfo * si)
|
void CGameState::init(StartInfo * si)
|
||||||
{
|
{
|
||||||
auto giveCampaignBonusToHero = [&](CGHeroInstance * hero)
|
|
||||||
{
|
|
||||||
const boost::optional<CScenarioTravel::STravelBonus> & curBonus = scenarioOps->campState->getBonusForCurrentMap();
|
|
||||||
if(!curBonus)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(curBonus->isBonusForHero())
|
|
||||||
{
|
|
||||||
//apply bonus
|
|
||||||
switch (curBonus->type)
|
|
||||||
{
|
|
||||||
case CScenarioTravel::STravelBonus::SPELL:
|
|
||||||
hero->spells.insert(SpellID(curBonus->info2));
|
|
||||||
break;
|
|
||||||
case CScenarioTravel::STravelBonus::MONSTER:
|
|
||||||
{
|
|
||||||
for(int i=0; i<GameConstants::ARMY_SIZE; i++)
|
|
||||||
{
|
|
||||||
if(hero->slotEmpty(SlotID(i)))
|
|
||||||
{
|
|
||||||
hero->addToSlot(SlotID(i), CreatureID(curBonus->info2), curBonus->info3);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CScenarioTravel::STravelBonus::ARTIFACT:
|
|
||||||
gs->giveHeroArtifact(hero, static_cast<ArtifactID>(curBonus->info2));
|
|
||||||
break;
|
|
||||||
case CScenarioTravel::STravelBonus::SPELL_SCROLL:
|
|
||||||
{
|
|
||||||
CArtifactInstance * scroll = CArtifactInstance::createScroll(SpellID(curBonus->info2).toSpell());
|
|
||||||
scroll->putAt(ArtifactLocation(hero, scroll->firstAvailableSlot(hero)));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CScenarioTravel::STravelBonus::PRIMARY_SKILL:
|
|
||||||
{
|
|
||||||
const ui8* ptr = reinterpret_cast<const ui8*>(&curBonus->info2);
|
|
||||||
for (int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
|
||||||
{
|
|
||||||
int val = ptr[g];
|
|
||||||
if (val == 0)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
auto bb = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::CAMPAIGN_BONUS, val, *scenarioOps->campState->currentMap, g);
|
|
||||||
hero->addNewBonus(bb);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CScenarioTravel::STravelBonus::SECONDARY_SKILL:
|
|
||||||
hero->setSecSkillLevel(SecondarySkill(curBonus->info2), curBonus->info3, true);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
auto getHumanPlayerInfo = [&]() -> std::vector<const PlayerSettings *>
|
|
||||||
{
|
|
||||||
std::vector<const PlayerSettings *> ret;
|
|
||||||
for(auto it = scenarioOps->playerInfos.cbegin();
|
|
||||||
it != scenarioOps->playerInfos.cend(); ++it)
|
|
||||||
{
|
|
||||||
if(it->second.playerID != PlayerSettings::PLAYER_AI)
|
|
||||||
ret.push_back(&it->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
|
|
||||||
logGlobal->infoStream() << "\tUsing random seed: "<< si->seedToBeUsed;
|
logGlobal->infoStream() << "\tUsing random seed: "<< si->seedToBeUsed;
|
||||||
ran.seed((boost::int32_t)si->seedToBeUsed);
|
ran.seed((boost::int32_t)si->seedToBeUsed);
|
||||||
scenarioOps = new StartInfo(*si);
|
scenarioOps = new StartInfo(*si);
|
||||||
@ -841,6 +773,59 @@ void CGameState::init(StartInfo * si)
|
|||||||
switch(scenarioOps->mode)
|
switch(scenarioOps->mode)
|
||||||
{
|
{
|
||||||
case StartInfo::NEW_GAME:
|
case StartInfo::NEW_GAME:
|
||||||
|
initNewGame();
|
||||||
|
break;
|
||||||
|
case StartInfo::CAMPAIGN:
|
||||||
|
initCampaign();
|
||||||
|
break;
|
||||||
|
case StartInfo::DUEL:
|
||||||
|
initDuel();
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
logGlobal->errorStream() << "Wrong mode: " << (int)scenarioOps->mode;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
VLC->arth->initAllowedArtifactsList(map->allowedArtifact);
|
||||||
|
logGlobal->infoStream() << "Map loaded!";
|
||||||
|
|
||||||
|
checkMapChecksum();
|
||||||
|
|
||||||
|
day = 0;
|
||||||
|
|
||||||
|
logGlobal->debugStream() << "Initialization:";
|
||||||
|
|
||||||
|
initGrailPosition();
|
||||||
|
initRandomFactionsForPlayers();
|
||||||
|
randomizeMapObjects();
|
||||||
|
initPlayerStates();
|
||||||
|
initHeroPlaceholders();
|
||||||
|
placeStartingHeroes();
|
||||||
|
initStartingResources();
|
||||||
|
initHeroes();
|
||||||
|
initFogOfWar();
|
||||||
|
initStartingBonus();
|
||||||
|
initTowns();
|
||||||
|
initMapObjects();
|
||||||
|
buildBonusSystemTree();
|
||||||
|
initVisitingAndGarrisonedHeroes();
|
||||||
|
|
||||||
|
logGlobal->debugStream() << "\tChecking objectives";
|
||||||
|
map->checkForObjectives(); //needs to be run when all objects are properly placed
|
||||||
|
|
||||||
|
int seedAfterInit = ran();
|
||||||
|
logGlobal->infoStream() << "Seed after init is " << seedAfterInit << " (before was " << scenarioOps->seedToBeUsed << ")";
|
||||||
|
if(scenarioOps->seedPostInit > 0)
|
||||||
|
{
|
||||||
|
//RNG must be in the same state on all machines when initialization is done (otherwise we have desync)
|
||||||
|
assert(scenarioOps->seedPostInit == seedAfterInit);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scenarioOps->seedPostInit = seedAfterInit; //store the post init "seed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::initNewGame()
|
||||||
{
|
{
|
||||||
if(scenarioOps->createRandomMap())
|
if(scenarioOps->createRandomMap())
|
||||||
{
|
{
|
||||||
@ -881,8 +866,8 @@ void CGameState::init(StartInfo * si)
|
|||||||
map = CMapService::loadMap(scenarioOps->mapname).release();
|
map = CMapService::loadMap(scenarioOps->mapname).release();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case StartInfo::CAMPAIGN:
|
void CGameState::initCampaign()
|
||||||
{
|
{
|
||||||
logGlobal->infoStream() << "Open campaign map file: " << scenarioOps->campState->currentMap;
|
logGlobal->infoStream() << "Open campaign map file: " << scenarioOps->campState->currentMap;
|
||||||
auto campaign = scenarioOps->campState;
|
auto campaign = scenarioOps->campState;
|
||||||
@ -892,17 +877,110 @@ void CGameState::init(StartInfo * si)
|
|||||||
auto buffer = reinterpret_cast<const ui8 *>(mapContent.data());
|
auto buffer = reinterpret_cast<const ui8 *>(mapContent.data());
|
||||||
map = CMapService::loadMap(buffer, mapContent.size()).release();
|
map = CMapService::loadMap(buffer, mapContent.size()).release();
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case StartInfo::DUEL:
|
|
||||||
initDuel();
|
|
||||||
return;
|
|
||||||
default:
|
|
||||||
logGlobal->errorStream() << "Wrong mode: " << (int)scenarioOps->mode;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
VLC->arth->initAllowedArtifactsList(map->allowedArtifact);
|
|
||||||
logGlobal->infoStream() << "Map loaded!";
|
|
||||||
|
|
||||||
|
void CGameState::initDuel()
|
||||||
|
{
|
||||||
|
DuelParameters dp;
|
||||||
|
try //CLoadFile likes throwing
|
||||||
|
{
|
||||||
|
if(boost::algorithm::ends_with(scenarioOps->mapname, ".json"))
|
||||||
|
{
|
||||||
|
logGlobal->infoStream() << "Loading duel settings from JSON file: " << scenarioOps->mapname;
|
||||||
|
dp = DuelParameters::fromJSON(scenarioOps->mapname);
|
||||||
|
logGlobal->infoStream() << "JSON file has been successfully read!";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CLoadFile lf(scenarioOps->mapname);
|
||||||
|
lf >> dp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(...)
|
||||||
|
{
|
||||||
|
logGlobal->errorStream() << "Cannot load duel settings from " << scenarioOps->mapname;
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CArmedInstance *armies[2] = {nullptr};
|
||||||
|
const CGHeroInstance *heroes[2] = {nullptr};
|
||||||
|
CGTownInstance *town = nullptr;
|
||||||
|
|
||||||
|
for(int i = 0; i < 2; i++)
|
||||||
|
{
|
||||||
|
CArmedInstance *obj = nullptr;
|
||||||
|
if(dp.sides[i].heroId >= 0)
|
||||||
|
{
|
||||||
|
const DuelParameters::SideSettings &ss = dp.sides[i];
|
||||||
|
auto h = new CGHeroInstance();
|
||||||
|
armies[i] = heroes[i] = h;
|
||||||
|
obj = h;
|
||||||
|
h->subID = ss.heroId;
|
||||||
|
for(int i = 0; i < ss.heroPrimSkills.size(); i++)
|
||||||
|
h->pushPrimSkill(static_cast<PrimarySkill::PrimarySkill>(i), ss.heroPrimSkills[i]);
|
||||||
|
|
||||||
|
if(!ss.spells.empty())
|
||||||
|
{
|
||||||
|
h->putArtifact(ArtifactPosition::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(0));
|
||||||
|
boost::copy(ss.spells, std::inserter(h->spells, h->spells.begin()));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto &parka : ss.artifacts)
|
||||||
|
{
|
||||||
|
h->putArtifact(ArtifactPosition(parka.first), parka.second);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef const std::pair<si32, si8> &TSecSKill;
|
||||||
|
for(TSecSKill secSkill : ss.heroSecSkills)
|
||||||
|
h->setSecSkillLevel(SecondarySkill(secSkill.first), secSkill.second, 1);
|
||||||
|
|
||||||
|
h->initHero(HeroTypeID(h->subID));
|
||||||
|
obj->initObj();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto c = new CGCreature();
|
||||||
|
armies[i] = obj = c;
|
||||||
|
//c->subID = 34;
|
||||||
|
}
|
||||||
|
|
||||||
|
obj->setOwner(PlayerColor(i));
|
||||||
|
|
||||||
|
for(int j = 0; j < ARRAY_COUNT(dp.sides[i].stacks); j++)
|
||||||
|
{
|
||||||
|
CreatureID cre = dp.sides[i].stacks[j].type;
|
||||||
|
TQuantity count = dp.sides[i].stacks[j].count;
|
||||||
|
if(count || obj->hasStackAtSlot(SlotID(j)))
|
||||||
|
obj->setCreature(SlotID(j), cre, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const DuelParameters::CusomCreature &cc : dp.creatures)
|
||||||
|
{
|
||||||
|
CCreature *c = VLC->creh->creatures[cc.id];
|
||||||
|
if(cc.attack >= 0)
|
||||||
|
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK))->val = cc.attack;
|
||||||
|
if(cc.defense >= 0)
|
||||||
|
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE))->val = cc.defense;
|
||||||
|
if(cc.speed >= 0)
|
||||||
|
c->getBonusLocalFirst(Selector::type(Bonus::STACKS_SPEED))->val = cc.speed;
|
||||||
|
if(cc.HP >= 0)
|
||||||
|
c->getBonusLocalFirst(Selector::type(Bonus::STACK_HEALTH))->val = cc.HP;
|
||||||
|
if(cc.dmg >= 0)
|
||||||
|
{
|
||||||
|
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1))->val = cc.dmg;
|
||||||
|
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2))->val = cc.dmg;
|
||||||
|
}
|
||||||
|
if(cc.shoots >= 0)
|
||||||
|
c->getBonusLocalFirst(Selector::type(Bonus::SHOTS))->val = cc.shoots;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
curB = BattleInfo::setupBattle(int3(), dp.terType, dp.bfieldType, armies, heroes, false, town);
|
||||||
|
curB->obstacles = dp.obstacles;
|
||||||
|
curB->localInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::checkMapChecksum()
|
||||||
|
{
|
||||||
logGlobal->infoStream() << "\tOur checksum for the map: "<< map->checksum;
|
logGlobal->infoStream() << "\tOur checksum for the map: "<< map->checksum;
|
||||||
if(scenarioOps->mapfileChecksum)
|
if(scenarioOps->mapfileChecksum)
|
||||||
{
|
{
|
||||||
@ -914,11 +992,13 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
scenarioOps->mapfileChecksum = map->checksum;
|
scenarioOps->mapfileChecksum = map->checksum;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
day = 0;
|
void CGameState::initGrailPosition()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "Initialization:";
|
|
||||||
logGlobal->debugStream() << "\tPicking grail position";
|
logGlobal->debugStream() << "\tPicking grail position";
|
||||||
//pick grail location
|
//pick grail location
|
||||||
if(map->grailPos.x < 0 || map->grailRadious) //grail not set or set within a radius around some place
|
if(map->grailPos.x < 0 || map->grailRadious) //grail not set or set within a radius around some place
|
||||||
@ -957,8 +1037,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
else
|
else
|
||||||
logGlobal->warnStream() << "Warning: Grail cannot be placed, no appropriate tile found!";
|
logGlobal->warnStream() << "Warning: Grail cannot be placed, no appropriate tile found!";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//picking random factions for players
|
void CGameState::initRandomFactionsForPlayers()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tPicking random factions for players";
|
logGlobal->debugStream() << "\tPicking random factions for players";
|
||||||
for(auto & elem : scenarioOps->playerInfos)
|
for(auto & elem : scenarioOps->playerInfos)
|
||||||
{
|
{
|
||||||
@ -971,29 +1053,35 @@ void CGameState::init(StartInfo * si)
|
|||||||
elem.second.castle = *iter;
|
elem.second.castle = *iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//randomizing objects
|
void CGameState::randomizeMapObjects()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tRandomizing objects";
|
logGlobal->debugStream() << "\tRandomizing objects";
|
||||||
for(CGObjectInstance *obj : map->objects)
|
for(CGObjectInstance *obj : map->objects)
|
||||||
{
|
{
|
||||||
if(!obj)
|
if(!obj) continue;
|
||||||
continue;
|
|
||||||
|
|
||||||
randomizeObject(obj);
|
randomizeObject(obj);
|
||||||
obj->hoverName = VLC->generaltexth->names[obj->ID];
|
obj->hoverName = VLC->generaltexth->names[obj->ID];
|
||||||
|
|
||||||
//handle Favouring Winds - mark tiles under it
|
//handle Favouring Winds - mark tiles under it
|
||||||
if(obj->ID == Obj::FAVORABLE_WINDS)
|
if(obj->ID == Obj::FAVORABLE_WINDS)
|
||||||
|
{
|
||||||
for (int i = 0; i < obj->getWidth() ; i++)
|
for (int i = 0; i < obj->getWidth() ; i++)
|
||||||
|
{
|
||||||
for (int j = 0; j < obj->getHeight() ; j++)
|
for (int j = 0; j < obj->getHeight() ; j++)
|
||||||
{
|
{
|
||||||
int3 pos = obj->pos - int3(i,j,0);
|
int3 pos = obj->pos - int3(i,j,0);
|
||||||
if(map->isInTheMap(pos))
|
if(map->isInTheMap(pos)) map->getTile(pos).extTileFlags |= 128;
|
||||||
map->getTile(pos).extTileFlags |= 128;
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*********creating players entries in gs****************************************/
|
void CGameState::initPlayerStates()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tCreating player entries in gs";
|
logGlobal->debugStream() << "\tCreating player entries in gs";
|
||||||
for(auto & elem : scenarioOps->playerInfos)
|
for(auto & elem : scenarioOps->playerInfos)
|
||||||
{
|
{
|
||||||
@ -1005,8 +1093,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
teams[ins.second.team].players.insert(ins.first);//add player to team
|
teams[ins.second.team].players.insert(ins.first);//add player to team
|
||||||
players.insert(ins);
|
players.insert(ins);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************replace hero placeholders*****************************/
|
void CGameState::initHeroPlaceholders()
|
||||||
|
{
|
||||||
if (scenarioOps->campState)
|
if (scenarioOps->campState)
|
||||||
{
|
{
|
||||||
logGlobal->debugStream() << "\tReplacing hero placeholders";
|
logGlobal->debugStream() << "\tReplacing hero placeholders";
|
||||||
@ -1015,11 +1105,11 @@ void CGameState::init(StartInfo * si)
|
|||||||
logGlobal->debugStream() << "\tSetting up heroes";
|
logGlobal->debugStream() << "\tSetting up heroes";
|
||||||
placeCampaignHeroes(campHeroReplacements);
|
placeCampaignHeroes(campHeroReplacements);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::placeStartingHeroes()
|
||||||
/*********give starting hero****************************************/
|
|
||||||
logGlobal->debugStream() << "\tGiving starting hero";
|
|
||||||
{
|
{
|
||||||
|
logGlobal->debugStream() << "\tGiving starting hero";
|
||||||
bool campaignGiveHero = false;
|
bool campaignGiveHero = false;
|
||||||
if(scenarioOps->campState)
|
if(scenarioOps->campState)
|
||||||
{
|
{
|
||||||
@ -1054,7 +1144,8 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************RESOURCES****************************************************/
|
void CGameState::initStartingResources()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tSetting up resources";
|
logGlobal->debugStream() << "\tSetting up resources";
|
||||||
const JsonNode config(ResourceID("config/startres.json"));
|
const JsonNode config(ResourceID("config/startres.json"));
|
||||||
const JsonVector &vector = config["difficulty"].Vector();
|
const JsonVector &vector = config["difficulty"].Vector();
|
||||||
@ -1073,6 +1164,19 @@ void CGameState::init(StartInfo * si)
|
|||||||
p.resources = startresAI;
|
p.resources = startresAI;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto getHumanPlayerInfo = [&]() -> std::vector<const PlayerSettings *>
|
||||||
|
{
|
||||||
|
std::vector<const PlayerSettings *> ret;
|
||||||
|
for(auto it = scenarioOps->playerInfos.cbegin();
|
||||||
|
it != scenarioOps->playerInfos.cend(); ++it)
|
||||||
|
{
|
||||||
|
if(it->second.playerID != PlayerSettings::PLAYER_AI)
|
||||||
|
ret.push_back(&it->second);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
|
||||||
//give start resource bonus in case of campaign
|
//give start resource bonus in case of campaign
|
||||||
if (scenarioOps->mode == StartInfo::CAMPAIGN)
|
if (scenarioOps->mode == StartInfo::CAMPAIGN)
|
||||||
{
|
{
|
||||||
@ -1106,9 +1210,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::initHeroes()
|
||||||
/*************************HEROES INIT / POOL************************************************/
|
{
|
||||||
for(auto hero : map->heroesOnMap) //heroes instances initialization
|
for(auto hero : map->heroesOnMap) //heroes instances initialization
|
||||||
{
|
{
|
||||||
if (hero->getOwner() == PlayerColor::UNFLAGGABLE)
|
if (hero->getOwner() == PlayerColor::UNFLAGGABLE)
|
||||||
@ -1204,8 +1309,67 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*************************FOG**OF**WAR******************************************/
|
void CGameState::giveCampaignBonusToHero(CGHeroInstance * hero)
|
||||||
|
{
|
||||||
|
const boost::optional<CScenarioTravel::STravelBonus> & curBonus = scenarioOps->campState->getBonusForCurrentMap();
|
||||||
|
if(!curBonus)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if(curBonus->isBonusForHero())
|
||||||
|
{
|
||||||
|
//apply bonus
|
||||||
|
switch (curBonus->type)
|
||||||
|
{
|
||||||
|
case CScenarioTravel::STravelBonus::SPELL:
|
||||||
|
hero->spells.insert(SpellID(curBonus->info2));
|
||||||
|
break;
|
||||||
|
case CScenarioTravel::STravelBonus::MONSTER:
|
||||||
|
{
|
||||||
|
for(int i=0; i<GameConstants::ARMY_SIZE; i++)
|
||||||
|
{
|
||||||
|
if(hero->slotEmpty(SlotID(i)))
|
||||||
|
{
|
||||||
|
hero->addToSlot(SlotID(i), CreatureID(curBonus->info2), curBonus->info3);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CScenarioTravel::STravelBonus::ARTIFACT:
|
||||||
|
gs->giveHeroArtifact(hero, static_cast<ArtifactID>(curBonus->info2));
|
||||||
|
break;
|
||||||
|
case CScenarioTravel::STravelBonus::SPELL_SCROLL:
|
||||||
|
{
|
||||||
|
CArtifactInstance * scroll = CArtifactInstance::createScroll(SpellID(curBonus->info2).toSpell());
|
||||||
|
scroll->putAt(ArtifactLocation(hero, scroll->firstAvailableSlot(hero)));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CScenarioTravel::STravelBonus::PRIMARY_SKILL:
|
||||||
|
{
|
||||||
|
const ui8* ptr = reinterpret_cast<const ui8*>(&curBonus->info2);
|
||||||
|
for (int g=0; g<GameConstants::PRIMARY_SKILLS; ++g)
|
||||||
|
{
|
||||||
|
int val = ptr[g];
|
||||||
|
if (val == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
auto bb = new Bonus(Bonus::PERMANENT, Bonus::PRIMARY_SKILL, Bonus::CAMPAIGN_BONUS, val, *scenarioOps->campState->currentMap, g);
|
||||||
|
hero->addNewBonus(bb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CScenarioTravel::STravelBonus::SECONDARY_SKILL:
|
||||||
|
hero->setSecSkillLevel(SecondarySkill(curBonus->info2), curBonus->info3, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::initFogOfWar()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tFog of war"; //FIXME: should be initialized after all bonuses are set
|
logGlobal->debugStream() << "\tFog of war"; //FIXME: should be initialized after all bonuses are set
|
||||||
for(auto & elem : teams)
|
for(auto & elem : teams)
|
||||||
{
|
{
|
||||||
@ -1234,7 +1398,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::initStartingBonus()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tStarting bonuses";
|
logGlobal->debugStream() << "\tStarting bonuses";
|
||||||
for(auto & elem : players)
|
for(auto & elem : players)
|
||||||
{
|
{
|
||||||
@ -1276,7 +1443,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/****************************TOWNS************************************************/
|
}
|
||||||
|
|
||||||
|
void CGameState::initTowns()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tTowns";
|
logGlobal->debugStream() << "\tTowns";
|
||||||
|
|
||||||
//campaign bonuses for towns
|
//campaign bonuses for towns
|
||||||
@ -1415,7 +1585,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
if(vti->getOwner() != PlayerColor::NEUTRAL)
|
if(vti->getOwner() != PlayerColor::NEUTRAL)
|
||||||
getPlayer(vti->getOwner())->towns.push_back(vti);
|
getPlayer(vti->getOwner())->towns.push_back(vti);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameState::initMapObjects()
|
||||||
|
{
|
||||||
logGlobal->debugStream() << "\tObject initialization";
|
logGlobal->debugStream() << "\tObject initialization";
|
||||||
objCaller->preInit();
|
objCaller->preInit();
|
||||||
for(CGObjectInstance *obj : map->objects)
|
for(CGObjectInstance *obj : map->objects)
|
||||||
@ -1440,9 +1613,10 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
CGTeleport::postInit(); //pairing subterranean gates
|
CGTeleport::postInit(); //pairing subterranean gates
|
||||||
|
}
|
||||||
|
|
||||||
buildBonusSystemTree();
|
void CGameState::initVisitingAndGarrisonedHeroes()
|
||||||
|
{
|
||||||
for(auto k=players.begin(); k!=players.end(); ++k)
|
for(auto k=players.begin(); k!=players.end(); ++k)
|
||||||
{
|
{
|
||||||
if(k->first==PlayerColor::NEUTRAL)
|
if(k->first==PlayerColor::NEUTRAL)
|
||||||
@ -1468,124 +1642,6 @@ void CGameState::init(StartInfo * si)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
logGlobal->debugStream() << "\tChecking objectives";
|
|
||||||
map->checkForObjectives(); //needs to be run when all objects are properly placed
|
|
||||||
|
|
||||||
int seedAfterInit = ran();
|
|
||||||
logGlobal->infoStream() << "Seed after init is " << seedAfterInit << " (before was " << scenarioOps->seedToBeUsed << ")";
|
|
||||||
if(scenarioOps->seedPostInit > 0)
|
|
||||||
{
|
|
||||||
//RNG must be in the same state on all machines when initialization is done (otherwise we have desync)
|
|
||||||
assert(scenarioOps->seedPostInit == seedAfterInit);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
scenarioOps->seedPostInit = seedAfterInit; //store the post init "seed"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CGameState::initDuel()
|
|
||||||
{
|
|
||||||
DuelParameters dp;
|
|
||||||
try //CLoadFile likes throwing
|
|
||||||
{
|
|
||||||
if(boost::algorithm::ends_with(scenarioOps->mapname, ".json"))
|
|
||||||
{
|
|
||||||
logGlobal->infoStream() << "Loading duel settings from JSON file: " << scenarioOps->mapname;
|
|
||||||
dp = DuelParameters::fromJSON(scenarioOps->mapname);
|
|
||||||
logGlobal->infoStream() << "JSON file has been successfully read!";
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
CLoadFile lf(scenarioOps->mapname);
|
|
||||||
lf >> dp;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(...)
|
|
||||||
{
|
|
||||||
logGlobal->errorStream() << "Cannot load duel settings from " << scenarioOps->mapname;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
const CArmedInstance *armies[2] = {nullptr};
|
|
||||||
const CGHeroInstance *heroes[2] = {nullptr};
|
|
||||||
CGTownInstance *town = nullptr;
|
|
||||||
|
|
||||||
for(int i = 0; i < 2; i++)
|
|
||||||
{
|
|
||||||
CArmedInstance *obj = nullptr;
|
|
||||||
if(dp.sides[i].heroId >= 0)
|
|
||||||
{
|
|
||||||
const DuelParameters::SideSettings &ss = dp.sides[i];
|
|
||||||
auto h = new CGHeroInstance();
|
|
||||||
armies[i] = heroes[i] = h;
|
|
||||||
obj = h;
|
|
||||||
h->subID = ss.heroId;
|
|
||||||
for(int i = 0; i < ss.heroPrimSkills.size(); i++)
|
|
||||||
h->pushPrimSkill(static_cast<PrimarySkill::PrimarySkill>(i), ss.heroPrimSkills[i]);
|
|
||||||
|
|
||||||
if(!ss.spells.empty())
|
|
||||||
{
|
|
||||||
h->putArtifact(ArtifactPosition::SPELLBOOK, CArtifactInstance::createNewArtifactInstance(0));
|
|
||||||
boost::copy(ss.spells, std::inserter(h->spells, h->spells.begin()));
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto &parka : ss.artifacts)
|
|
||||||
{
|
|
||||||
h->putArtifact(ArtifactPosition(parka.first), parka.second);
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef const std::pair<si32, si8> &TSecSKill;
|
|
||||||
for(TSecSKill secSkill : ss.heroSecSkills)
|
|
||||||
h->setSecSkillLevel(SecondarySkill(secSkill.first), secSkill.second, 1);
|
|
||||||
|
|
||||||
h->initHero(HeroTypeID(h->subID));
|
|
||||||
obj->initObj();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto c = new CGCreature();
|
|
||||||
armies[i] = obj = c;
|
|
||||||
//c->subID = 34;
|
|
||||||
}
|
|
||||||
|
|
||||||
obj->setOwner(PlayerColor(i));
|
|
||||||
|
|
||||||
for(int j = 0; j < ARRAY_COUNT(dp.sides[i].stacks); j++)
|
|
||||||
{
|
|
||||||
CreatureID cre = dp.sides[i].stacks[j].type;
|
|
||||||
TQuantity count = dp.sides[i].stacks[j].count;
|
|
||||||
if(count || obj->hasStackAtSlot(SlotID(j)))
|
|
||||||
obj->setCreature(SlotID(j), cre, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(const DuelParameters::CusomCreature &cc : dp.creatures)
|
|
||||||
{
|
|
||||||
CCreature *c = VLC->creh->creatures[cc.id];
|
|
||||||
if(cc.attack >= 0)
|
|
||||||
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::ATTACK))->val = cc.attack;
|
|
||||||
if(cc.defense >= 0)
|
|
||||||
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::PRIMARY_SKILL, PrimarySkill::DEFENSE))->val = cc.defense;
|
|
||||||
if(cc.speed >= 0)
|
|
||||||
c->getBonusLocalFirst(Selector::type(Bonus::STACKS_SPEED))->val = cc.speed;
|
|
||||||
if(cc.HP >= 0)
|
|
||||||
c->getBonusLocalFirst(Selector::type(Bonus::STACK_HEALTH))->val = cc.HP;
|
|
||||||
if(cc.dmg >= 0)
|
|
||||||
{
|
|
||||||
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 1))->val = cc.dmg;
|
|
||||||
c->getBonusLocalFirst(Selector::typeSubtype(Bonus::CREATURE_DAMAGE, 2))->val = cc.dmg;
|
|
||||||
}
|
|
||||||
if(cc.shoots >= 0)
|
|
||||||
c->getBonusLocalFirst(Selector::type(Bonus::SHOTS))->val = cc.shoots;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
curB = BattleInfo::setupBattle(int3(), dp.terType, dp.bfieldType, armies, heroes, false, town);
|
|
||||||
curB->obstacles = dp.obstacles;
|
|
||||||
curB->localInit();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BFieldType CGameState::battleGetBattlefieldType(int3 tile) const
|
BFieldType CGameState::battleGetBattlefieldType(int3 tile) const
|
||||||
@ -2555,14 +2611,12 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::campaignH
|
|||||||
//selecting heroes by type
|
//selecting heroes by type
|
||||||
for(int g=0; g<map->objects.size(); ++g)
|
for(int g=0; g<map->objects.size(); ++g)
|
||||||
{
|
{
|
||||||
const ObjectInstanceID gid = ObjectInstanceID(g);
|
|
||||||
CGObjectInstance * obj = map->objects[g];
|
CGObjectInstance * obj = map->objects[g];
|
||||||
if (obj->ID != Obj::HERO_PLACEHOLDER)
|
if (obj->ID == Obj::HERO_PLACEHOLDER)
|
||||||
{
|
{
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
|
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
|
||||||
|
|
||||||
|
const ObjectInstanceID gid = ObjectInstanceID(g);
|
||||||
if(hp->subID != 0xFF) //select by type
|
if(hp->subID != 0xFF) //select by type
|
||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
@ -2584,6 +2638,7 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::campaignH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//selecting heroes by power
|
//selecting heroes by power
|
||||||
|
|
||||||
@ -2594,14 +2649,12 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::campaignH
|
|||||||
|
|
||||||
for(int g=0; g<map->objects.size(); ++g)
|
for(int g=0; g<map->objects.size(); ++g)
|
||||||
{
|
{
|
||||||
const ObjectInstanceID gid = ObjectInstanceID(g);
|
|
||||||
CGObjectInstance * obj = map->objects[g];
|
CGObjectInstance * obj = map->objects[g];
|
||||||
if (obj->ID != Obj::HERO_PLACEHOLDER)
|
if (obj->ID == Obj::HERO_PLACEHOLDER)
|
||||||
{
|
{
|
||||||
continue;
|
|
||||||
}
|
|
||||||
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
|
CGHeroPlaceholder * hp = static_cast<CGHeroPlaceholder*>(obj);
|
||||||
|
|
||||||
|
const ObjectInstanceID gid = ObjectInstanceID(g);
|
||||||
if (hp->subID == 0xFF) //select by power
|
if (hp->subID == 0xFF) //select by power
|
||||||
{
|
{
|
||||||
if(Xheroes.size() > hp->power - 1)
|
if(Xheroes.size() > hp->power - 1)
|
||||||
@ -2617,6 +2670,7 @@ std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > CGameState::campaignH
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,8 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
class CTown;
|
class CTown;
|
||||||
class CScriptCallback;
|
|
||||||
class CCallback;
|
class CCallback;
|
||||||
class IGameCallback;
|
class IGameCallback;
|
||||||
class CLuaCallback;
|
|
||||||
class CCPPObjectScript;
|
|
||||||
class CCreatureSet;
|
class CCreatureSet;
|
||||||
class CStack;
|
class CStack;
|
||||||
class CQuest;
|
class CQuest;
|
||||||
@ -388,15 +385,6 @@ DLL_LINKAGE std::ostream & operator<<(std::ostream & os, const EVictoryLossCheck
|
|||||||
class DLL_LINKAGE CGameState : public CNonConstInfoCallback
|
class DLL_LINKAGE CGameState : public CNonConstInfoCallback
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
|
|
||||||
PlayerColor currentPlayer; //ID of player currently having turn
|
|
||||||
ConstTransitivePtr<BattleInfo> curB; //current battle
|
|
||||||
ui32 day; //total number of days in game
|
|
||||||
ConstTransitivePtr<CMap> map;
|
|
||||||
std::map<PlayerColor, PlayerState> players;
|
|
||||||
std::map<TeamID, TeamState> teams;
|
|
||||||
CBonusSystemNode globalEffects;
|
|
||||||
|
|
||||||
struct DLL_LINKAGE HeroesPool
|
struct DLL_LINKAGE HeroesPool
|
||||||
{
|
{
|
||||||
std::map<ui32, ConstTransitivePtr<CGHeroInstance> > heroesPool; //[subID] - heroes available to buy; nullptr if not available
|
std::map<ui32, ConstTransitivePtr<CGHeroInstance> > heroesPool; //[subID] - heroes available to buy; nullptr if not available
|
||||||
@ -410,18 +398,22 @@ public:
|
|||||||
}
|
}
|
||||||
} hpool; //we have here all heroes available on this map that are not hired
|
} hpool; //we have here all heroes available on this map that are not hired
|
||||||
|
|
||||||
boost::shared_mutex *mx;
|
CGameState();
|
||||||
|
virtual ~CGameState();
|
||||||
|
|
||||||
void init(StartInfo * si);
|
void init(StartInfo * si);
|
||||||
|
|
||||||
bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
|
ConstTransitivePtr<StartInfo> scenarioOps, initialOpts; //second one is a copy of settings received from pregame (not randomized)
|
||||||
void placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
|
PlayerColor currentPlayer; //ID of player currently having turn
|
||||||
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroesToReplace(); //returns heroes and placeholders in where heroes will be put; may remove some placeholders
|
ConstTransitivePtr<BattleInfo> curB; //current battle
|
||||||
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
ui32 day; //total number of days in game
|
||||||
void initDuel();
|
ConstTransitivePtr<CMap> map;
|
||||||
void randomizeObject(CGObjectInstance *cur);
|
std::map<PlayerColor, PlayerState> players;
|
||||||
std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
std::map<TeamID, TeamState> teams;
|
||||||
int pickHero(PlayerColor owner);
|
CBonusSystemNode globalEffects;
|
||||||
|
|
||||||
|
boost::shared_mutex *mx;
|
||||||
|
|
||||||
void giveHeroArtifact(CGHeroInstance *h, ArtifactID aid);
|
void giveHeroArtifact(CGHeroInstance *h, ArtifactID aid);
|
||||||
|
|
||||||
void apply(CPack *pack);
|
void apply(CPack *pack);
|
||||||
@ -439,38 +431,65 @@ public:
|
|||||||
std::map<ui32, ConstTransitivePtr<CGHeroInstance> > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns
|
std::map<ui32, ConstTransitivePtr<CGHeroInstance> > unusedHeroesFromPool(); //heroes pool without heroes that are available in taverns
|
||||||
BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town);
|
BattleInfo * setupBattle(int3 tile, const CArmedInstance *armies[2], const CGHeroInstance * heroes[2], bool creatureBank, const CGTownInstance *town);
|
||||||
|
|
||||||
void buildBonusSystemTree();
|
|
||||||
void attachArmedObjects();
|
|
||||||
void buildGlobalTeamPlayerTree();
|
|
||||||
void deserializationFix();
|
|
||||||
|
|
||||||
bool isVisible(int3 pos, PlayerColor player);
|
bool isVisible(int3 pos, PlayerColor player);
|
||||||
bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> player);
|
bool isVisible(const CGObjectInstance *obj, boost::optional<PlayerColor> player);
|
||||||
|
|
||||||
CGameState(); //c-tor
|
|
||||||
virtual ~CGameState(); //d-tor
|
|
||||||
void getNeighbours(const TerrainTile &srct, int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand, bool limitCoastSailing);
|
void getNeighbours(const TerrainTile &srct, int3 tile, std::vector<int3> &vec, const boost::logic::tribool &onLand, bool limitCoastSailing);
|
||||||
int getMovementCost(const CGHeroInstance *h, const int3 &src, const int3 &dest, int remainingMovePoints=-1, bool checkLast=true);
|
int getMovementCost(const CGHeroInstance *h, const int3 &src, const int3 &dest, int remainingMovePoints=-1, bool checkLast=true);
|
||||||
int getDate(Date::EDateType mode=Date::DAY) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
int getDate(Date::EDateType mode=Date::DAY) const; //mode=0 - total days in game, mode=1 - day of week, mode=2 - current week, mode=3 - current month
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int version)
|
template <typename Handler> void serialize(Handler &h, const int version)
|
||||||
{
|
{
|
||||||
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects;
|
h & scenarioOps & initialOpts & currentPlayer & day & map & players & teams & hpool & globalEffects;
|
||||||
BONUS_TREE_DESERIALIZATION_FIX
|
BONUS_TREE_DESERIALIZATION_FIX
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class CCallback;
|
|
||||||
friend class CLuaCallback;
|
|
||||||
friend class CClient;
|
|
||||||
friend void initGameState(CMap * map, CGameInfo * cgi);
|
|
||||||
friend class IGameCallback;
|
|
||||||
friend class CMapHandler;
|
|
||||||
friend class CGameHandler;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// Init game state
|
||||||
|
void initNewGame();
|
||||||
|
void initCampaign();
|
||||||
|
void initDuel();
|
||||||
|
void checkMapChecksum();
|
||||||
|
void initGrailPosition();
|
||||||
|
void initRandomFactionsForPlayers();
|
||||||
|
void randomizeMapObjects();
|
||||||
|
void randomizeObject(CGObjectInstance *cur);
|
||||||
|
void initPlayerStates();
|
||||||
|
void initHeroPlaceholders();
|
||||||
|
void placeCampaignHeroes(const std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > &campHeroReplacements);
|
||||||
|
void placeStartingHeroes();
|
||||||
|
void initStartingResources();
|
||||||
|
void initHeroes();
|
||||||
|
void giveCampaignBonusToHero(CGHeroInstance * hero);
|
||||||
|
void initFogOfWar();
|
||||||
|
void initStartingBonus();
|
||||||
|
void initTowns();
|
||||||
|
void initMapObjects();
|
||||||
|
void initVisitingAndGarrisonedHeroes();
|
||||||
|
|
||||||
|
// Victory / Loss condition checks
|
||||||
EVictoryLossCheckResult checkForVictory(PlayerColor player) const; //checks if given player is winner
|
EVictoryLossCheckResult checkForVictory(PlayerColor player) const; //checks if given player is winner
|
||||||
EVictoryLossCheckResult checkForLoss(PlayerColor player) const; //checks if given player is loser
|
EVictoryLossCheckResult checkForLoss(PlayerColor player) const; //checks if given player is loser
|
||||||
PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
|
PlayerColor checkForStandardWin() const; //returns color of player that accomplished standard victory conditions or 255 (NEUTRAL) if no winner
|
||||||
bool checkForStandardLoss(PlayerColor player) const; //checks if given player lost the game
|
bool checkForStandardLoss(PlayerColor player) const; //checks if given player lost the game
|
||||||
|
|
||||||
|
// Bonus system handling
|
||||||
|
void buildBonusSystemTree();
|
||||||
|
void attachArmedObjects();
|
||||||
|
void buildGlobalTeamPlayerTree();
|
||||||
|
void deserializationFix();
|
||||||
|
|
||||||
|
bool isUsedHero(HeroTypeID hid) const; //looks in heroes and prisons
|
||||||
|
std::vector<std::pair<CGHeroInstance*, ObjectInstanceID> > campaignHeroesToReplace(); //returns heroes and placeholders in where heroes will be put; may remove some placeholders
|
||||||
|
std::set<HeroTypeID> getUnusedAllowedHeroes(bool alsoIncludeNotAllowed = false) const;
|
||||||
|
std::pair<Obj,int> pickObject(CGObjectInstance *obj); //chooses type of object to be randomized, returns <type, subtype>
|
||||||
|
int pickHero(PlayerColor owner);
|
||||||
|
|
||||||
|
friend class CCallback;
|
||||||
|
friend class CClient;
|
||||||
|
friend class IGameCallback;
|
||||||
|
friend class CMapHandler;
|
||||||
|
friend class CGameHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
struct DLL_LINKAGE QuestInfo //universal interface for human and AI
|
||||||
|
@ -25,7 +25,6 @@ struct BattleInfo;
|
|||||||
struct QuestInfo;
|
struct QuestInfo;
|
||||||
class IGameCallback;
|
class IGameCallback;
|
||||||
struct BattleResult;
|
struct BattleResult;
|
||||||
class CCPPObjectScript;
|
|
||||||
class CGObjectInstance;
|
class CGObjectInstance;
|
||||||
class CScript;
|
class CScript;
|
||||||
class CObjectScript;
|
class CObjectScript;
|
||||||
|
@ -443,10 +443,9 @@ boost::optional<CScenarioTravel::STravelBonus> CCampaignState::getBonusForCurren
|
|||||||
{
|
{
|
||||||
auto bonuses = getCurrentScenario().travelOptions.bonusesToChoose;
|
auto bonuses = getCurrentScenario().travelOptions.bonusesToChoose;
|
||||||
assert(chosenCampaignBonuses.count(*currentMap) || bonuses.size() == 0);
|
assert(chosenCampaignBonuses.count(*currentMap) || bonuses.size() == 0);
|
||||||
if(bonuses.size())
|
|
||||||
return bonuses[currentBonusID()];
|
if(bonuses.empty()) return boost::optional<CScenarioTravel::STravelBonus>();
|
||||||
else
|
else return bonuses[currentBonusID()];
|
||||||
return boost::optional<CScenarioTravel::STravelBonus>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const CCampaignScenario & CCampaignState::getCurrentScenario() const
|
const CCampaignScenario & CCampaignState::getCurrentScenario() const
|
||||||
|
@ -83,16 +83,6 @@ public:
|
|||||||
class DLL_LINKAGE CCampaignScenario
|
class DLL_LINKAGE CCampaignScenario
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
std::string mapName; //*.h3m
|
|
||||||
std::string scenarioName; //from header. human-readble
|
|
||||||
ui32 packedMapSize; //generally not used
|
|
||||||
std::set<ui8> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
|
|
||||||
ui8 regionColor;
|
|
||||||
ui8 difficulty;
|
|
||||||
bool conquered;
|
|
||||||
|
|
||||||
std::string regionText;
|
|
||||||
|
|
||||||
struct DLL_LINKAGE SScenarioPrologEpilog
|
struct DLL_LINKAGE SScenarioPrologEpilog
|
||||||
{
|
{
|
||||||
bool hasPrologEpilog;
|
bool hasPrologEpilog;
|
||||||
@ -106,17 +96,23 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
std::string mapName; //*.h3m
|
||||||
|
std::string scenarioName; //from header. human-readble
|
||||||
|
ui32 packedMapSize; //generally not used
|
||||||
|
std::set<ui8> preconditionRegions; //what we need to conquer to conquer this one (stored as bitfield in h3c)
|
||||||
|
ui8 regionColor;
|
||||||
|
ui8 difficulty;
|
||||||
|
bool conquered;
|
||||||
|
|
||||||
|
std::string regionText;
|
||||||
SScenarioPrologEpilog prolog, epilog;
|
SScenarioPrologEpilog prolog, epilog;
|
||||||
|
|
||||||
CScenarioTravel travelOptions;
|
CScenarioTravel travelOptions;
|
||||||
|
|
||||||
std::vector<CGHeroInstance *> crossoverHeroes;
|
std::vector<CGHeroInstance *> crossoverHeroes;
|
||||||
|
|
||||||
const CGHeroInstance * strongestHero(PlayerColor owner) const;
|
const CGHeroInstance * strongestHero(PlayerColor owner) const;
|
||||||
|
|
||||||
void loadPreconditionRegions(ui32 regions);
|
void loadPreconditionRegions(ui32 regions);
|
||||||
void prepareCrossoverHeroes(std::vector<CGHeroInstance *> heroes);
|
void prepareCrossoverHeroes(std::vector<CGHeroInstance *> heroes);
|
||||||
|
|
||||||
bool isNotVoid() const;
|
bool isNotVoid() const;
|
||||||
|
|
||||||
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
template <typename Handler> void serialize(Handler &h, const int formatVersion)
|
||||||
|
@ -24,8 +24,6 @@ class CGameHandler;
|
|||||||
class CVCMIServer;
|
class CVCMIServer;
|
||||||
class CGameState;
|
class CGameState;
|
||||||
struct StartInfo;
|
struct StartInfo;
|
||||||
class CCPPObjectScript;
|
|
||||||
class CScriptCallback;
|
|
||||||
struct BattleResult;
|
struct BattleResult;
|
||||||
struct BattleAttack;
|
struct BattleAttack;
|
||||||
struct BattleStackAttacked;
|
struct BattleStackAttacked;
|
||||||
@ -286,7 +284,6 @@ public:
|
|||||||
bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition slot);
|
bool sacrificeArtifact(const IMarket * m, const CGHeroInstance * hero, ArtifactPosition slot);
|
||||||
void spawnWanderingMonsters(CreatureID creatureID);
|
void spawnWanderingMonsters(CreatureID creatureID);
|
||||||
friend class CVCMIServer;
|
friend class CVCMIServer;
|
||||||
friend class CScriptCallback;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::list<PlayerColor> generatePlayerTurnOrder() const;
|
std::list<PlayerColor> generatePlayerTurnOrder() const;
|
||||||
|
Reference in New Issue
Block a user