| 
									
										
										
										
											2022-06-20 17:39:50 +03:00
										 |  |  | /*
 | 
					
						
							| 
									
										
										
										
											2017-07-13 11:26:03 +03:00
										 |  |  |  * CObjectClassesHandler.cpp, part of VCMI engine | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * Authors: listed in file AUTHORS in main folder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  * License: GNU General Public License v2.0 or later | 
					
						
							|  |  |  |  * Full text of license available in license.txt file, in main folder | 
					
						
							|  |  |  |  * | 
					
						
							|  |  |  |  */ | 
					
						
							|  |  |  | #include "StdInc.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | #include "CObjectClassesHandler.h"
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 20:26:50 +03:00
										 |  |  | #include "../filesystem/Filesystem.h"
 | 
					
						
							|  |  |  | #include "../filesystem/CBinaryReader.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-23 19:58:19 +02:00
										 |  |  | #include "../VCMI_Lib.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 20:26:50 +03:00
										 |  |  | #include "../GameConstants.h"
 | 
					
						
							| 
									
										
										
										
											2023-08-20 00:22:31 +03:00
										 |  |  | #include "../constants/StringConstants.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 20:26:50 +03:00
										 |  |  | #include "../CGeneralTextHandler.h"
 | 
					
						
							| 
									
										
										
										
											2023-03-15 21:34:29 +02:00
										 |  |  | #include "../GameSettings.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 20:26:50 +03:00
										 |  |  | #include "../JsonNode.h"
 | 
					
						
							| 
									
										
										
										
											2017-09-13 03:35:58 +03:00
										 |  |  | #include "../CSoundBase.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-08 00:04:13 +03:00
										 |  |  | #include "../mapObjectConstructors/CBankInstanceConstructor.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-02 21:47:37 +03:00
										 |  |  | #include "../mapObjectConstructors/CRewardableConstructor.h"
 | 
					
						
							|  |  |  | #include "../mapObjectConstructors/CommonConstructors.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-08 17:29:29 +03:00
										 |  |  | #include "../mapObjectConstructors/DwellingInstanceConstructor.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-07 00:17:39 +03:00
										 |  |  | #include "../mapObjectConstructors/HillFortInstanceConstructor.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-08 00:04:13 +03:00
										 |  |  | #include "../mapObjectConstructors/ShipyardInstanceConstructor.h"
 | 
					
						
							|  |  |  | #include "../mapObjectConstructors/ShrineInstanceConstructor.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-17 15:21:42 +03:00
										 |  |  | #include "../mapObjects/CGCreature.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-02 21:47:37 +03:00
										 |  |  | #include "../mapObjects/CGPandoraBox.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-08 00:04:13 +03:00
										 |  |  | #include "../mapObjects/CQuest.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-02 21:47:37 +03:00
										 |  |  | #include "../mapObjects/ObjectTemplate.h"
 | 
					
						
							| 
									
										
										
										
											2023-06-08 00:42:47 +03:00
										 |  |  | #include "../mapObjects/CGMarket.h"
 | 
					
						
							|  |  |  | #include "../mapObjects/MiscObjects.h"
 | 
					
						
							|  |  |  | #include "../mapObjects/CGHeroInstance.h"
 | 
					
						
							|  |  |  | #include "../mapObjects/CGTownInstance.h"
 | 
					
						
							| 
									
										
										
										
											2023-07-30 20:12:25 +03:00
										 |  |  | #include "../modding/IdentifierStorage.h"
 | 
					
						
							|  |  |  | #include "../modding/CModHandler.h"
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 16:07:42 +03:00
										 |  |  | VCMI_LIB_NAMESPACE_BEGIN | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | CObjectClassesHandler::CObjectClassesHandler() | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | #define SET_HANDLER_CLASS(STRING, CLASSNAME) handlerConstructors[STRING] = std::make_shared<CLASSNAME>;
 | 
					
						
							| 
									
										
										
										
											2017-07-16 12:58:05 +03:00
										 |  |  | #define SET_HANDLER(STRING, TYPENAME) handlerConstructors[STRING] = std::make_shared<CDefaultObjectTypeHandler<TYPENAME>>
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// list of all known handlers, hardcoded for now since the only way to add new objects is via C++ code
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:57:47 +03:00
										 |  |  | 	//Note: should be in sync with registerTypesMapObjectTypes function
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	SET_HANDLER_CLASS("configurable", CRewardableConstructor); | 
					
						
							| 
									
										
										
										
											2023-06-08 17:29:29 +03:00
										 |  |  | 	SET_HANDLER_CLASS("dwelling", DwellingInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2014-06-14 18:42:13 +03:00
										 |  |  | 	SET_HANDLER_CLASS("hero", CHeroInstanceConstructor); | 
					
						
							|  |  |  | 	SET_HANDLER_CLASS("town", CTownInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2014-06-22 13:39:40 +03:00
										 |  |  | 	SET_HANDLER_CLASS("bank", CBankInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2023-04-18 17:27:39 +04:00
										 |  |  | 	SET_HANDLER_CLASS("boat", BoatInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2023-04-28 05:16:10 +04:00
										 |  |  | 	SET_HANDLER_CLASS("market", MarketInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2023-06-06 18:34:04 +03:00
										 |  |  | 	SET_HANDLER_CLASS("shrine", ShrineInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2023-06-07 00:17:39 +03:00
										 |  |  | 	SET_HANDLER_CLASS("hillFort", HillFortInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2023-06-08 00:04:13 +03:00
										 |  |  | 	SET_HANDLER_CLASS("shipyard", ShipyardInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2023-07-15 14:50:09 +03:00
										 |  |  | 	SET_HANDLER_CLASS("monster", CreatureInstanceConstructor); | 
					
						
							|  |  |  | 	SET_HANDLER_CLASS("resource", ResourceInstanceConstructor); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-14 18:42:13 +03:00
										 |  |  | 	SET_HANDLER_CLASS("static", CObstacleConstructor); | 
					
						
							|  |  |  | 	SET_HANDLER_CLASS("", CObstacleConstructor); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-27 19:08:36 +03:00
										 |  |  | 	SET_HANDLER("randomArtifact", CGArtifact); | 
					
						
							|  |  |  | 	SET_HANDLER("randomHero", CGHeroInstance); | 
					
						
							|  |  |  | 	SET_HANDLER("randomResource", CGResource); | 
					
						
							|  |  |  | 	SET_HANDLER("randomTown", CGTownInstance); | 
					
						
							|  |  |  | 	SET_HANDLER("randomMonster", CGCreature); | 
					
						
							|  |  |  | 	SET_HANDLER("randomDwelling", CGDwelling); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-14 18:42:13 +03:00
										 |  |  | 	SET_HANDLER("generic", CGObjectInstance); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	SET_HANDLER("cartographer", CCartographer); | 
					
						
							|  |  |  | 	SET_HANDLER("artifact", CGArtifact); | 
					
						
							|  |  |  | 	SET_HANDLER("borderGate", CGBorderGate); | 
					
						
							|  |  |  | 	SET_HANDLER("borderGuard", CGBorderGuard); | 
					
						
							|  |  |  | 	SET_HANDLER("denOfThieves", CGDenOfthieves); | 
					
						
							|  |  |  | 	SET_HANDLER("event", CGEvent); | 
					
						
							|  |  |  | 	SET_HANDLER("garrison", CGGarrison); | 
					
						
							|  |  |  | 	SET_HANDLER("heroPlaceholder", CGHeroPlaceholder); | 
					
						
							|  |  |  | 	SET_HANDLER("keymaster", CGKeymasterTent); | 
					
						
							|  |  |  | 	SET_HANDLER("lighthouse", CGLighthouse); | 
					
						
							|  |  |  | 	SET_HANDLER("magi", CGMagi); | 
					
						
							|  |  |  | 	SET_HANDLER("mine", CGMine); | 
					
						
							|  |  |  | 	SET_HANDLER("obelisk", CGObelisk); | 
					
						
							|  |  |  | 	SET_HANDLER("observatory", CGObservatory); | 
					
						
							|  |  |  | 	SET_HANDLER("pandora", CGPandoraBox); | 
					
						
							| 
									
										
										
										
											2014-06-17 14:57:47 +03:00
										 |  |  | 	SET_HANDLER("prison", CGHeroInstance); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	SET_HANDLER("questGuard", CGQuestGuard); | 
					
						
							|  |  |  | 	SET_HANDLER("scholar", CGScholar); | 
					
						
							|  |  |  | 	SET_HANDLER("seerHut", CGSeerHut); | 
					
						
							|  |  |  | 	SET_HANDLER("sign", CGSignBottle); | 
					
						
							|  |  |  | 	SET_HANDLER("siren", CGSirens); | 
					
						
							| 
									
										
										
										
											2015-03-08 16:11:23 +03:00
										 |  |  | 	SET_HANDLER("monolith", CGMonolith); | 
					
						
							|  |  |  | 	SET_HANDLER("subterraneanGate", CGSubterraneanGate); | 
					
						
							|  |  |  | 	SET_HANDLER("whirlpool", CGWhirlpool); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	SET_HANDLER("witch", CGWitchHut); | 
					
						
							| 
									
										
										
										
											2022-06-26 10:21:05 +03:00
										 |  |  | 	SET_HANDLER("terrain", CGTerrainPatch); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | #undef SET_HANDLER_CLASS
 | 
					
						
							|  |  |  | #undef SET_HANDLER
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-17 09:24:01 +03:00
										 |  |  | CObjectClassesHandler::~CObjectClassesHandler() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	for(auto * p : objects) | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		delete p; | 
					
						
							| 
									
										
										
										
											2016-08-17 09:24:01 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-15 21:34:29 +02:00
										 |  |  | std::vector<JsonNode> CObjectClassesHandler::loadLegacyData() | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-03-15 21:34:29 +02:00
										 |  |  | 	size_t dataSize = VLC->settings()->getInteger(EGameSettings::TEXTS_OBJECT); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:57:47 +03:00
										 |  |  | 	CLegacyConfigParser parser("Data/Objects.txt"); | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	auto totalNumber = static_cast<size_t>(parser.readNumber()); // first line contains number of objects to read and nothing else
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	parser.endLine(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-09-29 19:07:56 +02:00
										 |  |  | 	for (size_t i = 0; i < totalNumber; i++) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 		auto * tmpl = new ObjectTemplate; | 
					
						
							| 
									
										
										
										
											2022-09-29 19:07:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		tmpl->readTxt(parser); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 		parser.endLine(); | 
					
						
							| 
									
										
										
										
											2022-09-29 19:07:56 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		std::pair<si32, si32> key(tmpl->id.num, tmpl->subid); | 
					
						
							|  |  |  | 		legacyTemplates.insert(std::make_pair(key, std::shared_ptr<const ObjectTemplate>(tmpl))); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-01 20:51:56 +02:00
										 |  |  | 	objects.resize(256); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	std::vector<JsonNode> ret(dataSize);// create storage for 256 objects
 | 
					
						
							|  |  |  | 	assert(dataSize == 256); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-17 14:57:47 +03:00
										 |  |  | 	CLegacyConfigParser namesParser("Data/ObjNames.txt"); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	for (size_t i=0; i<256; i++) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 		ret[i]["name"].String() = namesParser.readString(); | 
					
						
							| 
									
										
										
										
											2014-06-17 14:57:47 +03:00
										 |  |  | 		namesParser.endLine(); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	JsonNode cregen1; | 
					
						
							|  |  |  | 	JsonNode cregen4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | 	CLegacyConfigParser cregen1Parser("data/crgen1"); | 
					
						
							|  |  |  | 	do | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		JsonNode subObject; | 
					
						
							|  |  |  | 		subObject["name"].String() = cregen1Parser.readString(); | 
					
						
							|  |  |  | 		cregen1.Vector().push_back(subObject); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | 	while(cregen1Parser.endLine()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	CLegacyConfigParser cregen4Parser("data/crgen4"); | 
					
						
							|  |  |  | 	do | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	{ | 
					
						
							|  |  |  | 		JsonNode subObject; | 
					
						
							|  |  |  | 		subObject["name"].String() = cregen4Parser.readString(); | 
					
						
							|  |  |  | 		cregen4.Vector().push_back(subObject); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | 	while(cregen4Parser.endLine()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	ret[Obj::CREATURE_GENERATOR1]["subObjects"] = cregen1; | 
					
						
							|  |  |  | 	ret[Obj::CREATURE_GENERATOR4]["subObjects"] = cregen4; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 	ret[Obj::REFUGEE_CAMP]["subObjects"].Vector().push_back(ret[Obj::REFUGEE_CAMP]); | 
					
						
							|  |  |  | 	ret[Obj::WAR_MACHINE_FACTORY]["subObjects"].Vector().push_back(ret[Obj::WAR_MACHINE_FACTORY]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | void CObjectClassesHandler::loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	auto object = loadSubObjectFromJson(scope, identifier, entry, obj, obj->objects.size()); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	assert(object); | 
					
						
							|  |  |  | 	obj->objects.push_back(object); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-20 13:45:27 +02:00
										 |  |  | 	registerObject(scope, obj->getJsonKey(), object->getSubTypeName(), object->subtype); | 
					
						
							| 
									
										
										
										
											2023-04-16 20:42:56 +03:00
										 |  |  | 	for(const auto & compatID : entry["compatibilityIdentifiers"].Vector()) | 
					
						
							| 
									
										
										
										
											2023-04-09 12:27:33 +03:00
										 |  |  | 		registerObject(scope, obj->getJsonKey(), compatID.String(), object->subtype); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | void CObjectClassesHandler::loadSubObject(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	auto object = loadSubObjectFromJson(scope, identifier, entry, obj, index); | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	assert(object); | 
					
						
							|  |  |  | 	assert(obj->objects[index] == nullptr); // ensure that this id was not loaded before
 | 
					
						
							|  |  |  | 	obj->objects[index] = object; | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-20 13:45:27 +02:00
										 |  |  | 	registerObject(scope, obj->getJsonKey(), object->getSubTypeName(), object->subtype); | 
					
						
							| 
									
										
										
										
											2023-04-16 20:42:56 +03:00
										 |  |  | 	for(const auto & compatID : entry["compatibilityIdentifiers"].Vector()) | 
					
						
							| 
									
										
										
										
											2023-04-09 12:27:33 +03:00
										 |  |  | 		registerObject(scope, obj->getJsonKey(), compatID.String(), object->subtype); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | TObjectTypeHandler CObjectClassesHandler::loadSubObjectFromJson(const std::string & scope, const std::string & identifier, const JsonNode & entry, ObjectClass * obj, size_t index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	assert(identifier.find(':') == std::string::npos); | 
					
						
							|  |  |  | 	assert(!scope.empty()); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	if(!handlerConstructors.count(obj->handlerName)) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		logGlobal->error("Handler with name %s was not found!", obj->handlerName); | 
					
						
							|  |  |  | 		return nullptr; | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-30 17:11:25 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	auto createdObject = handlerConstructors.at(obj->handlerName)(); | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	createdObject->modScope = scope; | 
					
						
							|  |  |  | 	createdObject->typeName = obj->identifier;; | 
					
						
							|  |  |  | 	createdObject->subTypeName = identifier; | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	createdObject->type = obj->id; | 
					
						
							|  |  |  | 	createdObject->subtype = index; | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	createdObject->init(entry); | 
					
						
							| 
									
										
										
										
											2020-10-25 01:03:32 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	auto range = legacyTemplates.equal_range(std::make_pair(obj->id, index)); | 
					
						
							|  |  |  | 	for (auto & templ : boost::make_iterator_range(range.first, range.second)) | 
					
						
							| 
									
										
										
										
											2020-10-04 00:06:25 +03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		createdObject->addTemplate(templ.second); | 
					
						
							| 
									
										
										
										
											2021-02-20 04:57:50 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	legacyTemplates.erase(range.first, range.second); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 	logGlobal->debug("Loaded object %s(%d)::%s(%d)", obj->getJsonKey(), obj->id, identifier, index); | 
					
						
							| 
									
										
										
										
											2022-12-30 19:18:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	return createdObject; | 
					
						
							| 
									
										
										
										
											2022-12-30 19:18:31 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | std::string ObjectClass::getJsonKey() const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	return modScope + ':' + identifier; | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string ObjectClass::getNameTextID() const | 
					
						
							| 
									
										
										
										
											2022-12-30 19:18:31 +02:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-19 01:43:12 +02:00
										 |  |  | 	return TextIdentifier("object", modScope, identifier, "name").get(); | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::string ObjectClass::getNameTranslated() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return VLC->generaltexth->translate(getNameTextID()); | 
					
						
							| 
									
										
										
										
											2022-12-30 19:18:31 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | ObjectClass * CObjectClassesHandler::loadFromJson(const std::string & scope, const JsonNode & json, const std::string & name, size_t index) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	auto * obj = new ObjectClass(); | 
					
						
							| 
									
										
										
										
											2022-12-30 19:18:31 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-19 00:54:19 +02:00
										 |  |  | 	obj->modScope = scope; | 
					
						
							|  |  |  | 	obj->identifier = name; | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	obj->handlerName = json["handler"].String(); | 
					
						
							| 
									
										
										
										
											2014-06-16 19:27:26 +03:00
										 |  |  | 	obj->base = json["base"]; | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	obj->id = index; | 
					
						
							| 
									
										
										
										
											2021-04-25 15:07:06 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-09 15:03:49 +02:00
										 |  |  | 	VLC->generaltexth->registerString(scope, obj->getNameTextID(), json["name"].String()); | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	obj->objects.resize(json["lastReservedIndex"].Float() + 1); | 
					
						
							| 
									
										
										
										
											2017-09-13 03:35:58 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	for (auto subData : json["types"].Struct()) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		if (!subData.second["index"].isNull()) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 			const std::string & subMeta = subData.second["index"].meta; | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 			if ( subMeta != "core") | 
					
						
							|  |  |  | 				logMod->warn("Object %s:%s.%s - attempt to load object with preset index! This option is reserved for built-in mod", subMeta, name, subData.first ); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 			size_t subIndex = subData.second["index"].Integer(); | 
					
						
							| 
									
										
										
										
											2023-01-19 01:43:12 +02:00
										 |  |  | 			loadSubObject(subData.second.meta, subData.first, subData.second, obj, subIndex); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		else | 
					
						
							| 
									
										
										
										
											2023-01-19 01:43:12 +02:00
										 |  |  | 			loadSubObject(subData.second.meta, subData.first, subData.second, obj); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	return obj; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	auto * object = loadFromJson(scope, data, name, objects.size()); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	objects.push_back(object); | 
					
						
							| 
									
										
										
										
											2023-08-25 22:36:00 +03:00
										 |  |  | 	VLC->identifiersHandler->registerObject(scope, "object", name, object->id); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CObjectClassesHandler::loadObject(std::string scope, std::string name, const JsonNode & data, size_t index) | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	auto * object = loadFromJson(scope, data, name, index); | 
					
						
							| 
									
										
										
										
											2020-10-01 01:38:06 -07:00
										 |  |  | 	assert(objects[(si32)index] == nullptr); // ensure that this id was not loaded before
 | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	objects[static_cast<si32>(index)] = object; | 
					
						
							| 
									
										
										
										
											2023-08-25 22:36:00 +03:00
										 |  |  | 	VLC->identifiersHandler->registerObject(scope, "object", name, object->id); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | void CObjectClassesHandler::loadSubObject(const std::string & identifier, JsonNode config, si32 ID, si32 subID) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2017-11-26 22:18:18 +01:00
										 |  |  | 	config.setType(JsonNode::JsonType::DATA_STRUCT); // ensure that input is not NULL
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	assert(ID < objects.size()); | 
					
						
							|  |  |  | 	assert(objects[ID]); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-01 20:51:56 +02:00
										 |  |  | 	if ( subID >= objects[ID]->objects.size()) | 
					
						
							|  |  |  | 		objects[ID]->objects.resize(subID+1); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-29 22:34:32 +02:00
										 |  |  | 	JsonUtils::inherit(config, objects.at(ID)->base); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	loadSubObject(config.meta, identifier, config, objects[ID], subID); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 23:51:24 +03:00
										 |  |  | void CObjectClassesHandler::removeSubObject(si32 ID, si32 subID) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	assert(ID < objects.size()); | 
					
						
							|  |  |  | 	assert(objects[ID]); | 
					
						
							|  |  |  | 	assert(subID < objects[ID]->objects.size()); | 
					
						
							|  |  |  | 	objects[ID]->objects[subID] = nullptr; | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::vector<bool> CObjectClassesHandler::getDefaultAllowed() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return std::vector<bool>(); //TODO?
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TObjectTypeHandler CObjectClassesHandler::getHandlerFor(si32 type, si32 subtype) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-08-08 12:50:39 +03:00
										 |  |  | 	try | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		auto result = objects.at(type)->objects.at(subtype); | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-08-08 12:50:39 +03:00
										 |  |  | 		if (result != nullptr) | 
					
						
							|  |  |  | 			return result; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	catch (std::out_of_range & e) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		// Leave catch block silently
 | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	std::string errorString = "Failed to find object of type " + std::to_string(type) + "::" + std::to_string(subtype); | 
					
						
							|  |  |  | 	logGlobal->error(errorString); | 
					
						
							|  |  |  | 	throw std::runtime_error(errorString); | 
					
						
							| 
									
										
										
										
											2015-11-14 16:50:29 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | TObjectTypeHandler CObjectClassesHandler::getHandlerFor(const std::string & scope, const std::string & type, const std::string & subtype) const | 
					
						
							| 
									
										
										
										
											2015-11-14 16:50:29 +03:00
										 |  |  | { | 
					
						
							| 
									
										
										
										
											2023-07-30 20:12:25 +03:00
										 |  |  | 	std::optional<si32> id = VLC->identifiers()->getIdentifier(scope, "object", type); | 
					
						
							| 
									
										
										
										
											2015-11-14 16:50:29 +03:00
										 |  |  | 	if(id) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2023-04-16 20:42:56 +03:00
										 |  |  | 		auto * object = objects[id.value()]; | 
					
						
							| 
									
										
										
										
											2023-07-30 20:12:25 +03:00
										 |  |  | 		std::optional<si32> subID = VLC->identifiers()->getIdentifier(scope, object->getJsonKey(), subtype); | 
					
						
							| 
									
										
										
										
											2018-01-09 10:14:56 +03:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		if (subID) | 
					
						
							| 
									
										
										
										
											2023-04-16 20:42:56 +03:00
										 |  |  | 			return object->objects[subID.value()]; | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-03 20:52:27 +04:00
										 |  |  | 	std::string errorString = "Failed to find object of type " + type + "::" + subtype; | 
					
						
							|  |  |  | 	logGlobal->error(errorString); | 
					
						
							|  |  |  | 	throw std::runtime_error(errorString); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2018-07-22 19:12:11 +02:00
										 |  |  | TObjectTypeHandler CObjectClassesHandler::getHandlerFor(CompoundMapObjectID compoundIdentifier) const | 
					
						
							| 
									
										
										
										
											2018-07-22 18:12:29 +02:00
										 |  |  | { | 
					
						
							|  |  |  | 	return getHandlerFor(compoundIdentifier.primaryID, compoundIdentifier.secondaryID); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 23:51:24 +03:00
										 |  |  | std::set<si32> CObjectClassesHandler::knownObjects() const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::set<si32> ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	for(auto * entry : objects) | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		if (entry) | 
					
						
							|  |  |  | 			ret.insert(entry->id); | 
					
						
							| 
									
										
										
										
											2014-06-05 23:51:24 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | std::set<si32> CObjectClassesHandler::knownSubObjects(si32 primaryID) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	std::set<si32> ret; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-14 21:48:39 +02:00
										 |  |  | 	if (!objects.at(primaryID)) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		logGlobal->error("Failed to find object %d", primaryID); | 
					
						
							|  |  |  | 		return ret; | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	for(const auto & entry : objects.at(primaryID)->objects) | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		if (entry) | 
					
						
							|  |  |  | 			ret.insert(entry->subtype); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 23:51:24 +03:00
										 |  |  | 	return ret; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | void CObjectClassesHandler::beforeValidate(JsonNode & object) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	for (auto & entry : object["types"].Struct()) | 
					
						
							|  |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2023-01-10 16:24:42 +02:00
										 |  |  | 		if (object.Struct().count("subObjects")) | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 			const auto & vector = object["subObjects"].Vector(); | 
					
						
							| 
									
										
										
										
											2023-01-10 16:24:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-20 02:07:22 +02:00
										 |  |  | 			if (entry.second.Struct().count("index")) | 
					
						
							|  |  |  | 			{ | 
					
						
							|  |  |  | 				size_t index = entry.second["index"].Integer(); | 
					
						
							| 
									
										
										
										
											2023-01-10 16:24:42 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-01-20 02:07:22 +02:00
										 |  |  | 				if (index < vector.size()) | 
					
						
							|  |  |  | 					JsonUtils::inherit(entry.second, vector[index]); | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2023-01-10 16:24:42 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-11-30 17:38:53 +02:00
										 |  |  | 		JsonUtils::inherit(entry.second, object["base"]); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 		for (auto & templ : entry.second["templates"].Struct()) | 
					
						
							| 
									
										
										
										
											2022-11-30 17:38:53 +02:00
										 |  |  | 			JsonUtils::inherit(templ.second, entry.second["base"]); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2023-01-10 16:24:42 +02:00
										 |  |  | 	object.Struct().erase("subObjects"); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CObjectClassesHandler::afterLoadFinalization() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	for(auto * entry : objects) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 	{ | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 		if (!entry) | 
					
						
							|  |  |  | 			continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 		for(const auto & obj : entry->objects) | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2023-01-01 20:51:56 +02:00
										 |  |  | 			if (!obj) | 
					
						
							|  |  |  | 				continue; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 			obj->afterLoadFinalization(); | 
					
						
							|  |  |  | 			if(obj->getTemplates().empty()) | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 				logGlobal->warn("No templates found for %s:%s", entry->getJsonKey(), obj->getJsonKey()); | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-09 09:03:40 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 06:58:25 +01:00
										 |  |  | 	generateExtraMonolithsForRMG(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | void CObjectClassesHandler::generateExtraMonolithsForRMG() | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2016-01-09 09:03:40 +01:00
										 |  |  | 	//duplicate existing two-way portals to make reserve for RMG
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	auto& portalVec = objects[Obj::MONOLITH_TWO_WAY]->objects; | 
					
						
							| 
									
										
										
										
											2023-03-16 06:58:25 +01:00
										 |  |  | 	//FIXME: Monoliths  in this vector can be already not useful for every terrain
 | 
					
						
							|  |  |  | 	const size_t portalCount = portalVec.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	//Invalid portals will be skipped and portalVec size stays unchanged
 | 
					
						
							|  |  |  | 	for (size_t i = portalCount; portalVec.size() < 100; ++i) | 
					
						
							|  |  |  | 	{ | 
					
						
							|  |  |  | 		auto index = static_cast<si32>(i % portalCount); | 
					
						
							|  |  |  | 		auto portal = portalVec[index]; | 
					
						
							|  |  |  | 		auto templates = portal->getTemplates(); | 
					
						
							|  |  |  | 		if (templates.empty() || !templates[0]->canBePlacedAtAnyTerrain()) | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			continue; //Do not clone HoTA water-only portals or any others we can't use
 | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2023-01-01 20:51:56 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-03-16 06:58:25 +01:00
										 |  |  | 		//deep copy of noncopyable object :?
 | 
					
						
							|  |  |  | 		auto newPortal = std::make_shared<CDefaultObjectTypeHandler<CGMonolith>>(); | 
					
						
							|  |  |  | 		newPortal->rmgInfo = portal->getRMGInfo(); | 
					
						
							|  |  |  | 		newPortal->base = portal->base; //not needed?
 | 
					
						
							|  |  |  | 		newPortal->templates = portal->getTemplates(); | 
					
						
							|  |  |  | 		newPortal->sounds = portal->getSounds(); | 
					
						
							|  |  |  | 		newPortal->aiValue = portal->getAiValue(); | 
					
						
							|  |  |  | 		newPortal->battlefield = portal->battlefield; //getter is not initialized at this point
 | 
					
						
							|  |  |  | 		newPortal->modScope = portal->modScope; //private
 | 
					
						
							|  |  |  | 		newPortal->typeName = portal->getTypeName();  | 
					
						
							|  |  |  | 		newPortal->subTypeName = std::string("monolith") + std::to_string(portalVec.size()); | 
					
						
							|  |  |  | 		newPortal->type = portal->getIndex(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		newPortal->subtype = portalVec.size(); //indexes must be unique, they are returned as a set
 | 
					
						
							|  |  |  | 		portalVec.push_back(newPortal); | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2014-06-05 19:57:43 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-06-30 00:16:45 +03:00
										 |  |  | std::string CObjectClassesHandler::getObjectName(si32 type, si32 subtype) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-02-12 23:39:17 +03:00
										 |  |  | 	const auto handler = getHandlerFor(type, subtype); | 
					
						
							| 
									
										
										
										
											2023-03-06 00:35:10 +02:00
										 |  |  | 	if (handler && handler->hasNameTextID()) | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 		return handler->getNameTranslated(); | 
					
						
							|  |  |  | 	else | 
					
						
							|  |  |  | 		return objects[type]->getNameTranslated(); | 
					
						
							| 
									
										
										
										
											2017-09-13 03:35:58 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | SObjectSounds CObjectClassesHandler::getObjectSounds(si32 type, si32 subtype) const | 
					
						
							|  |  |  | { | 
					
						
							| 
									
										
										
										
											2023-01-11 00:48:51 +02:00
										 |  |  | 	// TODO: these objects may have subID's that does not have associated handler:
 | 
					
						
							|  |  |  | 	// Prison: uses hero type as subID
 | 
					
						
							|  |  |  | 	// Hero: uses hero type as subID, but registers hero classes as subtypes
 | 
					
						
							|  |  |  | 	// Spell scroll: uses spell ID as subID
 | 
					
						
							| 
									
										
										
										
											2023-01-10 01:30:01 +02:00
										 |  |  | 	if(type == Obj::PRISON || type == Obj::HERO || type == Obj::SPELL_SCROLL) | 
					
						
							| 
									
										
										
										
											2023-01-01 20:51:56 +02:00
										 |  |  | 		subtype = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-12-31 15:01:19 +02:00
										 |  |  | 	assert(type < objects.size()); | 
					
						
							|  |  |  | 	assert(objects[type]); | 
					
						
							|  |  |  | 	assert(subtype < objects[type]->objects.size()); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	return getHandlerFor(type, subtype)->getSounds(); | 
					
						
							| 
									
										
										
										
											2017-09-13 03:35:58 +03:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-30 18:07:30 +02:00
										 |  |  | std::string CObjectClassesHandler::getObjectHandlerName(si32 type) const | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  | 	return objects.at(type)->handlerName; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-26 16:07:42 +03:00
										 |  |  | VCMI_LIB_NAMESPACE_END |