1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Seer Huts part 2.

This commit is contained in:
DjWarmonger 2015-02-28 22:37:04 +01:00
parent 607375a9bc
commit 4f1d96e5e8
3 changed files with 94 additions and 81 deletions

View File

@ -79,11 +79,10 @@ void CMapGenerator::initPrisonsRemaining()
void CMapGenerator::initQuestArtsRemaining() void CMapGenerator::initQuestArtsRemaining()
{ {
questArtsRemaining = 0;
for (auto art : VLC->arth->artifacts) for (auto art : VLC->arth->artifacts)
{ {
if (art->aClass == CArtifact::ART_TREASURE && art->constituentOf.empty()) //don't use parts of combined artifacts if (art->aClass == CArtifact::ART_TREASURE && art->constituentOf.empty()) //don't use parts of combined artifacts
questArtsRemaining++; questArtifacts.push_back(art->id);
} }
} }
@ -497,13 +496,14 @@ void CMapGenerator::decreasePrisonsRemaining()
prisonsRemaining = std::max (0, prisonsRemaining - 1); prisonsRemaining = std::max (0, prisonsRemaining - 1);
} }
int CMapGenerator::getQuestArtsRemaning() const std::vector<ArtifactID> CMapGenerator::getQuestArtsRemaning() const
{ {
return questArtsRemaining; return questArtifacts;
} }
void CMapGenerator::decreaseQuestArtsRemaining() void CMapGenerator::banQuestArt(ArtifactID id)
{ {
questArtsRemaining = std::max(0, questArtsRemaining - 1); map->allowedArtifact[id] = false;
vstd::erase_if_present (questArtifacts, id);
} }
void CMapGenerator::registerZone (TFaction faction) void CMapGenerator::registerZone (TFaction faction)

View File

@ -80,8 +80,8 @@ public:
int getNextMonlithIndex(); int getNextMonlithIndex();
int getPrisonsRemaning() const; int getPrisonsRemaning() const;
void decreasePrisonsRemaining(); void decreasePrisonsRemaining();
int getQuestArtsRemaning() const; std::vector<ArtifactID> getQuestArtsRemaning() const;
void decreaseQuestArtsRemaining(); void banQuestArt(ArtifactID id);
void registerZone (TFaction faction); void registerZone (TFaction faction);
ui32 getZoneCount(TFaction faction); ui32 getZoneCount(TFaction faction);
@ -97,6 +97,7 @@ private:
int prisonsRemaining; int prisonsRemaining;
int questArtsRemaining; int questArtsRemaining;
int monolithIndex; int monolithIndex;
std::vector<ArtifactID> questArtifacts;
/// Generation methods /// Generation methods
std::string getMapDescription() const; std::string getMapDescription() const;

View File

