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

Spawn quest arts in nearby zones.

This commit is contained in:
DjWarmonger 2015-03-01 10:20:49 +01:00
parent 67ab90616d
commit 9453250e0f
4 changed files with 157 additions and 100 deletions

View File

@ -241,6 +241,7 @@ void CMapGenerator::fillZones()
it.second->initFreeTiles(this);
}
findZonesForQuestArts();
createConnections();
//make sure all connections are passable before creating borders
for (auto it : zones)
@ -270,6 +271,26 @@ void CMapGenerator::fillZones()
logGlobal->infoStream() << "Zones filled successfully";
}
void CMapGenerator::findZonesForQuestArts()
{
//we want to place arties in zones that were not yet filled (higher index)
for (auto connection : mapGenOptions->getMapTemplate()->getConnections())
{
auto zoneA = connection.getZoneA();
auto zoneB = connection.getZoneB();
if (zoneA->getId() > zoneB->getId())
{
zoneB->setQuestArtZone(zoneA);
}
else if (zoneA->getId() < zoneB->getId())
{
zoneA->setQuestArtZone(zoneB);
}
}
}
void CMapGenerator::createConnections()
{
for (auto connection : mapGenOptions->getMapTemplate()->getConnections())

View File

@ -64,6 +64,7 @@ public:
std::map<TRmgTemplateZoneId, CRmgTemplateZone*> getZones() const;
void createConnections();
void findZonesForQuestArts();
void foreach_neighbour(const int3 &pos, std::function<void(int3& pos)> foo);
bool isBlocked(const int3 &tile) const;

View File

@ -144,7 +144,8 @@ CRmgTemplateZone::CRmgTemplateZone() :
townType(ETownType::NEUTRAL),
terrainType (ETerrainType::GRASS),
zoneMonsterStrength(EMonsterStrength::ZONE_NORMAL),
minGuardedValue(0)
minGuardedValue(0),
questArtZone(nullptr)
{
terrainTypes = getDefaultTerrainTypes();
}
@ -297,6 +298,11 @@ void CRmgTemplateZone::addConnection(TRmgTemplateZoneId otherZone)
connections.push_back (otherZone);
}
void CRmgTemplateZone::setQuestArtZone(CRmgTemplateZone * otherZone)
{
questArtZone = otherZone;
}
std::vector<TRmgTemplateZoneId> CRmgTemplateZone::getConnections() const
{
return connections;
@ -2259,120 +2265,147 @@ void CRmgTemplateZone::addAllPossibleObjects(CMapGenerator* gen)
//seer huts with creatures or generic rewards
static const int genericSeerHuts = 8;
int seerHutsPerType = 0;
const int questArtsRemaining = gen->getQuestArtsRemaning().size();
std::vector<CCreature *> creatures;
for (auto cre : VLC->creh->creatures)
if (questArtZone) //we won't be placing seer huts if there is no zone left to place arties
{
if (cre->faction == townType)
static const int genericSeerHuts = 8;
int seerHutsPerType = 0;
const int questArtsRemaining = gen->getQuestArtsRemaning().size();
std::vector<CCreature *> creatures;
for (auto cre : VLC->creh->creatures)
{
creatures.push_back(cre);
if (cre->faction == townType)
{
creatures.push_back(cre);
}
}
}
//general issue is that not many artifact types are available for quests
//general issue is that not many artifact types are available for quests
if (questArtsRemaining >= genericSeerHuts + creatures.size())
{
seerHutsPerType = questArtsRemaining / (genericSeerHuts + creatures.size());
}
else if (questArtsRemaining >= genericSeerHuts)
{
seerHutsPerType = 1;
}
oi.maxPerZone = seerHutsPerType;
RandomGeneratorUtil::randomShuffle(creatures, gen->rand);
for (int i = 0; i < std::min<int>(creatures.size(), questArtsRemaining - genericSeerHuts); i++)
{
auto creature = creatures[i];
int creaturesAmount = creatureToCount(creature);
if (!creaturesAmount)
continue;
int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
oi.generateObject = [creature, creaturesAmount, randomAppearance, gen]() -> CGObjectInstance *
if (questArtsRemaining >= genericSeerHuts + creatures.size())
{
auto obj = new CGSeerHut();
obj->ID = Obj::SEER_HUT;
obj->subID = randomAppearance;
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);
gen->map->addQuest(obj);
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);
}
static int seerExpGold[] = { 5000, 10000, 15000, 20000 };
static int seerValues[] = { 2000, 5333, 8666, 12000};
for (int i = 0; i < 4; i++) //seems that code for exp and gold reward is similiar
{
int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
oi.setTemplate(Obj::SEER_HUT, randomAppearance, terrainType);
oi.value = seerValues[i];
oi.probability = 10;
oi.generateObject = [i, randomAppearance, gen]() -> CGObjectInstance *
seerHutsPerType = questArtsRemaining / (genericSeerHuts + creatures.size());
}
else if (questArtsRemaining >= genericSeerHuts)
{
auto obj = new CGSeerHut();
obj->ID = Obj::SEER_HUT;
obj->subID = randomAppearance;
obj->rewardType = CGSeerHut::EXPERIENCE;
obj->rID = 0; //unitialized?
obj->rVal = seerExpGold[i];
seerHutsPerType = 1;
}
oi.maxPerZone = seerHutsPerType;
obj->quest->missionType = CQuest::MISSION_ART;
ArtifactID artid = *RandomGeneratorUtil::nextItem(gen->getQuestArtsRemaning(), gen->rand);
obj->quest->m5arts.push_back(artid);
gen->banQuestArt(artid);
gen->map->addQuest(obj);
RandomGeneratorUtil::randomShuffle(creatures, gen->rand);
return obj;
//TODO: place required artifact in next zone
auto generateArtInfo = [](ArtifactID id) -> ObjectInfo
{
ObjectInfo artInfo;
artInfo.probability = 1e6; //99,9% to spawn that art in first treasure pile
artInfo.maxPerZone = 1;
artInfo.value = 2000; //treasure art
artInfo.generateObject = [id]() -> CGObjectInstance *
{
auto obj = new CGArtifact;
obj->ID = Obj::ARTIFACT;
obj->subID = id;
return obj;
//TODO: place required artifact in next zone
};
return artInfo;
};
possibleObjects.push_back(oi);
oi.generateObject = [i, randomAppearance, gen]() -> CGObjectInstance *
for (int i = 0; i < std::min<int>(creatures.size(), questArtsRemaining - genericSeerHuts); i++)
{
auto obj = new CGSeerHut();
obj->ID = Obj::SEER_HUT;
obj->subID = randomAppearance;
obj->rewardType = CGSeerHut::RESOURCES;
obj->rID = Res::GOLD;
obj->rVal = seerExpGold[i];
auto creature = creatures[i];
int creaturesAmount = creatureToCount(creature);
obj->quest->missionType = CQuest::MISSION_ART;
ArtifactID artid = *RandomGeneratorUtil::nextItem(gen->getQuestArtsRemaning(), gen->rand);
obj->quest->m5arts.push_back(artid);
gen->banQuestArt(artid);
gen->map->addQuest(obj);
if (!creaturesAmount)
continue;
return obj;
//TODO: place required artifact in next zone
};
int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
possibleObjects.push_back(oi);
oi.generateObject = [creature, creaturesAmount, randomAppearance, gen, this, generateArtInfo]() -> CGObjectInstance *
{
auto obj = new CGSeerHut();
obj->ID = Obj::SEER_HUT;
obj->subID = randomAppearance;
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);
gen->map->addQuest(obj);
this->questArtZone->possibleObjects.push_back (generateArtInfo(artid));
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);
}
static int seerExpGold[] = { 5000, 10000, 15000, 20000 };
static int seerValues[] = { 2000, 5333, 8666, 12000 };
for (int i = 0; i < 4; i++) //seems that code for exp and gold reward is similiar
{
int randomAppearance = *RandomGeneratorUtil::nextItem(VLC->objtypeh->knownSubObjects(Obj::SEER_HUT), gen->rand);
oi.setTemplate(Obj::SEER_HUT, randomAppearance, terrainType);
oi.value = seerValues[i];
oi.probability = 10;
oi.generateObject = [i, randomAppearance, gen, this, generateArtInfo]() -> CGObjectInstance *
{
auto obj = new CGSeerHut();
obj->ID = Obj::SEER_HUT;
obj->subID = randomAppearance;
obj->rewardType = CGSeerHut::EXPERIENCE;
obj->rID = 0; //unitialized?
obj->rVal = seerExpGold[i];
obj->quest->missionType = CQuest::MISSION_ART;
ArtifactID artid = *RandomGeneratorUtil::nextItem(gen->getQuestArtsRemaning(), gen->rand);
obj->quest->m5arts.push_back(artid);
gen->banQuestArt(artid);
gen->map->addQuest(obj);
this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));
return obj;
//TODO: place required artifact in next zone
};
possibleObjects.push_back(oi);
oi.generateObject = [i, randomAppearance, gen, this, generateArtInfo]() -> CGObjectInstance *
{
auto obj = new CGSeerHut();
obj->ID = Obj::SEER_HUT;
obj->subID = randomAppearance;
obj->rewardType = CGSeerHut::RESOURCES;
obj->rID = Res::GOLD;
obj->rVal = seerExpGold[i];
obj->quest->missionType = CQuest::MISSION_ART;
ArtifactID artid = *RandomGeneratorUtil::nextItem(gen->getQuestArtsRemaning(), gen->rand);
obj->quest->m5arts.push_back(artid);
gen->banQuestArt(artid);
gen->map->addQuest(obj);
this->questArtZone->possibleObjects.push_back(generateArtInfo(artid));
return obj;
//TODO: place required artifact in next zone
};
possibleObjects.push_back(oi);
}
}
}

View File

@ -169,6 +169,7 @@ public:
std::vector<int3> getAccessibleOffsets (CMapGenerator* gen, CGObjectInstance* object);
void addConnection(TRmgTemplateZoneId otherZone);
void setQuestArtZone(CRmgTemplateZone * otherZone);
std::vector<TRmgTemplateZoneId> getConnections() const;
void addTreasureInfo(CTreasureInfo & info);
std::vector<CTreasureInfo> getTreasureInfo();
@ -194,6 +195,7 @@ private:
si32 townType;
ETerrainType terrainType;
CRmgTemplateZone * questArtZone; //artifacts required for Seer Huts will be placed here - or not if null
EMonsterStrength::EMonsterStrength zoneMonsterStrength;
std::vector<CTreasureInfo> treasureInfo;