mirror of
https://github.com/vcmi/vcmi.git
synced 2025-11-27 22:49:25 +02:00
Fix incorrect templates for mines in HoTA
This commit is contained in:
committed by
Andrii Danylchenko
parent
238dabe060
commit
8c481dff46
@@ -116,13 +116,15 @@ std::vector<JsonNode> CObjectClassesHandler::loadLegacyData(size_t dataSize)
|
|||||||
size_t totalNumber = static_cast<size_t>(parser.readNumber()); // first line contains number of objects to read and nothing else
|
size_t totalNumber = static_cast<size_t>(parser.readNumber()); // first line contains number of objects to read and nothing else
|
||||||
parser.endLine();
|
parser.endLine();
|
||||||
|
|
||||||
for (size_t i=0; i<totalNumber; i++)
|
for (size_t i = 0; i < totalNumber; i++)
|
||||||
{
|
{
|
||||||
auto templ = new ObjectTemplate;
|
auto tmpl = new ObjectTemplate;
|
||||||
templ->readTxt(parser);
|
|
||||||
|
tmpl->readTxt(parser);
|
||||||
parser.endLine();
|
parser.endLine();
|
||||||
std::pair<si32, si32> key(templ->id.num, templ->subid);
|
|
||||||
legacyTemplates.insert(std::make_pair(key, std::shared_ptr<const ObjectTemplate>(templ)));
|
std::pair<si32, si32> key(tmpl->id.num, tmpl->subid);
|
||||||
|
legacyTemplates.insert(std::make_pair(key, std::shared_ptr<const ObjectTemplate>(tmpl)));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<JsonNode> ret(dataSize);// create storage for 256 objects
|
std::vector<JsonNode> ret(dataSize);// create storage for 256 objects
|
||||||
@@ -560,10 +562,6 @@ SObjectSounds AObjectTypeHandler::getSounds() const
|
|||||||
|
|
||||||
void AObjectTypeHandler::addTemplate(std::shared_ptr<const ObjectTemplate> templ)
|
void AObjectTypeHandler::addTemplate(std::shared_ptr<const ObjectTemplate> templ)
|
||||||
{
|
{
|
||||||
//Otherwise the template remains constant
|
|
||||||
auto ptr = const_cast<ObjectTemplate*>(templ.get());
|
|
||||||
ptr->id = Obj(type);
|
|
||||||
ptr->subid = subtype;
|
|
||||||
templates.push_back(templ);
|
templates.push_back(templ);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -33,19 +33,11 @@ protected:
|
|||||||
auto obj = new ObjectType();
|
auto obj = new ObjectType();
|
||||||
preInitObject(obj);
|
preInitObject(obj);
|
||||||
|
|
||||||
|
//Set custom template or leave null
|
||||||
if (tmpl)
|
if (tmpl)
|
||||||
{
|
{
|
||||||
obj->appearance = tmpl;
|
obj->appearance = tmpl;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
auto templates = getTemplates();
|
|
||||||
if (templates.empty())
|
|
||||||
{
|
|
||||||
throw std::runtime_error("No handler for created object");
|
|
||||||
}
|
|
||||||
obj->appearance = templates.front(); //just any template for now, will be initialized later
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -490,6 +490,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
|
|||||||
|
|
||||||
auto & instance = object.addInstance(*guard);
|
auto & instance = object.addInstance(*guard);
|
||||||
instance.setPosition(guardPos - object.getPosition());
|
instance.setPosition(guardPos - object.getPosition());
|
||||||
|
instance.setAnyTemplate(); //terrain is irrelevant for monsters, but monsters need some template now
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,20 +105,26 @@ void Object::Instance::setPositionRaw(const int3 & position)
|
|||||||
dObject.pos = dPosition + dParent.getPosition();
|
dObject.pos = dPosition + dParent.getPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Object::Instance::setTemplate(const TerrainId & terrain)
|
void Object::Instance::setAnyTemplate()
|
||||||
{
|
{
|
||||||
if(dObject.appearance->id == Obj::NO_OBJ)
|
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates();
|
||||||
{
|
if(templates.empty())
|
||||||
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrain);
|
throw rmgException(boost::to_string(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
|
||||||
auto terrainName = VLC->terrainTypeHandler->terrains()[terrain].name;
|
|
||||||
if (templates.empty())
|
|
||||||
{
|
|
||||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") %
|
|
||||||
dObject.ID % dObject.subID % terrainName));
|
|
||||||
}
|
|
||||||
|
|
||||||
dObject.appearance = templates.front();
|
dObject.appearance = templates.front();
|
||||||
|
dAccessibleAreaCache.clear();
|
||||||
|
setPosition(getPosition(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Object::Instance::setTemplate(TerrainId terrain)
|
||||||
|
{
|
||||||
|
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrain);
|
||||||
|
if (templates.empty())
|
||||||
|
{
|
||||||
|
auto terrainName = VLC->terrainTypeHandler->terrains()[terrain].name;
|
||||||
|
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s") % dObject.ID % dObject.subID % terrainName));
|
||||||
}
|
}
|
||||||
|
dObject.appearance = templates.front();
|
||||||
dAccessibleAreaCache.clear();
|
dAccessibleAreaCache.clear();
|
||||||
setPosition(getPosition(false));
|
setPosition(getPosition(false));
|
||||||
}
|
}
|
||||||
@@ -283,6 +289,21 @@ void Object::Instance::finalize(RmgMap & map)
|
|||||||
if(!map.isOnMap(getPosition(true)))
|
if(!map.isOnMap(getPosition(true)))
|
||||||
throw rmgException(boost::to_string(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString()));
|
throw rmgException(boost::to_string(boost::format("Position of object %d at %s is outside the map") % dObject.id % getPosition(true).toString()));
|
||||||
|
|
||||||
|
//If no specific template was defined for this object, select any matching
|
||||||
|
if (!dObject.appearance)
|
||||||
|
{
|
||||||
|
auto terrainType = map.map().getTile(getPosition(true)).terType;
|
||||||
|
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->id);
|
||||||
|
if (templates.empty())
|
||||||
|
{
|
||||||
|
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") % dObject.ID % dObject.subID % getPosition(true).toString() % terrainType));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
setTemplate(terrainType->id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
|
if (dObject.isVisitable() && !map.isOnMap(dObject.visitablePos()))
|
||||||
throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
|
throw rmgException(boost::to_string(boost::format("Visitable tile %s of object %d at %s is outside the map") % dObject.visitablePos().toString() % dObject.id % dObject.pos.toString()));
|
||||||
|
|
||||||
@@ -292,17 +313,6 @@ void Object::Instance::finalize(RmgMap & map)
|
|||||||
throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
|
throw rmgException(boost::to_string(boost::format("Tile %s of object %d at %s is outside the map") % tile.toString() % dObject.id % dObject.pos.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dObject.appearance->id == Obj::NO_OBJ)
|
|
||||||
{
|
|
||||||
auto terrainType = map.map().getTile(getPosition(true)).terType;
|
|
||||||
auto templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrainType->id);
|
|
||||||
if (templates.empty())
|
|
||||||
throw rmgException(boost::to_string(boost::format("Did not find graphics for object (%d,%d) at %s (terrain %d)") %
|
|
||||||
dObject.ID % dObject.subID % getPosition(true).toString() % terrainType->name));
|
|
||||||
|
|
||||||
setTemplate(terrainType->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto & tile : getBlockedArea().getTilesVector())
|
for(auto & tile : getBlockedArea().getTilesVector())
|
||||||
{
|
{
|
||||||
map.setOccupied(tile, ETileType::ETileType::USED);
|
map.setOccupied(tile, ETileType::ETileType::USED);
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ public:
|
|||||||
int3 getVisitablePosition() const;
|
int3 getVisitablePosition() const;
|
||||||
bool isVisitableFrom(const int3 & tile) const;
|
bool isVisitableFrom(const int3 & tile) const;
|
||||||
const Area & getAccessibleArea() const;
|
const Area & getAccessibleArea() const;
|
||||||
void setTemplate(const TerrainId & terrain); //cache invalidation
|
void setTemplate(TerrainId terrain); //cache invalidation
|
||||||
|
void setAnyTemplate(); //cache invalidation
|
||||||
|
|
||||||
int3 getPosition(bool isAbsolute = false) const;
|
int3 getPosition(bool isAbsolute = false) const;
|
||||||
void setPosition(const int3 & position); //cache invalidation
|
void setPosition(const int3 & position); //cache invalidation
|
||||||
|
|||||||
@@ -391,56 +391,17 @@ public:
|
|||||||
else
|
else
|
||||||
data.reset();
|
data.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void load(std::shared_ptr<const T> &data) //version of the above for const ptr
|
void load(std::shared_ptr<const T> & data)
|
||||||
{
|
{
|
||||||
typedef typename std::remove_const<T>::type NonConstT;
|
std::shared_ptr<T> nonConstData;
|
||||||
NonConstT *internalPtr;
|
|
||||||
load(internalPtr);
|
|
||||||
|
|
||||||
void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
|
load(nonConstData);
|
||||||
|
|
||||||
if(internalPtr)
|
data = nonConstData;
|
||||||
{
|
|
||||||
auto itr = loadedSharedPointers.find(internalPtrDerived);
|
|
||||||
if(itr != loadedSharedPointers.end())
|
|
||||||
{
|
|
||||||
// This pointer is already loaded. The "data" needs to be pointed to it,
|
|
||||||
// so their shared state is actually shared.
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto actualType = typeList.getTypeInfo(internalPtr);
|
|
||||||
auto typeWeNeedToReturn = typeList.getTypeInfo<T>();
|
|
||||||
if(*actualType == *typeWeNeedToReturn)
|
|
||||||
{
|
|
||||||
// No casting needed, just unpack already stored shared_ptr and return it
|
|
||||||
data = boost::any_cast<std::shared_ptr<const T>>(itr->second);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We need to perform series of casts
|
|
||||||
auto ret = typeList.castShared(itr->second, actualType, typeWeNeedToReturn);
|
|
||||||
data = boost::any_cast<std::shared_ptr<const T>>(ret);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch(std::exception &e)
|
|
||||||
{
|
|
||||||
logGlobal->error(e.what());
|
|
||||||
logGlobal->error("Failed to cast stored shared ptr. Real type: %s. Needed type %s. FIXME FIXME FIXME", itr->second.type().name(), typeid(std::shared_ptr<T>).name());
|
|
||||||
//TODO scenario with inheritance -> we can have stored ptr to base and load ptr to derived (or vice versa)
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
auto hlp = std::shared_ptr<const T>(internalPtr);
|
|
||||||
data = hlp; //possibly adds const
|
|
||||||
loadedSharedPointers[internalPtrDerived] = typeList.castSharedToMostDerived(hlp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
data.reset();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
void load(std::unique_ptr<T> &data)
|
void load(std::unique_ptr<T> &data)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user