1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-02-15 13:33:36 +02:00

Merge branch 'develop' into FFMpeg

This commit is contained in:
AlexVinS 2014-07-31 19:26:32 +04:00
commit ca05087c3b
15 changed files with 101 additions and 64 deletions

View File

@ -58,6 +58,7 @@
"object" : {
"index" : 0,
"rmg" : {
"zoneLimit" : 1,
"value" : 100,
"rarity" : 100
}
@ -106,11 +107,16 @@
},
"redwoodObservatory" : {
"index" :58,
"index" :58,
"handler" : "observatory",
"types" : {
"object" : {
"index" : 0,
"templates" :
{
"base" : { "animation" : "avxredw.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["grass", "swamp", "dirt", "sand", "lava", "rough"] },
"snow" : { "animation" : "avxreds0.def", "visitableFrom" : [ "---", "+++", "+++" ], "mask" : [ "VV", "VV", "VA"], "allowedTerrains":["snow"] }
},
"rmg" : {
"zoneLimit" : 1,
"value" : 750,
@ -629,6 +635,7 @@
"object" : {
"index" : 0,
"rmg" : {
"zoneLimit" : 1,
"value" : 100,
"rarity" : 20
}

View File

@ -408,12 +408,12 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow
return t->hasBuilt(id);
};
if(t->builded >= VLC->modh->settings.MAX_BUILDING_PER_TURN)
return EBuildingState::CANT_BUILD_TODAY; //building limit
if (!building->requirements.test(buildTest))
return EBuildingState::PREREQUIRES;
if(t->builded >= VLC->modh->settings.MAX_BUILDING_PER_TURN)
return EBuildingState::CANT_BUILD_TODAY; //building limit
if (building->upgrade != BuildingID::NONE && !t->hasBuilt(building->upgrade))
return EBuildingState::MISSING_BASE;

View File

@ -815,8 +815,8 @@ void CGameState::initNewGame()
CStopWatch sw;
// Gen map
CMapGenerator mapGenerator(scenarioOps->mapGenOptions, scenarioOps->seedToBeUsed);
map = mapGenerator.generate().release();
CMapGenerator mapGenerator;
map = mapGenerator.generate(scenarioOps->mapGenOptions.get(), scenarioOps->seedToBeUsed).release();
// Update starting options
for(int i = 0; i < map->players.size(); ++i)
@ -1849,7 +1849,10 @@ void CGameState::initMapObjects()
for(CGObjectInstance *obj : map->objects)
{
if(obj)
{
logGlobal->traceStream() << boost::format ("Calling Init for object %d, %d") % obj->ID % obj->subID;
obj->initObj();
}
}
for(CGObjectInstance *obj : map->objects)
{
@ -3518,5 +3521,6 @@ CPathfinder::CPathfinder(CPathsInfo &_out, CGameState *_gs, const CGHeroInstance
CRandomGenerator & CGameState::getRandomGenerator()
{
logGlobal->traceStream() << "Fetching CGameState::rand with seed " << rand.nextInt();
return rand;
}

View File

@ -853,14 +853,14 @@ void CBonusSystemNode::newChildAttached(CBonusSystemNode *child)
{
assert(!vstd::contains(children, child));
children.push_back(child);
BONUS_LOG_LINE(child->nodeName() << " #attached to# " << nodeName());
//BONUS_LOG_LINE(child->nodeName() << " #attached to# " << nodeName());
}
void CBonusSystemNode::childDetached(CBonusSystemNode *child)
{
assert(vstd::contains(children, child));
children -= child;
BONUS_LOG_LINE(child->nodeName() << " #detached from# " << nodeName());
//BONUS_LOG_LINE(child->nodeName() << " #detached from# " << nodeName());
}
void CBonusSystemNode::detachFromAll()

View File

@ -222,7 +222,7 @@ public:
h & exp & level & name & biography & portrait & mana & secSkills & movement
& sex & inTownGarrison & spells & patrol & moveDir & skillsInfo;
h & visitedTown & boat;
h & type & specialty & commander;
h & type & specialty & commander & visitedObjects;
BONUS_TREE_DESERIALIZATION_FIX
//visitied town pointer will be restored by map serialization method
}

View File

@ -271,6 +271,8 @@ BankConfig CBankInstanceConstructor::generateConfig(const JsonNode & level, CRan
void CBankInstanceConstructor::configureObject(CGObjectInstance * object, CRandomGenerator & rng) const
{
//logGlobal->debugStream() << "Seed used to configure bank is " << rng.nextInt();
auto bank = dynamic_cast<CBank*>(object);
bank->resetDuration = bankResetDuration;
@ -282,6 +284,7 @@ void CBankInstanceConstructor::configureObject(CGObjectInstance * object, CRando
assert(totalChance != 0);
si32 selectedChance = rng.nextInt(totalChance - 1);
//logGlobal->debugStream() << "Selected chance for bank config is " << selectedChance;
for (auto & node : levels)
{

View File

@ -632,6 +632,11 @@ std::string CGResource::getHoverText(PlayerColor player) const
return VLC->generaltexth->restypes[subID];
}
CGResource::CGResource()
{
amount = 0;
}
void CGResource::initObj()
{
blockVisit = true;

View File

@ -182,6 +182,7 @@ public:
ui32 amount; //0 if random
std::string message;
CGResource();
void onHeroVisit(const CGHeroInstance * h) const override;
void initObj() override;
void battleFinished(const CGHeroInstance *hero, const BattleResult &result) const override;

View File

@ -65,7 +65,7 @@ si8 CMapGenOptions::getPlayerCount() const
void CMapGenOptions::setPlayerCount(si8 value)
{
assert((value >= 2 && value <= PlayerColor::PLAYER_LIMIT_I) || value == RANDOM_SIZE);
assert((value >= 1 && value <= PlayerColor::PLAYER_LIMIT_I) || value == RANDOM_SIZE);
playerCount = value;
resetPlayersMap();
}

View File

@ -24,10 +24,9 @@ void CMapGenerator::foreach_neighbour(const int3 &pos, std::function<void(int3&
}
CMapGenerator::CMapGenerator(shared_ptr<CMapGenOptions> mapGenOptions, int RandomSeed /*= std::time(nullptr)*/) :
mapGenOptions(mapGenOptions), randomSeed(RandomSeed), monolithIndex(0), zonesTotal(0)
CMapGenerator::CMapGenerator() :
monolithIndex(0), zonesTotal(0)
{
rand.setSeed(randomSeed);
}
void CMapGenerator::initTiles()
@ -78,8 +77,11 @@ void CMapGenerator::initPrisonsRemaining()
prisonsRemaining = std::max<int> (0, prisonsRemaining - 16 * map->players.size()); //so at least 16 heroes will be available for every player
}
std::unique_ptr<CMap> CMapGenerator::generate()
std::unique_ptr<CMap> CMapGenerator::generate(CMapGenOptions * mapGenOptions, int randomSeed /*= std::time(nullptr)*/)
{
this->mapGenOptions = mapGenOptions;
this->randomSeed = randomSeed;
rand.setSeed(this->randomSeed);
mapGenOptions->finalize(rand);
map = make_unique<CMap>();
@ -95,7 +97,7 @@ std::unique_ptr<CMap> CMapGenerator::generate()
genZones();
map->calculateGuardingGreaturePositions(); //clear map so that all tiles are unguarded
fillZones();
//updated fuarded tiles will be calculated in CGameState::initMapObjects()
//updated guarded tiles will be calculated in CGameState::initMapObjects()
}
catch (rmgException &e)
{

View File

@ -51,12 +51,12 @@ public:
class DLL_LINKAGE CMapGenerator
{
public:
explicit CMapGenerator(shared_ptr<CMapGenOptions> mapGenOptions, int RandomSeed = std::time(nullptr));
explicit CMapGenerator();
~CMapGenerator(); // required due to unique_ptr
std::unique_ptr<CMap> generate();
std::unique_ptr<CMap> generate(CMapGenOptions * mapGenOptions, int RandomSeed = std::time(nullptr));
shared_ptr<CMapGenOptions> mapGenOptions;
CMapGenOptions * mapGenOptions;
std::unique_ptr<CMap> map;
CRandomGenerator rand;
int randomSeed;

View File

@ -620,6 +620,7 @@ bool CRmgTemplateZone::addMonster(CMapGenerator* gen, int3 &pos, si32 strength,
auto guard = new CGCreature();
guard->ID = Obj::MONSTER;
guard->subID = creId;
guard->character = 1; //MUST be initialized or switch will diverge
auto hlp = new CStackInstance(creId, amount);
//will be set during initialization
guard->putStack(SlotID(0), hlp);
@ -670,10 +671,11 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
}
}
}
ui32 desiredValue = gen->rand.nextInt(minValue, maxValue);
int currentValue = 0;
CGObjectInstance * object = nullptr;
while (currentValue < minValue)
while (currentValue < desiredValue)
{
treasures[info.nextTreasurePos] = nullptr;
@ -697,21 +699,22 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
break;
}
int remaining = maxValue - currentValue;
ObjectInfo oi = getRandomObject(gen, info, remaining);
object = oi.generateObject();
if (!object)
ObjectInfo oi = getRandomObject(gen, info, desiredValue - currentValue);
if (!oi.value) //0 value indicates no object
{
vstd::erase_if_present(treasures, info.nextTreasurePos);
break;
}
else
{
object = oi.generateObject();
//remove from possible objects
auto oiptr = std::find(possibleObjects.begin(), possibleObjects.end(), oi);
assert (oiptr != possibleObjects.end());
oiptr->maxPerZone--;
if (!oiptr->maxPerZone)
possibleObjects.erase(oiptr);
//TODO
//update treasure pile area
@ -730,34 +733,38 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
info.blockedPositions.insert(blockPos);
}
info.occupiedPositions.insert(visitablePos);
}
currentValue += oi.value;
currentValue += oi.value;
treasures[info.nextTreasurePos] = object;
treasures[info.nextTreasurePos] = object;
//now find place for next object
int3 placeFound(-1,-1,-1);
//now find place for next object
int3 placeFound(-1,-1,-1);
for (auto tile : boundary)
{
if (gen->isPossible(tile)) //we can place new treasure only on possible tile
//randomize next position from among possible ones
std::vector<int3> boundaryCopy (boundary.begin(), boundary.end());
RandomGeneratorUtil::randomShuffle(boundaryCopy, gen->rand);
for (auto tile : boundaryCopy)
{
bool here = true;
gen->foreach_neighbour (tile, [gen, &here](int3 pos)
if (gen->isPossible(tile)) //we can place new treasure only on possible tile
{
if (!(gen->isBlocked(pos) || gen->isPossible(pos)))
here = false;
});
if (here)
{
placeFound = tile;
break;
bool here = true;
gen->foreach_neighbour (tile, [gen, &here](int3 pos)
{
if (!(gen->isBlocked(pos) || gen->isPossible(pos)))
here = false;
});
if (here)
{
placeFound = tile;
break;
}
}
}
}
if (placeFound.valid())
info.nextTreasurePos = placeFound;
if (placeFound.valid())
info.nextTreasurePos = placeFound;
}
}
if (treasures.size())
@ -865,6 +872,8 @@ bool CRmgTemplateZone::createTreasurePile (CMapGenerator* gen, int3 &pos)
{
if (gen->isPossible(treasure.first))
gen->setOccupied (treasure.first, ETileType::BLOCKED);
delete treasure.second;
}
}
@ -1077,7 +1086,8 @@ bool CRmgTemplateZone::createRequiredObjects(CMapGenerator* gen)
void CRmgTemplateZone::createTreasures(CMapGenerator* gen)
{
const double minDistance = std::max<float>(15.0f / sqrt(totalDensity), 2);
//this is squared distance for optimization purposes
const double minDistance = std::max<float>(200.f / totalDensity, 4);
//distance lower than 2 causes objects to overlap and crash
do {
@ -1230,7 +1240,7 @@ bool CRmgTemplateZone::findPlaceForTreasurePile(CMapGenerator* gen, float min_di
bool allTilesAvailable = true;
gen->foreach_neighbour (tile, [&gen, &allTilesAvailable](int3 neighbour)
{
if (!(gen->isPossible(neighbour) || gen->isBlocked(neighbour)))
if (!(gen->isPossible(neighbour) || gen->shouldBeBlocked(neighbour)))
{
allTilesAvailable = false; //all present tiles must be already blocked or ready for new objects
}
@ -1488,19 +1498,20 @@ bool CRmgTemplateZone::guardObject(CMapGenerator* gen, CGObjectInstance* object,
return true;
}
ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 value)
ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 remaining)
{
//int objectsVisitableFromBottom = 0; //for debug
std::vector<std::pair<ui32, ObjectInfo>> tresholds;
ui32 total = 0;
ui32 minValue = 0.25f * value;
//calculate actual treasure value range based on remaining value
ui32 minValue = 0.25f * remaining;
//roulette wheel
for (ObjectInfo &oi : possibleObjects) //copy constructor turned out to be costly
{
if (oi.value >= minValue && oi.value <= value && oi.maxPerZone > 0)
if (oi.value >= minValue && oi.value <= remaining && oi.maxPerZone > 0)
{
int3 newVisitableOffset = oi.templ.getVisitableOffset(); //visitablePos assumes object will be shifter by visitableOffset
int3 newVisitablePos = info.nextTreasurePos;
@ -1590,16 +1601,17 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
continue;
total += oi.probability;
//assert (oi.value > 0);
tresholds.push_back (std::make_pair (total, oi));
}
}
//logGlobal->infoStream() << boost::format ("Number of objects visitable from bottom: %d") % objectsVisitableFromBottom;
//Generate pandora Box with gold if the value is extremely high
ObjectInfo oi;
if (tresholds.empty())
{
ObjectInfo oi;
//Generate pandora Box with gold if the value is extremely high
if (minValue > 20000) //we don't have object valuable enough
{
oi.generateObject = [minValue]() -> CGObjectInstance *
@ -1614,25 +1626,28 @@ ObjectInfo CRmgTemplateZone::getRandomObject (CMapGenerator* gen, CTreasurePileI
oi.value = minValue;
oi.probability = 0;
}
else
else //generate empty object with 0 value if the value if we can't spawn anything
{
oi.generateObject = [gen]() -> CGObjectInstance *
{
return nullptr;
};
oi.setTemplate(Obj::PANDORAS_BOX, 0, terrainType); //TODO: null template or something? should be never used, but hell knows
oi.value = 0;
oi.value = 0; // this field is checked to determine no object
oi.probability = 0;
}
return oi;
}
int r = gen->rand.nextInt (1, total);
for (auto t : tresholds)
else
{
if (r <= t.first)
return t.second;
int r = gen->rand.nextInt (1, total);
for (auto t : tresholds)
{
if (r <= t.first)
return t.second;
}
assert (0); //we should never be here
}
//FIXME: control reaches end of non-void function. Missing return?
}

View File

@ -173,7 +173,7 @@ public:
std::vector<CTreasureInfo> getTreasureInfo();
std::set<int3>* getFreePaths();
ObjectInfo getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 value);
ObjectInfo getRandomObject (CMapGenerator* gen, CTreasurePileInfo &info, ui32 remaining);
void placeAndGuardObject(CMapGenerator* gen, CGObjectInstance* object, const int3 &pos, si32 str, bool zoneGuard = false);

View File

@ -38,7 +38,7 @@ int3 CZonePlacer::cords (const float3 f) const
return int3(std::max(0.f, (f.x * gen->map->width)-1), std::max(0.f, (f.y * gen->map->height-1)), f.z);
}
void CZonePlacer::placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGenerator * rand)
void CZonePlacer::placeZones(const CMapGenOptions * mapGenOptions, CRandomGenerator * rand)
{
//gravity-based algorithm
@ -207,7 +207,7 @@ d = 0.01 * dx^3 - 0.1618 * dx^2 + 1 * dx + ...
return dx * (1 + dx * (0.1 + dx * 0.01)) + dy * (1.618 + dy * (-0.1618 + dy * 0.01618));
}
void CZonePlacer::assignZones(shared_ptr<CMapGenOptions> mapGenOptions)
void CZonePlacer::assignZones(const CMapGenOptions * mapGenOptions)
{
logGlobal->infoStream() << "Starting zone colouring";

View File

@ -43,8 +43,8 @@ public:
float metric (const int3 &a, const int3 &b) const;
~CZonePlacer();
void placeZones(shared_ptr<CMapGenOptions> mapGenOptions, CRandomGenerator * rand);
void assignZones(shared_ptr<CMapGenOptions> mapGenOptions);
void placeZones(const CMapGenOptions * mapGenOptions, CRandomGenerator * rand);
void assignZones(const CMapGenOptions * mapGenOptions);
private:
//metric coefiicients