@ -1917,18 +1917,18 @@ ObjectInfo CRmgTemplateZone::getRandomObject(CMapGenerator* gen, CTreasurePileIn
//FIXME: control reaches end of non-void function. Missing return? //FIXME: control reaches end of non-void function. Missing return?
} }
void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen) void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
{ {
ObjectInfo oi; ObjectInfo oi;
oi.maxPerMap = std::numeric_limits<ui32>().max(); oi.maxPerMap = std::numeric_limits<ui32>().max();
int numZones = gen->getZones().size(); int numZones = gen->getZones().size();
for (auto primaryID : VLC->objtypeh->knownObjects()) for (auto primaryID : VLC->objtypeh->knownObjects())
{ {
for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID)) for (auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
{ {
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID); auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
if (!handler->isStaticObject() && handler->getRMGInfo().value) if (!handler->isStaticObject() && handler->getRMGInfo().value)
{ {
for (auto temp : handler->getTemplates()) for (auto temp : handler->getTemplates())
@ -1944,18 +1944,18 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
oi.probability = rmgInfo.rarity; oi.probability = rmgInfo.rarity;
oi.templ = temp; oi.templ = temp;
oi.maxPerZone = rmgInfo.zoneLimit; oi.maxPerZone = rmgInfo.zoneLimit;
vstd::amin (oi.maxPerZone, rmgInfo.mapLimit / numZones); //simple, but should distribute objects evenly on large maps vstd::amin(oi.maxPerZone, rmgInfo.mapLimit / numZones); //simple, but should distribute objects evenly on large maps
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
} }
} }
} }
} }
//prisons //prisons
//levels 1, 5, 10, 20, 30 //levels 1, 5, 10, 20, 30
static int prisonExp[] = {0, 5000, 15000, 90000, 500000}; static int prisonExp[] = { 0, 5000, 15000, 90000, 500000 };
static int prisonValues[] = {2500, 5000, 10000, 20000, 30000}; static int prisonValues[] = { 2500, 5000, 10000, 20000, 30000 };
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@ -1981,11 +1981,11 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
return obj; return obj;
}; };
oi.setTemplate (Obj::PRISON, 0, terrainType); oi.setTemplate(Obj::PRISON, 0, terrainType);
oi.value = prisonValues[i]; oi.value = prisonValues[i];
oi.probability = 30; oi.probability = 30;
oi.maxPerZone = gen->getPrisonsRemaning() / 5; //probably not perfect, but we can't generate more prisons than hereos. oi.maxPerZone = gen->getPrisonsRemaning() / 5; //probably not perfect, but we can't generate more prisons than hereos.
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
//all following objects are unlimited //all following objects are unlimited
@ -1996,7 +1996,7 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
auto subObjects = VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1); auto subObjects = VLC->objtypeh->knownSubObjects(Obj::CREATURE_GENERATOR1);
//don't spawn original "neutral" dwellings that got replaced by Conflux dwellings in AB //don't spawn original "neutral" dwellings that got replaced by Conflux dwellings in AB
static int elementalConfluxROE[] = {7, 13, 16, 47}; static int elementalConfluxROE[] = { 7, 13, 16, 47 };
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
vstd::erase_if_present(subObjects, elementalConfluxROE[i]); vstd::erase_if_present(subObjects, elementalConfluxROE[i]);
@ -2027,13 +2027,13 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
}; };
oi.templ = temp; oi.templ = temp;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
} }
} }
} }
static const int scrollValues[] = {500, 2000, 3000, 4000, 5000}; static const int scrollValues[] = { 500, 2000, 3000, 4000, 5000 };
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
@ -2048,7 +2048,7 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
for (ui32 spellid = 0; spellid < gen->map->allowedSpell.size(); spellid++) //spellh size appears to be greater (?) for (ui32 spellid = 0; spellid < gen->map->allowedSpell.size(); spellid++) //spellh size appears to be greater (?)
{ {
const CSpell *spell = SpellID(spellid).toSpell(); const CSpell *spell = SpellID(spellid).toSpell();
if (gen->map->allowedSpell[spell->id] && spell->level == i+1) if (gen->map->allowedSpell[spell->id] && spell->level == i + 1)
{ {
out.push_back(spell->id); out.push_back(spell->id);
} }
@ -2058,10 +2058,10 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
obj->storedArtifact = a; obj->storedArtifact = a;
return obj; return obj;
}; };
oi.setTemplate (Obj::SPELL_SCROLL, 0, terrainType); oi.setTemplate(Obj::SPELL_SCROLL, 0, terrainType);
oi.value = scrollValues[i]; oi.value = scrollValues[i];
oi.probability = 30; oi.probability = 30;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
//pandora box with gold //pandora box with gold
@ -2075,10 +2075,10 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
obj->resources[Res::GOLD] = i * 5000; obj->resources[Res::GOLD] = i * 5000;
return obj; return obj;
}; };
oi.setTemplate (Obj::PANDORAS_BOX, 0, terrainType); oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType);
oi.value = i * 5000;; oi.value = i * 5000;;
oi.probability = 5; oi.probability = 5;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
//pandora box with experience //pandora box with experience
@ -2092,14 +2092,14 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
obj->gainedExp = i * 5000; obj->gainedExp = i * 5000;
return obj; return obj;
}; };
oi.setTemplate (Obj::PANDORAS_BOX, 0, terrainType); oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType);
oi.value = i * 6000;; oi.value = i * 6000;;
oi.probability = 20; oi.probability = 20;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
//pandora box with creatures //pandora box with creatures
static const int tierValues[] = {5000, 7000, 9000, 12000, 16000, 21000, 27000}; static const int tierValues[] = { 5000, 7000, 9000, 12000, 16000, 21000, 27000 };
auto creatureToCount = [](CCreature * creature) -> int auto creatureToCount = [](CCreature * creature) -> int
{ {
@ -2143,10 +2143,10 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
obj->creatures.putStack(SlotID(0), stack); obj->creatures.putStack(SlotID(0), stack);
return obj; return obj;
}; };
oi.setTemplate (Obj::PANDORAS_BOX, 0, terrainType); oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType);
oi.value = (2 * (creature->AIValue) * creaturesAmount * (1 + (float)(gen->getZoneCount(creature->faction)) / gen->getTotalZoneCount()))/3; oi.value = (2 * (creature->AIValue) * creaturesAmount * (1 + (float)(gen->getZoneCount(creature->faction)) / gen->getTotalZoneCount())) / 3;
oi.probability = 3; oi.probability = 3;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
} }
@ -2169,15 +2169,15 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
RandomGeneratorUtil::randomShuffle(spells, gen->rand); RandomGeneratorUtil::randomShuffle(spells, gen->rand);
for (int j = 0; j < std::min<int>(12, spells.size()); j++) for (int j = 0; j < std::min<int>(12, spells.size()); j++)
{ {
obj->spells.push_back (spells[j]->id); obj->spells.push_back(spells[j]->id);
} }
return obj; return obj;
}; };
oi.setTemplate (Obj::PANDORAS_BOX, 0, terrainType); oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType);
oi.value = (i + 1) * 2500; //5000 - 15000 oi.value = (i + 1) * 2500; //5000 - 15000
oi.probability = 2; oi.probability = 2;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
//Pandora with 15 spells of certain school //Pandora with 15 spells of certain school
@ -2197,18 +2197,18 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
bool school = false; //TODO: we could have better interface for iterating schools bool school = false; //TODO: we could have better interface for iterating schools
switch (i) switch (i)
{ {
case 1: case 1:
school = spell->air; school = spell->air;
break; break;
case 2: case 2:
school = spell->earth; school = spell->earth;
break; break;
case 3: case 3:
school = spell->fire; school = spell->fire;
break; break;
case 4: case 4:
school = spell->water; school = spell->water;
break; break;
} }
if (school) if (school)
spells.push_back(spell); spells.push_back(spell);
@ -2218,15 +2218,15 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
RandomGeneratorUtil::randomShuffle(spells, gen->rand); RandomGeneratorUtil::randomShuffle(spells, gen->rand);
for (int j = 0; j < std::min<int>(15, spells.size()); j++) for (int j = 0; j < std::min<int>(15, spells.size()); j++)
{ {
obj->spells.push_back (spells[j]->id); obj->spells.push_back(spells[j]->id);
} }
return obj; return obj;
}; };
oi.setTemplate (Obj::PANDORAS_BOX, 0, terrainType); oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType);
oi.value = 15000; oi.value = 15000;
oi.probability = 2; oi.probability = 2;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
} }
// Pandora box with 60 random spells // Pandora box with 60 random spells
@ -2247,21 +2247,21 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
RandomGeneratorUtil::randomShuffle(spells, gen->rand); RandomGeneratorUtil::randomShuffle(spells, gen->rand);
for (int j = 0; j < std::min<int>(60, spells.size()); j++) for (int j = 0; j < std::min<int>(60, spells.size()); j++)
{ {
obj->spells.push_back (spells[j]->id); obj->spells.push_back(spells[j]->id);
} }
return obj; return obj;
}; };
oi.setTemplate (Obj::PANDORAS_BOX, 0, terrainType); oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType);
oi.value = 3000; oi.value = 3000;
oi.probability = 2; oi.probability = 2;
possibleObjects.push_back (oi); possibleObjects.push_back(oi);
//seer huts with creatures or generic rewards //seer huts with creatures or generic rewards
static const int genericSeerHuts = 8; static const int genericSeerHuts = 8;
int seerHutsPerType = 0; int seerHutsPerType = 0;
const int questArtsRemaining = gen->getQuestArtsRemaning(); const int questArtsRemaining = gen->getQuestArtsRemaning().size();
std::vector<CCreature *> creatures; std::vector<CCreature *> creatures;
@ -2286,32 +2286,44 @@ void CRmgTemplateZone::addAllPossibleObjects (CMapGenerator* gen)
RandomGeneratorUtil::randomShuffle(creatures, gen->rand); RandomGeneratorUtil::randomShuffle(creatures, gen->rand);
for (int i = 0; i < std::min<int>(creatures.size(), questArtsRemaining - genericSeerHuts); i++) for (int loops = 0; loops < seerHutsPerType; loops++) //in case there are many arties available
{ {
auto creature = creatures[i]; for (int i = 0; i < std::min<int>(creatures.size(), questArtsRemaining - genericSeerHuts); i++)
int creaturesAmount = creatureToCount(creature);
if (!creaturesAmount)
continue;
//int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand); //FIXME: empty subids?
int randomAppearance = 0;
oi.generateObject = [creature, creaturesAmount, randomAppearance, gen]() -> CGObjectInstance *
{ {
auto obj = new CGSeerHut(); auto creature = creatures[i];
obj->ID = Obj::SEER_HUT; int creaturesAmount = creatureToCount(creature);
obj->subID = randomAppearance;
obj->rewardType = CGSeerHut::CREATURE; if (!creaturesAmount)
obj->rID = creature->idNumber; continue;
obj->rVal = creaturesAmount;
gen->decreaseQuestArtsRemaining(); int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
return obj;
//TODO: place required artifact in next zone oi.generateObject = [creature, creaturesAmount, randomAppearance, gen]() -> CGObjectInstance *
}; {
oi.setTemplate(Obj::PANDORAS_BOX, randomAppearance, terrainType); auto obj = new CGSeerHut();
oi.value = ((2 * (creature->AIValue) * creaturesAmount * (1 + (float)(gen->getZoneCount(creature->faction)) / gen->getTotalZoneCount())) - 4000) / 3; obj->ID = Obj::SEER_HUT;
oi.probability = 3; obj->subID = randomAppearance;
possibleObjects.push_back(oi); obj->rewardType = CGSeerHut::CREATURE;
obj->rID = creature->idNumber;
obj->rVal = creaturesAmount;
obj->quest->missionType = CQuest::MISSION_ART;
ArtifactID artid = *RandomGeneratorUtil::nextItem(gen->getQuestArtsRemaning(), gen->rand);
obj->quest->m5arts.push_back(artid);
gen->banQuestArt(artid);
obj->quest->lastDay = -1;
obj->quest->isCustomFirst = false;
obj->quest->isCustomNext = false;
obj->quest->isCustomComplete = false;
return obj;
//TODO: place required artifact in next zone
};
oi.setTemplate(Obj::SEER_HUT, randomAppearance, terrainType);
oi.value = ((2 * (creature->AIValue) * creaturesAmount * (1 + (float)(gen->getZoneCount(creature->faction)) / gen->getTotalZoneCount())) - 4000) / 3;
oi.probability = 3;
possibleObjects.push_back(oi);
}
} }
} }