mirror of
https://github.com/vcmi/vcmi.git
synced 2025-03-25 21:38:59 +02:00
Select random object template instead of first
This commit is contained in:
parent
811680c4c5
commit
ce62ab3e66
@ -111,18 +111,18 @@ void Object::Instance::setPositionRaw(const int3 & position)
|
||||
dObject.pos = dPosition + dParent.getPosition();
|
||||
}
|
||||
|
||||
void Object::Instance::setAnyTemplate()
|
||||
void Object::Instance::setAnyTemplate(CRandomGenerator & rng)
|
||||
{
|
||||
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates();
|
||||
if(templates.empty())
|
||||
throw rmgException(boost::str(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
|
||||
|
||||
dObject.appearance = templates.front();
|
||||
dObject.appearance = *RandomGeneratorUtil::nextItem(templates, rng);
|
||||
dAccessibleAreaCache.clear();
|
||||
setPosition(getPosition(false));
|
||||
}
|
||||
|
||||
void Object::Instance::setTemplate(TerrainId terrain)
|
||||
void Object::Instance::setTemplate(TerrainId terrain, CRandomGenerator & rng)
|
||||
{
|
||||
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrain);
|
||||
if (templates.empty())
|
||||
@ -130,7 +130,8 @@ void Object::Instance::setTemplate(TerrainId terrain)
|
||||
auto terrainName = VLC->terrainTypeHandler->getById(terrain)->getNameTranslated();
|
||||
throw rmgException(boost::str(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.subID % terrainName));
|
||||
}
|
||||
dObject.appearance = templates.front();
|
||||
|
||||
dObject.appearance = *RandomGeneratorUtil::nextItem(templates, rng);
|
||||
dAccessibleAreaCache.clear();
|
||||
setPosition(getPosition(false));
|
||||
}
|
||||
@ -280,10 +281,10 @@ void Object::setPosition(const int3 & position)
|
||||
i.setPositionRaw(i.getPosition());
|
||||
}
|
||||
|
||||
void Object::setTemplate(const TerrainId & terrain)
|
||||
void Object::setTemplate(const TerrainId & terrain, CRandomGenerator & rng)
|
||||
{
|
||||
for(auto& i : dInstances)
|
||||
i.setTemplate(terrain);
|
||||
i.setTemplate(terrain, rng);
|
||||
}
|
||||
|
||||
const Area & Object::getArea() const
|
||||
@ -325,7 +326,7 @@ void rmg::Object::setGuardedIfMonster(const Instance& object)
|
||||
}
|
||||
}
|
||||
|
||||
void Object::Instance::finalize(RmgMap & map)
|
||||
void Object::Instance::finalize(RmgMap & map, CRandomGenerator & rng)
|
||||
{
|
||||
if(!map.isOnMap(getPosition(true)))
|
||||
throw rmgException(boost::str(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString()));
|
||||
@ -341,7 +342,7 @@ void Object::Instance::finalize(RmgMap & map)
|
||||
}
|
||||
else
|
||||
{
|
||||
setTemplate(terrainType->getId());
|
||||
setTemplate(terrainType->getId(), rng);
|
||||
}
|
||||
}
|
||||
|
||||
@ -362,14 +363,14 @@ void Object::Instance::finalize(RmgMap & map)
|
||||
map.getMapProxy()->insertObject(&dObject);
|
||||
}
|
||||
|
||||
void Object::finalize(RmgMap & map)
|
||||
void Object::finalize(RmgMap & map, CRandomGenerator & rng)
|
||||
{
|
||||
if(dInstances.empty())
|
||||
throw rmgException("Cannot finalize object without instances");
|
||||
|
||||
for(auto & dInstance : dInstances)
|
||||
{
|
||||
dInstance.finalize(map);
|
||||
dInstance.finalize(map, rng);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
|
||||
class CGObjectInstance;
|
||||
class CRandomGenerator;
|
||||
class RmgMap;
|
||||
|
||||
namespace rmg {
|
||||
@ -35,8 +36,8 @@ public:
|
||||
int3 getVisitablePosition() const;
|
||||
bool isVisitableFrom(const int3 & tile) const;
|
||||
const Area & getAccessibleArea() const;
|
||||
void setTemplate(TerrainId terrain); //cache invalidation
|
||||
void setAnyTemplate(); //cache invalidation
|
||||
void setTemplate(TerrainId terrain, CRandomGenerator &); //cache invalidation
|
||||
void setAnyTemplate(CRandomGenerator &); //cache invalidation
|
||||
|
||||
int3 getTopTile() const;
|
||||
int3 getPosition(bool isAbsolute = false) const;
|
||||
@ -45,7 +46,7 @@ public:
|
||||
const CGObjectInstance & object() const;
|
||||
CGObjectInstance & object();
|
||||
|
||||
void finalize(RmgMap & map); //cache invalidation
|
||||
void finalize(RmgMap & map, CRandomGenerator &); //cache invalidation
|
||||
void clear();
|
||||
|
||||
private:
|
||||
@ -73,7 +74,7 @@ public:
|
||||
|
||||
const int3 & getPosition() const;
|
||||
void setPosition(const int3 & position);
|
||||
void setTemplate(const TerrainId & terrain);
|
||||
void setTemplate(const TerrainId & terrain, CRandomGenerator &);
|
||||
|
||||
const Area & getArea() const; //lazy cache invalidation
|
||||
const int3 getVisibleTop() const;
|
||||
@ -81,7 +82,7 @@ public:
|
||||
bool isGuarded() const;
|
||||
void setGuardedIfMonster(const Instance & object);
|
||||
|
||||
void finalize(RmgMap & map);
|
||||
void finalize(RmgMap & map, CRandomGenerator &);
|
||||
void clear();
|
||||
|
||||
private:
|
||||
|
@ -316,8 +316,8 @@ void ConnectionsPlacer::selfSideIndirectConnection(const rmg::ZoneConnection & c
|
||||
auto * gate2 = factory->create();
|
||||
rmg::Object rmgGate1(*gate1);
|
||||
rmg::Object rmgGate2(*gate2);
|
||||
rmgGate1.setTemplate(zone.getTerrainType());
|
||||
rmgGate2.setTemplate(otherZone->getTerrainType());
|
||||
rmgGate1.setTemplate(zone.getTerrainType(), zone.getRand());
|
||||
rmgGate2.setTemplate(otherZone->getTerrainType(), zone.getRand());
|
||||
bool guarded1 = manager.addGuard(rmgGate1, connection.getGuardStrength(), true);
|
||||
bool guarded2 = managerOther.addGuard(rmgGate2, connection.getGuardStrength(), true);
|
||||
int minDist = 3;
|
||||
|
@ -354,7 +354,7 @@ bool ObjectManager::createRequiredObjects()
|
||||
for(const auto & objInfo : requiredObjects)
|
||||
{
|
||||
rmg::Object rmgObject(*objInfo.obj);
|
||||
rmgObject.setTemplate(zone.getTerrainType());
|
||||
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
|
||||
bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
|
||||
|
||||
Zone::Lock lock(zone.areaMutex);
|
||||
@ -394,7 +394,7 @@ bool ObjectManager::createRequiredObjects()
|
||||
auto possibleArea = zone.areaPossible();
|
||||
|
||||
rmg::Object rmgObject(*objInfo.obj);
|
||||
rmgObject.setTemplate(zone.getTerrainType());
|
||||
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
|
||||
bool guarded = addGuard(rmgObject, objInfo.guardStrength, (objInfo.obj->ID == Obj::MONOLITH_TWO_WAY));
|
||||
auto path = placeAndConnectObject(zone.areaPossible(), rmgObject,
|
||||
[this, &rmgObject](const int3 & tile)
|
||||
@ -480,7 +480,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
|
||||
if (!monster->object().appearance)
|
||||
{
|
||||
//Needed to determine visitable offset
|
||||
monster->setAnyTemplate();
|
||||
monster->setAnyTemplate(zone.getRand());
|
||||
}
|
||||
object.getPosition();
|
||||
auto visitableOffset = monster->object().getVisitableOffset();
|
||||
@ -492,7 +492,7 @@ void ObjectManager::placeObject(rmg::Object & object, bool guarded, bool updateD
|
||||
int3 parentOffset = monster->getPosition(true) - monster->getPosition(false);
|
||||
monster->setPosition(fixedPos - parentOffset);
|
||||
}
|
||||
object.finalize(map);
|
||||
object.finalize(map, zone.getRand());
|
||||
|
||||
Zone::Lock lock(zone.areaMutex);
|
||||
zone.areaPossible().subtract(object.getArea());
|
||||
@ -689,7 +689,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
|
||||
});
|
||||
|
||||
auto & instance = object.addInstance(*guard);
|
||||
instance.setAnyTemplate(); //terrain is irrelevant for monsters, but monsters need some template now
|
||||
instance.setAnyTemplate(zone.getRand()); //terrain is irrelevant for monsters, but monsters need some template now
|
||||
|
||||
//Fix HoTA monsters with offset template
|
||||
auto visitableOffset = instance.object().getVisitableOffset();
|
||||
|
@ -397,7 +397,7 @@ void RiverPlacer::connectRiver(const int3 & tile)
|
||||
{
|
||||
auto * obj = handler->create(templ);
|
||||
rmg::Object deltaObj(*obj, deltaPositions[pos]);
|
||||
deltaObj.finalize(map);
|
||||
deltaObj.finalize(map, zone.getRand());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -140,7 +140,7 @@ int3 TownPlacer::placeMainTown(ObjectManager & manager, CGTownInstance & town)
|
||||
{
|
||||
//towns are big objects and should be centered around visitable position
|
||||
rmg::Object rmgObject(town);
|
||||
rmgObject.setTemplate(zone.getTerrainType());
|
||||
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
|
||||
|
||||
int3 position(-1, -1, -1);
|
||||
{
|
||||
|
@ -254,7 +254,7 @@ bool WaterProxy::placeBoat(Zone & land, const Lake & lake, bool createRoad, Rout
|
||||
auto * boat = dynamic_cast<CGBoat *>(VLC->objtypeh->getHandlerFor(Obj::BOAT, *RandomGeneratorUtil::nextItem(sailingBoatTypes, zone.getRand()))->create());
|
||||
|
||||
rmg::Object rmgObject(*boat);
|
||||
rmgObject.setTemplate(zone.getTerrainType());
|
||||
rmgObject.setTemplate(zone.getTerrainType(), zone.getRand());
|
||||
|
||||
auto waterAvailable = zone.areaPossible() + zone.freePaths();
|
||||
rmg::Area coast = lake.neighbourZones.at(land.getId()); //having land tiles
|
||||
@ -319,7 +319,7 @@ bool WaterProxy::placeShipyard(Zone & land, const Lake & lake, si32 guard, bool
|
||||
shipyard->tempOwner = PlayerColor::NEUTRAL;
|
||||
|
||||
rmg::Object rmgObject(*shipyard);
|
||||
rmgObject.setTemplate(land.getTerrainType());
|
||||
rmgObject.setTemplate(land.getTerrainType(), zone.getRand());
|
||||
bool guarded = manager->addGuard(rmgObject, guard);
|
||||
|
||||
auto waterAvailable = zone.areaPossible() + zone.freePaths();
|
||||
|
Loading…
x
Reference in New Issue
Block a user