mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-20 20:23:03 +02:00
[0002285] Implement feature with extra resources near mines (#742)
* RMG: clear start position * [0002285] some heaps of resources are placed nearby mines * Fix leak in case of inability to place resource * Fix indentation according to vcmi style * Add constant for random amount of resources * Code review fixes
This commit is contained in:
parent
c293b655f5
commit
a8265c7052
@ -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)
|
||||
{
|
||||
|
@ -215,7 +215,9 @@ protected:
|
||||
class DLL_LINKAGE CGResource : public CArmedInstance
|
||||
{
|
||||
public:
|
||||
static const ui32 RANDOM_AMOUNT = 0;
|
||||
ui32 amount; //0 if random
|
||||
|
||||
std::string message;
|
||||
|
||||
CGResource();
|
||||
|
@ -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)
|
||||
{
|
||||
@ -1106,14 +1110,17 @@ void CRmgTemplateZone::initTownType ()
|
||||
//cut a ring around town to ensure crunchPath always hits it.
|
||||
auto cutPathAroundTown = [this](const CGTownInstance * town)
|
||||
{
|
||||
for (auto blockedTile : town->getBlockedPos())
|
||||
{
|
||||
gen->foreach_neighbour(blockedTile, [this](const int3 & pos)
|
||||
auto clearPos = [this](const int3 & pos)
|
||||
{
|
||||
if (gen->isPossible(pos))
|
||||
gen->setOccupied(pos, ETileType::FREE);
|
||||
});
|
||||
};
|
||||
for (auto blockedTile : town->getBlockedPos())
|
||||
{
|
||||
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)
|
||||
@ -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};
|
||||
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::array<TObjectTypeHandler, 7> factory =
|
||||
{
|
||||
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)
|
||||
};
|
||||
std::vector<CGMine*> createdMines;
|
||||
|
||||
for (const auto & res : woodOre)
|
||||
for(const auto & mineInfo : mines)
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -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?
|
||||
}
|
||||
else
|
||||
{
|
||||
auto pos = *RandomGeneratorUtil::nextItem(possiblePositions, gen->rand);
|
||||
placeObject(obj, pos);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -111,6 +111,7 @@ public:
|
||||
|
||||
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);
|
||||
@ -173,6 +174,7 @@ private:
|
||||
//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
|
||||
|
Loading…
Reference in New Issue
Block a user