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:
parent
67ab90616d
commit
9453250e0f
@ -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())
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user