1
0
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:
Tomasz Zieliński
2022-09-29 19:07:56 +02:00
committed by Andrii Danylchenko
parent 238dabe060
commit 8c481dff46
6 changed files with 48 additions and 85 deletions

View File

@@ -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);
} }

View File

@@ -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;
} }

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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

View File

@@ -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)
{ {