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 all 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
4 changes: 2 additions & 2 deletions lib/mapObjects/MiscObjects.cpp
Expand Up @@ -838,14 +838,14 @@ std::string CGResource::getHoverText(PlayerColor player) const

CGResource::CGResource()
{
amount = 0;
amount = CGResource::RANDOM_AMOUNT;
}

void CGResource::initObj(CRandomGenerator & rand)
{
blockVisit = true;

if(!amount)
if(amount == CGResource::RANDOM_AMOUNT)
{
switch(subID)
{
Expand Down
2 changes: 2 additions & 0 deletions lib/mapObjects/MiscObjects.h
Expand Up @@ -215,7 +215,9 @@ class DLL_LINKAGE CGArtifact : public CArmedInstance
class DLL_LINKAGE CGResource : public CArmedInstance
{
public:
static const ui32 RANDOM_AMOUNT = 0;
ui32 amount; //0 if random

std::string message;

CGResource();
Expand Down
105 changes: 65 additions & 40 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 @@ -1294,53 +1301,39 @@ void CRmgTemplateZone::paintZoneTerrain (ETerrainType terrainType)

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 =
using namespace Res;
static const std::map<ERes, int> mineValue{{ERes::WOOD, 1500}, {ERes::ORE, 1500}, {ERes::GEMS, 3500}, {ERes::CRYSTAL, 3500}, {ERes::MERCURY, 3500}, {ERes::SULFUR, 3500}, {ERes::GOLD, 7000}};

std::vector<CGMine*> createdMines;

for(const auto & mineInfo : mines)
{
VLC->objtypeh->getHandlerFor(Obj::MINE, 0),
VLC->objtypeh->getHandlerFor(Obj::MINE, 1),
VLC->objtypeh->getHandlerFor(Obj::MINE, 2),
VLC->objtypeh->getHandlerFor(Obj::MINE, 3),
VLC->objtypeh->getHandlerFor(Obj::MINE, 4),
VLC->objtypeh->getHandlerFor(Obj::MINE, 5),
VLC->objtypeh->getHandlerFor(Obj::MINE, 6)
};

for (const auto & res : woodOre)
{
for (int i = 0; i < mines[res]; i++)
ERes res = (ERes)mineInfo.first;
for(int i = 0; i < mineInfo.second; ++i)
{
auto mine = (CGMine *) factory.at(static_cast<si32>(res))->create(ObjectTemplate());
auto mine = (CGMine*) VLC->objtypeh->getHandlerFor(Obj::MINE, res)->create(ObjectTemplate());
mine->producedResource = res;
mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction();
if (!i)
addCloseObject(mine, 1500); //only firts one is close
createdMines.push_back(mine);

if(!i && (res == ERes::WOOD || res == ERes::ORE))
addCloseObject(mine, mineValue.at(res)); //only first woor&ore mines are close
else
addRequiredObject(mine, 1500);
addRequiredObject(mine, mineValue.at(res));
}
}
for (const auto & res : preciousResources)

//create extra resources
for(auto * mine : createdMines)
{
for (int i = 0; i < mines[res]; i++)
for(int rc = gen->rand.nextInt(1, 3); rc > 0; --rc)
{
auto mine = (CGMine *) factory.at(static_cast<si32>(res))->create(ObjectTemplate());
mine->producedResource = res;
mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction();
addRequiredObject(mine, 3500);
auto resourse = (CGResource*) VLC->objtypeh->getHandlerFor(Obj::RESOURCE, mine->producedResource)->create(ObjectTemplate());
resourse->amount = CGResource::RANDOM_AMOUNT;
addNearbyObject(resourse, mine);
}
}
for (int i = 0; i < mines[Res::GOLD]; i++)
{
auto mine = (CGMine *) factory.at(Res::GOLD)->create(ObjectTemplate());
mine->producedResource = Res::GOLD;
mine->tempOwner = PlayerColor::NEUTRAL;
mine->producedQuantity = mine->defaultResProduction();
addRequiredObject(mine, 7000);
}

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

//create nearby objects (e.g. extra resources close to mines)
for(const auto & object : nearbyObjects)
{
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?
}
Nordsoft91 marked this conversation as resolved.
Show resolved Hide resolved
else
{
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