mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-06 09:09:40 +02:00
Working fir for Corpse issue:
- Do not place guard next to blockVis object, if possible - Do not place two blockVis objects next to each other
This commit is contained in:
@@ -10,7 +10,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"types" : {
|
"types" : {
|
||||||
"prison" : { "index" : 0, "aiValue" : 5000 }
|
"prison" : {
|
||||||
|
"index" : 0,
|
||||||
|
"aiValue" : 5000,
|
||||||
|
"removable": true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -136,6 +140,7 @@
|
|||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"aiValue" : 10000,
|
"aiValue" : 10000,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "ava0128.def", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "ava0128.def", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
},
|
},
|
||||||
@@ -150,6 +155,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -313,6 +319,7 @@
|
|||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"aiValue" : 0,
|
"aiValue" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -444,6 +451,7 @@
|
|||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"aiValue" : 10000,
|
"aiValue" : 10000,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -495,6 +503,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
"value" : 2000,
|
"value" : 2000,
|
||||||
"rarity" : 150
|
"rarity" : 150
|
||||||
@@ -511,6 +520,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
"value" : 5000,
|
"value" : 5000,
|
||||||
"rarity" : 150
|
"rarity" : 150
|
||||||
@@ -527,6 +537,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
"value" : 10000,
|
"value" : 10000,
|
||||||
"rarity" : 150
|
"rarity" : 150
|
||||||
@@ -543,6 +554,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
"value" : 20000,
|
"value" : 20000,
|
||||||
"rarity" : 150
|
"rarity" : 150
|
||||||
@@ -572,6 +584,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "AVWmon1", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "AVWmon1", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
}
|
}
|
||||||
@@ -584,6 +597,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "AVWmon2", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "AVWmon2", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
}
|
}
|
||||||
@@ -596,6 +610,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "AVWmon3", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "AVWmon3", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
}
|
}
|
||||||
@@ -608,6 +623,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "AVWmon4", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "AVWmon4", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
}
|
}
|
||||||
@@ -632,6 +648,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "AVWmon6", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "AVWmon6", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
}
|
}
|
||||||
@@ -644,6 +661,7 @@
|
|||||||
"types" : {
|
"types" : {
|
||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
|
"removable": true,
|
||||||
"templates" : {
|
"templates" : {
|
||||||
"normal" : { "animation" : "AVWmon7", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
"normal" : { "animation" : "AVWmon7", "visitableFrom" : [ "+++", "+-+", "+++" ], "mask" : [ "VV", "VA"] }
|
||||||
}
|
}
|
||||||
@@ -687,6 +705,7 @@
|
|||||||
"object" : {
|
"object" : {
|
||||||
"index" : 0,
|
"index" : 0,
|
||||||
"aiValue" : 0,
|
"aiValue" : 0,
|
||||||
|
"removable": true,
|
||||||
"rmg" : {
|
"rmg" : {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -723,6 +742,7 @@
|
|||||||
"index" :95,
|
"index" :95,
|
||||||
"handler": "generic",
|
"handler": "generic",
|
||||||
"base" : {
|
"base" : {
|
||||||
|
"blockVisit": true,
|
||||||
"sounds" : {
|
"sounds" : {
|
||||||
"ambient" : ["LOOPTAV"],
|
"ambient" : ["LOOPTAV"],
|
||||||
"visit" : ["STORE"]
|
"visit" : ["STORE"]
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
"index" :5,
|
"index" :5,
|
||||||
"handler": "artifact",
|
"handler": "artifact",
|
||||||
"base" : {
|
"base" : {
|
||||||
|
"removable": true,
|
||||||
"base" : {
|
"base" : {
|
||||||
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
||||||
"mask" : [ "VV", "VA"]
|
"mask" : [ "VV", "VA"]
|
||||||
@@ -25,6 +26,7 @@
|
|||||||
"handler": "hero",
|
"handler": "hero",
|
||||||
"base" : {
|
"base" : {
|
||||||
"aiValue" : 7500,
|
"aiValue" : 7500,
|
||||||
|
"removable": true,
|
||||||
"base" : {
|
"base" : {
|
||||||
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
||||||
"mask" : [ "VVV", "VAV"]
|
"mask" : [ "VVV", "VAV"]
|
||||||
@@ -40,6 +42,7 @@
|
|||||||
"index" :54,
|
"index" :54,
|
||||||
"handler": "monster",
|
"handler": "monster",
|
||||||
"base" : {
|
"base" : {
|
||||||
|
"removable": true,
|
||||||
"base" : {
|
"base" : {
|
||||||
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
||||||
"mask" : [ "VV", "VA"]
|
"mask" : [ "VV", "VA"]
|
||||||
@@ -55,6 +58,7 @@
|
|||||||
"index" :76,
|
"index" :76,
|
||||||
"handler": "randomResource",
|
"handler": "randomResource",
|
||||||
"base" : {
|
"base" : {
|
||||||
|
"removable": true,
|
||||||
"base" : {
|
"base" : {
|
||||||
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
||||||
"mask" : [ "VA" ]
|
"mask" : [ "VA" ]
|
||||||
@@ -85,6 +89,7 @@
|
|||||||
"handler": "resource",
|
"handler": "resource",
|
||||||
"lastReservedIndex" : 6,
|
"lastReservedIndex" : 6,
|
||||||
"base" : {
|
"base" : {
|
||||||
|
"removable": true,
|
||||||
"base" : {
|
"base" : {
|
||||||
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
"visitableFrom" : [ "+++", "+-+", "+++" ],
|
||||||
"mask" : [ "VA" ]
|
"mask" : [ "VA" ]
|
||||||
@@ -138,6 +143,7 @@
|
|||||||
"lastReservedIndex" : 2,
|
"lastReservedIndex" : 2,
|
||||||
"base" : {
|
"base" : {
|
||||||
"aiValue" : 0,
|
"aiValue" : 0,
|
||||||
|
"removable": true,
|
||||||
"layer" : "sail",
|
"layer" : "sail",
|
||||||
"onboardAssaultAllowed" : true,
|
"onboardAssaultAllowed" : true,
|
||||||
"onboardVisitAllowed" : true,
|
"onboardVisitAllowed" : true,
|
||||||
@@ -175,6 +181,7 @@
|
|||||||
"lastReservedIndex" : 7,
|
"lastReservedIndex" : 7,
|
||||||
"base" : {
|
"base" : {
|
||||||
"aiValue" : 0,
|
"aiValue" : 0,
|
||||||
|
"removable": true,
|
||||||
"sounds" : {
|
"sounds" : {
|
||||||
"visit" : ["CAVEHEAD"],
|
"visit" : ["CAVEHEAD"],
|
||||||
"removal" : [ "PICKUP01", "PICKUP02", "PICKUP03", "PICKUP04", "PICKUP05", "PICKUP06", "PICKUP07" ]
|
"removal" : [ "PICKUP01", "PICKUP02", "PICKUP03", "PICKUP04", "PICKUP05", "PICKUP06", "PICKUP07" ]
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
"value" : 2000,
|
"value" : 2000,
|
||||||
"rarity" : 500
|
"rarity" : 500
|
||||||
},
|
},
|
||||||
|
"removable": true,
|
||||||
"compatibilityIdentifiers" : [ "object" ],
|
"compatibilityIdentifiers" : [ "object" ],
|
||||||
|
|
||||||
"blockedVisitable" : true,
|
"blockedVisitable" : true,
|
||||||
@@ -61,6 +62,7 @@
|
|||||||
"value" : 2000,
|
"value" : 2000,
|
||||||
"rarity" : 100
|
"rarity" : 100
|
||||||
},
|
},
|
||||||
|
"removable": true,
|
||||||
"compatibilityIdentifiers" : [ "object" ],
|
"compatibilityIdentifiers" : [ "object" ],
|
||||||
|
|
||||||
"blockedVisitable" : true,
|
"blockedVisitable" : true,
|
||||||
@@ -119,6 +121,7 @@
|
|||||||
"value" : 1500,
|
"value" : 1500,
|
||||||
"rarity" : 500
|
"rarity" : 500
|
||||||
},
|
},
|
||||||
|
"removable": true,
|
||||||
"compatibilityIdentifiers" : [ "object" ],
|
"compatibilityIdentifiers" : [ "object" ],
|
||||||
|
|
||||||
"blockedVisitable" : true,
|
"blockedVisitable" : true,
|
||||||
@@ -170,6 +173,7 @@
|
|||||||
"value" : 1500,
|
"value" : 1500,
|
||||||
"rarity" : 50
|
"rarity" : 50
|
||||||
},
|
},
|
||||||
|
"removable": true,
|
||||||
"compatibilityIdentifiers" : [ "object" ],
|
"compatibilityIdentifiers" : [ "object" ],
|
||||||
|
|
||||||
"blockedVisitable" : true,
|
"blockedVisitable" : true,
|
||||||
@@ -221,6 +225,7 @@
|
|||||||
"value" : 1500,
|
"value" : 1500,
|
||||||
"rarity" : 1000
|
"rarity" : 1000
|
||||||
},
|
},
|
||||||
|
"removable": true,
|
||||||
"compatibilityIdentifiers" : [ "object" ],
|
"compatibilityIdentifiers" : [ "object" ],
|
||||||
|
|
||||||
"blockedVisitable" : true,
|
"blockedVisitable" : true,
|
||||||
|
|||||||
@@ -96,6 +96,18 @@ void AObjectTypeHandler::init(const JsonNode & input)
|
|||||||
else
|
else
|
||||||
aiValue = static_cast<std::optional<si32>>(input["aiValue"].Integer());
|
aiValue = static_cast<std::optional<si32>>(input["aiValue"].Integer());
|
||||||
|
|
||||||
|
// TODO: Define properties, move them to actual object instance
|
||||||
|
if(input["blockVisit"].isNull())
|
||||||
|
blockVisit = false;
|
||||||
|
else
|
||||||
|
blockVisit = input["blockVisit"].Bool();
|
||||||
|
|
||||||
|
if(input["removable"].isNull())
|
||||||
|
removable = false;
|
||||||
|
else
|
||||||
|
removable = input["removable"].Bool();
|
||||||
|
|
||||||
|
|
||||||
battlefield = BattleField::NONE;
|
battlefield = BattleField::NONE;
|
||||||
|
|
||||||
if(!input["battleground"].isNull())
|
if(!input["battleground"].isNull())
|
||||||
@@ -120,6 +132,8 @@ void AObjectTypeHandler::preInitObject(CGObjectInstance * obj) const
|
|||||||
obj->subID = subtype;
|
obj->subID = subtype;
|
||||||
obj->typeName = typeName;
|
obj->typeName = typeName;
|
||||||
obj->subTypeName = subTypeName;
|
obj->subTypeName = subTypeName;
|
||||||
|
obj->blockVisit = blockVisit;
|
||||||
|
obj->removable = removable;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AObjectTypeHandler::initTypeData(const JsonNode & input)
|
void AObjectTypeHandler::initTypeData(const JsonNode & input)
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ class DLL_LINKAGE AObjectTypeHandler : public boost::noncopyable
|
|||||||
si32 type;
|
si32 type;
|
||||||
si32 subtype;
|
si32 subtype;
|
||||||
|
|
||||||
|
bool blockVisit;
|
||||||
|
bool removable;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void preInitObject(CGObjectInstance * obj) const;
|
void preInitObject(CGObjectInstance * obj) const;
|
||||||
virtual bool objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const;
|
virtual bool objectFilter(const CGObjectInstance * obj, std::shared_ptr<const ObjectTemplate> tmpl) const;
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ CGObjectInstance::CGObjectInstance():
|
|||||||
ID(Obj::NO_OBJ),
|
ID(Obj::NO_OBJ),
|
||||||
subID(-1),
|
subID(-1),
|
||||||
tempOwner(PlayerColor::UNFLAGGABLE),
|
tempOwner(PlayerColor::UNFLAGGABLE),
|
||||||
blockVisit(false)
|
blockVisit(false),
|
||||||
|
removable(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,12 +174,7 @@ void CGObjectInstance::pickRandomObject(CRandomGenerator & rand)
|
|||||||
|
|
||||||
void CGObjectInstance::initObj(CRandomGenerator & rand)
|
void CGObjectInstance::initObj(CRandomGenerator & rand)
|
||||||
{
|
{
|
||||||
switch(ID.toEnum())
|
// no-op
|
||||||
{
|
|
||||||
case Obj::TAVERN:
|
|
||||||
blockVisit = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGObjectInstance::setProperty( ObjProperty what, ObjPropertyID identifier )
|
void CGObjectInstance::setProperty( ObjProperty what, ObjPropertyID identifier )
|
||||||
@@ -191,6 +187,7 @@ void CGObjectInstance::setProperty( ObjProperty what, ObjPropertyID identifier )
|
|||||||
tempOwner = identifier.as<PlayerColor>();
|
tempOwner = identifier.as<PlayerColor>();
|
||||||
break;
|
break;
|
||||||
case ObjProperty::BLOCKVIS:
|
case ObjProperty::BLOCKVIS:
|
||||||
|
// Never actually used in code, but possible in ERM
|
||||||
blockVisit = identifier.getNum();
|
blockVisit = identifier.getNum();
|
||||||
break;
|
break;
|
||||||
case ObjProperty::ID:
|
case ObjProperty::ID:
|
||||||
@@ -327,9 +324,16 @@ bool CGObjectInstance::isVisitable() const
|
|||||||
|
|
||||||
bool CGObjectInstance::isBlockedVisitable() const
|
bool CGObjectInstance::isBlockedVisitable() const
|
||||||
{
|
{
|
||||||
|
// TODO: Read from json
|
||||||
return blockVisit;
|
return blockVisit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CGObjectInstance::isRemovable() const
|
||||||
|
{
|
||||||
|
// TODO: Read from json
|
||||||
|
return removable;
|
||||||
|
}
|
||||||
|
|
||||||
bool CGObjectInstance::isCoastVisitable() const
|
bool CGObjectInstance::isCoastVisitable() const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ public:
|
|||||||
int3 getSightCenter() const;
|
int3 getSightCenter() const;
|
||||||
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
||||||
bool blockVisit;
|
bool blockVisit;
|
||||||
|
bool removable;
|
||||||
|
|
||||||
PlayerColor getOwner() const override
|
PlayerColor getOwner() const override
|
||||||
{
|
{
|
||||||
@@ -85,6 +86,9 @@ public:
|
|||||||
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
/// If true hero can visit this object only from neighbouring tiles and can't stand on this object
|
||||||
virtual bool isBlockedVisitable() const;
|
virtual bool isBlockedVisitable() const;
|
||||||
|
|
||||||
|
// If true, can be possibly removed from the map
|
||||||
|
virtual bool isRemovable() const;
|
||||||
|
|
||||||
/// If true this object can be visited by hero standing on the coast
|
/// If true this object can be visited by hero standing on the coast
|
||||||
virtual bool isCoastVisitable() const;
|
virtual bool isCoastVisitable() const;
|
||||||
|
|
||||||
@@ -144,6 +148,7 @@ public:
|
|||||||
h & id;
|
h & id;
|
||||||
h & tempOwner;
|
h & tempOwner;
|
||||||
h & blockVisit;
|
h & blockVisit;
|
||||||
|
h & removable;
|
||||||
h & appearance;
|
h & appearance;
|
||||||
//definfo is handled by map serializer
|
//definfo is handled by map serializer
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -153,6 +153,11 @@ bool Object::Instance::isBlockedVisitable() const
|
|||||||
return dObject.isBlockedVisitable();
|
return dObject.isBlockedVisitable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Object::Instance::isRemovable() const
|
||||||
|
{
|
||||||
|
return dObject.isRemovable();
|
||||||
|
}
|
||||||
|
|
||||||
CGObjectInstance & Object::Instance::object()
|
CGObjectInstance & Object::Instance::object()
|
||||||
{
|
{
|
||||||
return dObject;
|
return dObject;
|
||||||
@@ -269,21 +274,52 @@ const rmg::Area & Object::getBlockVisitableArea() const
|
|||||||
{
|
{
|
||||||
if(dInstances.empty())
|
if(dInstances.empty())
|
||||||
return dBlockVisitableCache;
|
return dBlockVisitableCache;
|
||||||
for(auto i = dInstances.begin(); i != std::prev(dInstances.end()); ++i)
|
|
||||||
|
for(const auto i : dInstances)
|
||||||
{
|
{
|
||||||
// FIXME: Account for blockvis objects with multiple visitable tiles
|
// FIXME: Account for blockvis objects with multiple visitable tiles
|
||||||
if (i->isBlockedVisitable())
|
if (i.isBlockedVisitable())
|
||||||
dAccessibleAreaCache.add(i->getVisitablePosition());
|
dBlockVisitableCache.add(i.getVisitablePosition());
|
||||||
}
|
}
|
||||||
|
|
||||||
return dBlockVisitableCache;
|
return dBlockVisitableCache;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const rmg::Area & Object::getRemovableArea() const
|
||||||
|
{
|
||||||
|
if(dInstances.empty())
|
||||||
|
return dRemovableAreaCache;
|
||||||
|
|
||||||
|
for(const auto i : dInstances)
|
||||||
|
{
|
||||||
|
if (i.isRemovable())
|
||||||
|
dRemovableAreaCache.unite(i.getBlockedArea());
|
||||||
|
}
|
||||||
|
|
||||||
|
return dRemovableAreaCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
const rmg::Area Object::getEntrableArea() const
|
||||||
|
{
|
||||||
|
// Calculate Area that hero can freely pass
|
||||||
|
|
||||||
|
// Do not use blockVisitTiles, unless they belong to removable objects (resources etc.)
|
||||||
|
// area = accessibleArea - (blockVisitableArea - removableArea)
|
||||||
|
|
||||||
|
rmg::Area entrableArea = getAccessibleArea();
|
||||||
|
rmg::Area blockVisitableArea = getBlockVisitableArea();
|
||||||
|
blockVisitableArea.subtract(getRemovableArea());
|
||||||
|
entrableArea.subtract(blockVisitableArea);
|
||||||
|
|
||||||
|
return entrableArea;
|
||||||
|
}
|
||||||
|
|
||||||
void Object::setPosition(const int3 & position)
|
void Object::setPosition(const int3 & position)
|
||||||
{
|
{
|
||||||
dAccessibleAreaCache.translate(position - dPosition);
|
dAccessibleAreaCache.translate(position - dPosition);
|
||||||
dAccessibleAreaFullCache.translate(position - dPosition);
|
dAccessibleAreaFullCache.translate(position - dPosition);
|
||||||
dBlockVisitableCache.translate(position - dPosition);
|
dBlockVisitableCache.translate(position - dPosition);
|
||||||
|
dRemovableAreaCache.translate(position - dPosition);
|
||||||
dFullAreaCache.translate(position - dPosition);
|
dFullAreaCache.translate(position - dPosition);
|
||||||
|
|
||||||
dPosition = position;
|
dPosition = position;
|
||||||
@@ -390,6 +426,7 @@ void Object::clearCachedArea() const
|
|||||||
dAccessibleAreaCache.clear();
|
dAccessibleAreaCache.clear();
|
||||||
dAccessibleAreaFullCache.clear();
|
dAccessibleAreaFullCache.clear();
|
||||||
dBlockVisitableCache.clear();
|
dBlockVisitableCache.clear();
|
||||||
|
dRemovableAreaCache.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::clear()
|
void Object::clear()
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ public:
|
|||||||
int3 getVisitablePosition() const;
|
int3 getVisitablePosition() const;
|
||||||
bool isVisitableFrom(const int3 & tile) const;
|
bool isVisitableFrom(const int3 & tile) const;
|
||||||
bool isBlockedVisitable() const;
|
bool isBlockedVisitable() const;
|
||||||
|
bool isRemovable() const;
|
||||||
const Area & getAccessibleArea() const;
|
const Area & getAccessibleArea() const;
|
||||||
void setTemplate(TerrainId terrain, CRandomGenerator &); //cache invalidation
|
void setTemplate(TerrainId terrain, CRandomGenerator &); //cache invalidation
|
||||||
void setAnyTemplate(CRandomGenerator &); //cache invalidation
|
void setAnyTemplate(CRandomGenerator &); //cache invalidation
|
||||||
@@ -73,6 +74,8 @@ public:
|
|||||||
int3 getVisitablePosition() const;
|
int3 getVisitablePosition() const;
|
||||||
const Area & getAccessibleArea(bool exceptLast = false) const;
|
const Area & getAccessibleArea(bool exceptLast = false) const;
|
||||||
const Area & getBlockVisitableArea() const;
|
const Area & getBlockVisitableArea() const;
|
||||||
|
const Area & getRemovableArea() const;
|
||||||
|
const Area getEntrableArea() const;
|
||||||
|
|
||||||
const int3 & getPosition() const;
|
const int3 & getPosition() const;
|
||||||
void setPosition(const int3 & position);
|
void setPosition(const int3 & position);
|
||||||
@@ -93,6 +96,7 @@ private:
|
|||||||
mutable Area dFullAreaCache;
|
mutable Area dFullAreaCache;
|
||||||
mutable Area dAccessibleAreaCache, dAccessibleAreaFullCache;
|
mutable Area dAccessibleAreaCache, dAccessibleAreaFullCache;
|
||||||
mutable Area dBlockVisitableCache;
|
mutable Area dBlockVisitableCache;
|
||||||
|
mutable Area dRemovableAreaCache;
|
||||||
int3 dPosition;
|
int3 dPosition;
|
||||||
ui32 dStrength;
|
ui32 dStrength;
|
||||||
bool guarded;
|
bool guarded;
|
||||||
|
|||||||
@@ -664,7 +664,19 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
|
|||||||
if(!guard)
|
if(!guard)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
rmg::Area visitablePos({object.getVisitablePosition()});
|
// Prefer non-blocking tiles, if any
|
||||||
|
auto entrableTiles = object.getEntrableArea().getTiles();
|
||||||
|
int3 entrableTile;
|
||||||
|
if (entrableTiles.empty())
|
||||||
|
{
|
||||||
|
entrableTile = object.getVisitablePosition();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*RandomGeneratorUtil::nextItem(entrableTiles, zone.getRand());
|
||||||
|
}
|
||||||
|
|
||||||
|
rmg::Area visitablePos({entrableTile});
|
||||||
visitablePos.unite(visitablePos.getBorderOutside());
|
visitablePos.unite(visitablePos.getBorderOutside());
|
||||||
|
|
||||||
auto accessibleArea = object.getAccessibleArea();
|
auto accessibleArea = object.getAccessibleArea();
|
||||||
|
|||||||
@@ -625,20 +625,31 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
for(const auto & oi : treasureInfos)
|
for(const auto & oi : treasureInfos)
|
||||||
{
|
{
|
||||||
auto blockedArea = rmgObject.getArea();
|
auto blockedArea = rmgObject.getArea();
|
||||||
auto accessibleArea = rmgObject.getAccessibleArea();
|
auto entrableArea = rmgObject.getEntrableArea();
|
||||||
|
|
||||||
if(rmgObject.instances().empty())
|
if(rmgObject.instances().empty())
|
||||||
accessibleArea.add(int3());
|
entrableArea.add(int3());
|
||||||
|
|
||||||
auto * object = oi->generateObject();
|
auto * object = oi->generateObject();
|
||||||
if(oi->templates.empty())
|
if(oi->templates.empty())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
object->appearance = *RandomGeneratorUtil::nextItem(oi->templates, zone.getRand());
|
object->appearance = *RandomGeneratorUtil::nextItem(oi->templates, zone.getRand());
|
||||||
|
|
||||||
|
auto blockingIssue = object->isBlockedVisitable() && !object->isRemovable();
|
||||||
|
if (blockingIssue)
|
||||||
|
{
|
||||||
|
// Do not place next to another such object (Corpse issue)
|
||||||
|
// Calculate this before instance is added to rmgObject
|
||||||
|
auto blockVisitProximity = rmgObject.getBlockVisitableArea().getBorderOutside();
|
||||||
|
entrableArea.subtract(blockVisitProximity);
|
||||||
|
}
|
||||||
|
|
||||||
auto & instance = rmgObject.addInstance(*object);
|
auto & instance = rmgObject.addInstance(*object);
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
if(accessibleArea.empty())
|
if(entrableArea.empty())
|
||||||
{
|
{
|
||||||
//fail - fallback
|
//fail - fallback
|
||||||
rmgObject.clear();
|
rmgObject.clear();
|
||||||
@@ -649,12 +660,14 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
if(densePlacement)
|
if(densePlacement)
|
||||||
{
|
{
|
||||||
int bestPositionsWeight = std::numeric_limits<int>::max();
|
int bestPositionsWeight = std::numeric_limits<int>::max();
|
||||||
for(const auto & t : accessibleArea.getTilesVector())
|
for(const auto & t : entrableArea.getTilesVector())
|
||||||
{
|
{
|
||||||
instance.setPosition(t);
|
instance.setPosition(t);
|
||||||
int w = rmgObject.getAccessibleArea().getTilesVector().size();
|
int w = rmgObject.getEntrableArea().getTilesVector().size();
|
||||||
if(w < bestPositionsWeight)
|
|
||||||
|
if(w && w < bestPositionsWeight)
|
||||||
{
|
{
|
||||||
|
// Minimum 1 position must be entrable
|
||||||
bestPositions.clear();
|
bestPositions.clear();
|
||||||
bestPositions.push_back(t);
|
bestPositions.push_back(t);
|
||||||
bestPositionsWeight = w;
|
bestPositionsWeight = w;
|
||||||
@@ -664,10 +677,12 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
bestPositions.push_back(t);
|
bestPositions.push_back(t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (bestPositions.empty())
|
||||||
{
|
{
|
||||||
bestPositions = accessibleArea.getTilesVector();
|
bestPositions = entrableArea.getTilesVector();
|
||||||
}
|
}
|
||||||
|
|
||||||
int3 nextPos = *RandomGeneratorUtil::nextItem(bestPositions, zone.getRand());
|
int3 nextPos = *RandomGeneratorUtil::nextItem(bestPositions, zone.getRand());
|
||||||
@@ -676,7 +691,6 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
auto instanceAccessibleArea = instance.getAccessibleArea();
|
auto instanceAccessibleArea = instance.getAccessibleArea();
|
||||||
if(instance.getBlockedArea().getTilesVector().size() == 1)
|
if(instance.getBlockedArea().getTilesVector().size() == 1)
|
||||||
{
|
{
|
||||||
//TOOD: Move hardcoded option to template
|
|
||||||
if(instance.object().appearance->isVisitableFromTop() && !instance.object().isBlockedVisitable())
|
if(instance.object().appearance->isVisitableFromTop() && !instance.object().isBlockedVisitable())
|
||||||
instanceAccessibleArea.add(instance.getVisitablePosition());
|
instanceAccessibleArea.add(instance.getVisitablePosition());
|
||||||
}
|
}
|
||||||
@@ -684,16 +698,12 @@ rmg::Object TreasurePlacer::constructTreasurePile(const std::vector<ObjectInfo*>
|
|||||||
//first object is good
|
//first object is good
|
||||||
if(rmgObject.instances().size() == 1)
|
if(rmgObject.instances().size() == 1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// TODO: Do not place blockvis objects so that they block access to existing accessible area
|
|
||||||
// Either object must be removable, or both must be accessible independently
|
|
||||||
|
|
||||||
//condition for good position
|
if(!blockedArea.overlap(instance.getBlockedArea()) && entrableArea.overlap(instanceAccessibleArea))
|
||||||
if(!blockedArea.overlap(instance.getBlockedArea()) && accessibleArea.overlap(instanceAccessibleArea))
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
//fail - new position
|
//fail - new position
|
||||||
accessibleArea.erase(nextPos);
|
entrableArea.erase(nextPos);
|
||||||
} while(true);
|
} while(true);
|
||||||
}
|
}
|
||||||
return rmgObject;
|
return rmgObject;
|
||||||
|
|||||||
Reference in New Issue
Block a user