mirror of
https://github.com/vcmi/vcmi.git
synced 2024-12-26 22:57:00 +02:00
Merge pull request #1017 from vcmi/fix-mine-templates
Fix incorrect templates for mines in HoTA
This commit is contained in:
commit
360f079bb7
@ -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
|
||||
parser.endLine();
|
||||
|
||||
for (size_t i=0; i<totalNumber; i++)
|
||||
for (size_t i = 0; i < totalNumber; i++)
|
||||
{
|
||||
auto templ = new ObjectTemplate;
|
||||
templ->readTxt(parser);
|
||||
auto tmpl = new ObjectTemplate;
|
||||
|
||||
tmpl->readTxt(parser);
|
||||
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
|
||||
@ -560,10 +562,6 @@ SObjectSounds AObjectTypeHandler::getSounds() const
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -33,19 +33,11 @@ protected:
|
||||
auto obj = new ObjectType();
|
||||
preInitObject(obj);
|
||||
|
||||
//Set custom template or leave null
|
||||
if (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;
|
||||
}
|
||||
|
@ -490,6 +490,7 @@ bool ObjectManager::addGuard(rmg::Object & object, si32 strength, bool zoneGuard
|
||||
|
||||
auto & instance = object.addInstance(*guard);
|
||||
instance.setPosition(guardPos - object.getPosition());
|
||||
instance.setAnyTemplate(); //terrain is irrelevant for monsters, but monsters need some template now
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -105,20 +105,26 @@ void Object::Instance::setPositionRaw(const int3 & position)
|
||||
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())
|
||||
throw rmgException(boost::to_string(boost::format("Did not find any graphics for object (%d,%d)") % dObject.ID % dObject.subID));
|
||||
|
||||
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 templates = VLC->objtypeh->getHandlerFor(dObject.ID, dObject.subID)->getTemplates(terrain);
|
||||
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();
|
||||
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();
|
||||
setPosition(getPosition(false));
|
||||
}
|
||||
@ -283,6 +289,21 @@ void Object::Instance::finalize(RmgMap & map)
|
||||
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()));
|
||||
|
||||
//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()))
|
||||
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()));
|
||||
}
|
||||
|
||||
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())
|
||||
{
|
||||
map.setOccupied(tile, ETileType::ETileType::USED);
|
||||
|
@ -35,7 +35,8 @@ public:
|
||||
int3 getVisitablePosition() const;
|
||||
bool isVisitableFrom(const int3 & tile) 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;
|
||||
void setPosition(const int3 & position); //cache invalidation
|
||||
|
@ -391,56 +391,17 @@ public:
|
||||
else
|
||||
data.reset();
|
||||
}
|
||||
|
||||
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;
|
||||
NonConstT *internalPtr;
|
||||
load(internalPtr);
|
||||
std::shared_ptr<T> nonConstData;
|
||||
|
||||
void *internalPtrDerived = typeList.castToMostDerived(internalPtr);
|
||||
load(nonConstData);
|
||||
|
||||
if(internalPtr)
|
||||
{
|
||||
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();
|
||||
data = nonConstData;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void load(std::unique_ptr<T> &data)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user