1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-12-20 00:22:54 +02:00

Implemented (basic) object construction and placement

* contain refactoring of RMG and class handling (will be more)
This commit is contained in:
AlexVinS
2015-11-14 16:50:29 +03:00
parent 9cc3dae5fe
commit 2d5a366e6c
14 changed files with 334 additions and 209 deletions

View File

@@ -74,7 +74,6 @@ CObjectClassesHandler::CObjectClassesHandler()
SET_HANDLER("pandora", CGPandoraBox);
SET_HANDLER("pickable", CGPickable);
SET_HANDLER("prison", CGHeroInstance);
SET_HANDLER("prison", CGHeroInstance);
SET_HANDLER("questGuard", CGQuestGuard);
SET_HANDLER("resource", CGResource);
SET_HANDLER("scholar", CGScholar);
@@ -148,17 +147,18 @@ si32 selectNextID(const JsonNode & fixedID, const Map & map, si32 defaultID)
return defaultID; // some H3M objects loaded, first modded found
}
void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContainter * obj)
void CObjectClassesHandler::loadObjectEntry(const std::string & identifier, const JsonNode & entry, ObjectContainter * obj)
{
if (!handlerConstructors.count(obj->handlerName))
{
logGlobal->errorStream() << "Handler with name " << obj->handlerName << " was not found!";
return;
}
si32 id = selectNextID(entry["index"], obj->objects, 1000);
si32 id = selectNextID(entry["index"], obj->subObjects, 1000);
auto handler = handlerConstructors.at(obj->handlerName)();
handler->setType(obj->id, id);
handler->setTypeName(obj->identifier, identifier);
if (customNames.count(obj->id) && customNames.at(obj->id).size() > id)
handler->init(entry, customNames.at(obj->id).at(id));
@@ -175,50 +175,49 @@ void CObjectClassesHandler::loadObjectEntry(const JsonNode & entry, ObjectContai
legacyTemplates.erase(range.first, range.second);
}
logGlobal->debugStream() << "Loaded object " << obj->id << ":" << id;
assert(!obj->objects.count(id)); // DO NOT override
obj->objects[id] = handler;
logGlobal->debugStream() << "Loaded object " << obj->identifier << "(" << obj->id << ")" << ":" << identifier << "(" << id << ")" ;
assert(!obj->subObjects.count(id)); // DO NOT override
obj->subObjects[id] = handler;
obj->subIds[identifier] = id;//todo: scope
}
CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(const JsonNode & json)
CObjectClassesHandler::ObjectContainter * CObjectClassesHandler::loadFromJson(const JsonNode & json, const std::string & name)
{
auto obj = new ObjectContainter();
obj->identifier = name;
obj->name = json["name"].String();
obj->handlerName = json["handler"].String();
obj->base = json["base"];
obj->id = selectNextID(json["index"], objects, 256);
for (auto entry : json["types"].Struct())
{
loadObjectEntry(entry.second, obj);
loadObjectEntry(entry.first, entry.second, obj);
}
return obj;
}
void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data)
{
auto object = loadFromJson(data);
auto object = loadFromJson(data, name);
objects[object->id] = object;
VLC->modh->identifiers.registerObject(scope, "object", name, object->id);
}
void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index)
{
auto object = loadFromJson(data);
auto object = loadFromJson(data, name);
assert(objects[index] == nullptr); // ensure that this id was not loaded before
objects[index] = object;
VLC->modh->identifiers.registerObject(scope, "object", name, object->id);
}
void CObjectClassesHandler::loadSubObject(std::string name, JsonNode config, si32 ID, boost::optional<si32> subID)
void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, si32 ID, boost::optional<si32> subID)
{
config.setType(JsonNode::DATA_STRUCT); // ensure that input is not NULL
assert(objects.count(ID));
if (subID)
{
assert(objects.at(ID)->objects.count(subID.get()) == 0);
assert(objects.at(ID)->subObjects.count(subID.get()) == 0);
assert(config["index"].isNull());
config["index"].Float() = subID.get();
}
@@ -227,14 +226,14 @@ void CObjectClassesHandler::loadSubObject(std::string name, JsonNode config, si3
JsonUtils::inherit(config, objects.at(ID)->base);
config.setMeta(oldMeta);
loadObjectEntry(config, objects[ID]);
loadObjectEntry(identifier, config, objects[ID]);
}
void CObjectClassesHandler::removeSubObject(si32 ID, si32 subID)
{
assert(objects.count(ID));
assert(objects.at(ID)->objects.count(subID));
objects.at(ID)->objects.erase(subID);
assert(objects.at(ID)->subObjects.count(subID));
objects.at(ID)->subObjects.erase(subID); //TODO: cleanup string id map
}
std::vector<bool> CObjectClassesHandler::getDefaultAllowed() const
@@ -246,14 +245,28 @@ TObjectTypeHandler CObjectClassesHandler::getHandlerFor(si32 type, si32 subtype)
{
if (objects.count(type))
{
if (objects.at(type)->objects.count(subtype))
return objects.at(type)->objects.at(subtype);
if (objects.at(type)->subObjects.count(subtype))
return objects.at(type)->subObjects.at(subtype);
}
logGlobal->errorStream() << "Failed to find object of type " << type << ":" << subtype;
assert(0); // FIXME: throw error?
throw std::runtime_error("Object type handler not found");
return nullptr;
}
TObjectTypeHandler CObjectClassesHandler::getHandlerFor(std::string type, std::string subtype) const
{
boost::optional<si32> id = VLC->modh->identifiers.getIdentifier("core", "object", type, false);
if(id)
{
si32 subId = objects.at(id.get())->subIds.at(subtype);
return objects.at(id.get())->subObjects.at(subId);
}
logGlobal->errorStream() << "Failed to find object of type " << type << ":" << subtype;
throw std::runtime_error("Object type handler not found");
return nullptr;
}
std::set<si32> CObjectClassesHandler::knownObjects() const
{
std::set<si32> ret;
@@ -270,7 +283,7 @@ std::set<si32> CObjectClassesHandler::knownSubObjects(si32 primaryID) const
if (objects.count(primaryID))
{
for (auto entry : objects.at(primaryID)->objects)
for (auto entry : objects.at(primaryID)->subObjects)
ret.insert(entry.first);
}
return ret;
@@ -292,7 +305,7 @@ void CObjectClassesHandler::afterLoadFinalization()
{
for (auto entry : objects)
{
for (auto obj : entry.second->objects)
for (auto obj : entry.second->subObjects)
{
obj.second->afterLoadFinalization();
if (obj.second->getTemplates().empty())
@@ -331,6 +344,12 @@ void AObjectTypeHandler::setType(si32 type, si32 subtype)
this->subtype = subtype;
}
void AObjectTypeHandler::setTypeName(std::string type, std::string subtype)
{
this->typeName = type;
this->subTypeName = subtype;
}
static ui32 loadJsonOrMax(const JsonNode & input)
{
if (input.isNull())
@@ -377,6 +396,14 @@ bool AObjectTypeHandler::objectFilter(const CGObjectInstance *, const ObjectTemp
return false; // by default there are no overrides
}
void AObjectTypeHandler::preInitObject(CGObjectInstance * obj) const
{
obj->ID = Obj(type);
obj->subID = subtype;
obj->typeName = typeName;
obj->subTypeName = subTypeName;
}
void AObjectTypeHandler::initTypeData(const JsonNode & input)
{
// empty implementation for overrides