Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[0002285] Implement feature with extra resources near mines #742

Merged
merged 7 commits into from May 23, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
83 changes: 73 additions & 10 deletions lib/rmg/CRmgTemplateZone.cpp
Expand Up @@ -790,6 +790,10 @@ void CRmgTemplateZone::addCloseObject(CGObjectInstance * obj, si32 strength)
{
closeObjects.push_back(std::make_pair(obj, strength));
}
void CRmgTemplateZone::addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget)
{
nearbyObjects.push_back(std::make_pair(obj, nearbyTarget));
}

void CRmgTemplateZone::addToConnectLater(const int3& src)
{
Expand Down Expand Up @@ -1106,14 +1110,17 @@ void CRmgTemplateZone::initTownType ()
//cut a ring around town to ensure crunchPath always hits it.
auto cutPathAroundTown = [this](const CGTownInstance * town)
{
auto clearPos = [this](const int3 & pos)
{
if (gen->isPossible(pos))
gen->setOccupied(pos, ETileType::FREE);
};
for (auto blockedTile : town->getBlockedPos())
{
gen->foreach_neighbour(blockedTile, [this](const int3 & pos)
{
if (gen->isPossible(pos))
gen->setOccupied(pos, ETileType::FREE);
});
gen->foreach_neighbour(blockedTile, clearPos);
}
//clear town entry
gen->foreach_neighbour(town->visitablePos()+int3{0,1,0}, clearPos);
};

auto addNewTowns = [&totalTowns, this, &cutPathAroundTown](int count, bool hasFort, PlayerColor player)
Expand Down Expand Up @@ -1297,7 +1304,7 @@ bool CRmgTemplateZone::placeMines ()
static const Res::ERes woodOre[] = {Res::ERes::WOOD, Res::ERes::ORE};
static const Res::ERes preciousResources[] = {Res::ERes::GEMS, Res::ERes::CRYSTAL, Res::ERes::MERCURY, Res::ERes::SULFUR};

std::array<TObjectTypeHandler, 7> factory =
std::array<TObjectTypeHandler, 7> factoryMine =
{
VLC->objtypeh->getHandlerFor(Obj::MINE, 0),
VLC->objtypeh->getHandlerFor(Obj::MINE, 1),
Expand All @@ -1307,17 +1314,29 @@ bool CRmgTemplateZone::placeMines ()
VLC->objtypeh->getHandlerFor(Obj::MINE, 5),
VLC->objtypeh->getHandlerFor(Obj::MINE, 6)
};
std::array<TObjectTypeHandler, 7> factoryRes =
{
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 0),
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 1),
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 2),
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 3),
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 4),
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 5),
VLC->objtypeh->getHandlerFor(Obj::RESOURCE, 6)
};
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved
std::vector<CGMine*> tempmines;

for (const auto & res : woodOre)
{
for (int i = 0; i < mines[res]; i++)
{
auto mine = (CGMine *) factory.at(static_cast<si32>(res))->create(ObjectTemplate());
auto mine = (CGMine *) factoryMine.at(static_cast<si32>(res))->create(ObjectTemplate());
tempmines.emplace_back(mine);
mine->producedResource = res;
mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction();
if (!i)
addCloseObject(mine, 1500); //only firts one is close
addCloseObject(mine, 1500); //only first is close
else
addRequiredObject(mine, 1500);
}
Expand All @@ -1326,7 +1345,8 @@ bool CRmgTemplateZone::placeMines ()
{
for (int i = 0; i < mines[res]; i++)
{
auto mine = (CGMine *) factory.at(static_cast<si32>(res))->create(ObjectTemplate());
auto mine = (CGMine *) factoryMine.at(static_cast<si32>(res))->create(ObjectTemplate());
tempmines.emplace_back(mine);
mine->producedResource = res;
mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction();
Expand All @@ -1335,12 +1355,24 @@ bool CRmgTemplateZone::placeMines ()
}
for (int i = 0; i < mines[Res::GOLD]; i++)
{
auto mine = (CGMine *) factory.at(Res::GOLD)->create(ObjectTemplate());
auto mine = (CGMine *) factoryMine.at(Res::GOLD)->create(ObjectTemplate());
tempmines.emplace_back(mine);
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved
mine->producedResource = Res::GOLD;
mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction();
addRequiredObject(mine, 7000);
}

//create extra resources
for(auto* mine : tempmines)
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved
{
for(int rc = gen->rand.nextInt(1,3); rc>0; --rc)
{
auto resourse = (CGResource*) factoryRes.at(mine->producedResource)->create(ObjectTemplate());
resourse->amount = 0;
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved
addNearbyObject(resourse, mine);
}
}

return true;
}
Expand Down Expand Up @@ -1463,6 +1495,37 @@ bool CRmgTemplateZone::createRequiredObjects()
}
}

//create nearby objects (e.g. extra resources close to mines)
for(const auto &object : nearbyObjects)
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved
{
auto obj = object.first;
std::set<int3> possiblePositions;
for (auto blockedTile : object.second->getBlockedPos())
{
gen->foreachDirectNeighbour(blockedTile, [this, &possiblePositions](int3 pos)
{
if (!gen->isBlocked(pos))
{
//some resources still could be unaccessible, at least one free cell shall be
gen->foreach_neighbour(pos, [this, &possiblePositions, &pos](int3 p)
{
if(gen->isFree(p))
possiblePositions.insert(pos);
});
}
});
}

if(possiblePositions.empty())
{
delete obj; //is it correct way to prevent leak?
continue;
}
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved

auto pos = *RandomGeneratorUtil::nextItem(possiblePositions, gen->rand);
placeObject(obj, pos);
}

return true;
}

Expand Down
2 changes: 2 additions & 0 deletions lib/rmg/CRmgTemplateZone.h
Expand Up @@ -111,6 +111,7 @@ class DLL_LINKAGE CRmgTemplateZone : public rmg::ZoneOptions

void addRequiredObject(CGObjectInstance * obj, si32 guardStrength=0);
void addCloseObject(CGObjectInstance * obj, si32 guardStrength = 0);
void addNearbyObject(CGObjectInstance * obj, CGObjectInstance * nearbyTarget);
void addToConnectLater(const int3& src);
bool addMonster(int3 &pos, si32 strength, bool clearSurroundingTiles = true, bool zoneGuard = false);
bool createTreasurePile(int3 &pos, float minDistance, const CTreasureInfo& treasureInfo);
Expand Down Expand Up @@ -173,6 +174,7 @@ class DLL_LINKAGE CRmgTemplateZone : public rmg::ZoneOptions
//content info
std::vector<std::pair<CGObjectInstance*, ui32>> requiredObjects;
std::vector<std::pair<CGObjectInstance*, ui32>> closeObjects;
std::vector<std::pair<CGObjectInstance*, CGObjectInstance*>> nearbyObjects;
std::vector<CGObjectInstance*> objects;

//placement info
Expand Down