mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- compile fix
- fixed crash if json defines only one creature horde
This commit is contained in:
		| @@ -844,4 +844,10 @@ bool AbstractGoal::invalid() const | |||||||
| void AbstractGoal::accept (VCAI * ai) | void AbstractGoal::accept (VCAI * ai) | ||||||
| { | { | ||||||
| 	ai->tryRealize(*this); | 	ai->tryRealize(*this); | ||||||
| }; | } | ||||||
|  |  | ||||||
|  | template<typename T> | ||||||
|  | void CGoal<T>::accept (VCAI * ai) | ||||||
|  | { | ||||||
|  | 	ai->tryRealize(static_cast<T&>(*this)); //casting enforces template instantiation | ||||||
|  | } | ||||||
|   | |||||||
| @@ -144,10 +144,7 @@ public: | |||||||
| 	OSETTER(CGTownInstance *, town) | 	OSETTER(CGTownInstance *, town) | ||||||
| 	OSETTER(int, bid) | 	OSETTER(int, bid) | ||||||
|  |  | ||||||
| 	void accept (VCAI * ai) override | 	void accept (VCAI * ai) override; | ||||||
| 	{ |  | ||||||
| 		ai->tryRealize(static_cast<T&>(*this)); //casting enforces template instantiation |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	CGoal<T> * clone() const override | 	CGoal<T> * clone() const override | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
| @@ -610,6 +610,7 @@ SDLImage::SDLImage(std::string filename, bool compressed): | |||||||
| 	if (surf == nullptr) | 	if (surf == nullptr) | ||||||
| 	{ | 	{ | ||||||
|         logGlobal->errorStream() << "Error: failed to load image "<<filename; |         logGlobal->errorStream() << "Error: failed to load image "<<filename; | ||||||
|  | 		return; | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
|   | |||||||
| @@ -480,9 +480,12 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source) | |||||||
|  |  | ||||||
| 	//  Horde building creature level | 	//  Horde building creature level | ||||||
| 	for(const JsonNode &node : source["horde"].Vector()) | 	for(const JsonNode &node : source["horde"].Vector()) | ||||||
| 	{ |  | ||||||
| 		town.hordeLvl[town.hordeLvl.size()] = node.Float(); | 		town.hordeLvl[town.hordeLvl.size()] = node.Float(); | ||||||
| 	} |  | ||||||
|  | 	// town needs to have exactly 2 horde entries. Validation will take care of 2+ entries | ||||||
|  | 	// but anything below 2 must be handled here | ||||||
|  | 	for (size_t i=source["horde"].Vector().size(); i<2; i++) | ||||||
|  | 		town.hordeLvl[i] = -1; | ||||||
|  |  | ||||||
| 	const JsonVector & creatures = source["creatures"].Vector(); | 	const JsonVector & creatures = source["creatures"].Vector(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -606,13 +606,13 @@ public: | |||||||
| 	}; | 	}; | ||||||
| 	Obj(EObj _num = NO_OBJ) : num(_num) | 	Obj(EObj _num = NO_OBJ) : num(_num) | ||||||
| 	{} | 	{} | ||||||
|  |  | ||||||
| 	ID_LIKE_CLASS_COMMON(Obj, EObj) | 	ID_LIKE_CLASS_COMMON(Obj, EObj) | ||||||
|  |  | ||||||
| 	std::map<int, ConstTransitivePtr<CGDefInfo> > & toDefObjInfo() const; | 	std::map<int, ConstTransitivePtr<CGDefInfo> > & toDefObjInfo() const; | ||||||
|  |  | ||||||
| 	EObj num; | 	EObj num; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| ID_LIKE_OPERATORS_DECLS(Obj, Obj::EObj) | ID_LIKE_OPERATORS_DECLS(Obj, Obj::EObj) | ||||||
|  |  | ||||||
| @@ -744,14 +744,19 @@ public: | |||||||
| 	{ | 	{ | ||||||
| 		FIRST_AVAILABLE = -2, | 		FIRST_AVAILABLE = -2, | ||||||
| 		PRE_FIRST = -1, //sometimes used as error, sometimes as first free in backpack | 		PRE_FIRST = -1, //sometimes used as error, sometimes as first free in backpack | ||||||
| 		HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, RIGHT_RING, LEFT_RING, FEET, MISC1, MISC2, MISC3, MISC4, | 		HEAD, SHOULDERS, NECK, RIGHT_HAND, LEFT_HAND, TORSO, //5 | ||||||
| 		MACH1, MACH2, MACH3, MACH4, SPELLBOOK, MISC5, | 		RIGHT_RING, LEFT_RING, FEET, //8 | ||||||
|  | 		MISC1, MISC2, MISC3, MISC4, //12 | ||||||
|  | 		MACH1, MACH2, MACH3, MACH4, //16 | ||||||
|  | 		SPELLBOOK, MISC5, //18 | ||||||
| 		AFTER_LAST, | 		AFTER_LAST, | ||||||
| 		//cres | 		//cres | ||||||
| 		CREATURE_SLOT = 0, | 		CREATURE_SLOT = 0, | ||||||
| 		COMMANDER1 = 0, COMMANDER2, COMMANDER3, COMMANDER4, COMMANDER5, COMMANDER6, COMMANDER_AFTER_LAST | 		COMMANDER1 = 0, COMMANDER2, COMMANDER3, COMMANDER4, COMMANDER5, COMMANDER6, COMMANDER_AFTER_LAST | ||||||
| 	}; | 	}; | ||||||
|  |  | ||||||
|  | 	static_assert (AFTER_LAST == 19, "incorrect number of artifact slots"); | ||||||
|  |  | ||||||
| 	ArtifactPosition(EArtifactPosition _num = PRE_FIRST) : num(_num) | 	ArtifactPosition(EArtifactPosition _num = PRE_FIRST) : num(_num) | ||||||
| 	{} | 	{} | ||||||
|  |  | ||||||
|   | |||||||
| @@ -133,8 +133,8 @@ void CPrivilagedInfoCallback::getAllTiles (std::unordered_set<int3, ShashInt3> & | |||||||
| 		{ | 		{ | ||||||
| 			for (int yd = 0; yd < gs->map->height; yd++) | 			for (int yd = 0; yd < gs->map->height; yd++) | ||||||
| 			{ | 			{ | ||||||
| 				if ((getTile (int3 (xd,yd,zd))->terType == 8 && water) | 				if ((getTile (int3 (xd,yd,zd))->terType == ETerrainType::WATER && water) | ||||||
| 					|| (getTile (int3 (xd,yd,zd))->terType != 8 && land)) | 					|| (getTile (int3 (xd,yd,zd))->terType != ETerrainType::WATER && land)) | ||||||
| 					tiles.insert(int3(xd,yd,zd)); | 					tiles.insert(int3(xd,yd,zd)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -157,7 +157,7 @@ void CPrivilagedInfoCallback::getFreeTiles (std::vector<int3> &tiles) const | |||||||
| 			for (int yd = 0; yd < gs->map->height; yd++) | 			for (int yd = 0; yd < gs->map->height; yd++) | ||||||
| 			{ | 			{ | ||||||
| 				tinfo = getTile(int3 (xd,yd,zd)); | 				tinfo = getTile(int3 (xd,yd,zd)); | ||||||
| 				if (tinfo->terType != 8 && !tinfo->blocked) //land and free | 				if (tinfo->terType != ETerrainType::WATER && !tinfo->blocked) //land and free | ||||||
| 					tiles.push_back (int3 (xd,yd,zd)); | 					tiles.push_back (int3 (xd,yd,zd)); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| @@ -567,13 +567,13 @@ EBuildingState::EBuildingState CGameInfoCallback::canBuildStructure( const CGTow | |||||||
| { | { | ||||||
| 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED); | 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", EBuildingState::TOWN_NOT_OWNED); | ||||||
|  |  | ||||||
| 	if(!t->town->buildings.count(ID)) | 	if(!t->town->buildings.count(ID)) | ||||||
| 		return EBuildingState::BUILDING_ERROR; | 		return EBuildingState::BUILDING_ERROR; | ||||||
|  |  | ||||||
| 	const CBuilding * pom = t->town->buildings.at(ID); | 	const CBuilding * pom = t->town->buildings.at(ID); | ||||||
|  |  | ||||||
|  |  | ||||||
| 	if(t->hasBuilt(ID))	//already built | 	if(t->hasBuilt(ID))	//already built | ||||||
| 		return EBuildingState::ALREADY_PRESENT; | 		return EBuildingState::ALREADY_PRESENT; | ||||||
|  |  | ||||||
| 	//can we build it? | 	//can we build it? | ||||||
| @@ -634,24 +634,24 @@ std::set<BuildingID> CGameInfoCallback::getBuildingRequiments( const CGTownInsta | |||||||
| { | { | ||||||
| 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", std::set<BuildingID>()); | 	ERROR_RET_VAL_IF(!canGetFullInfo(t), "Town is not owned!", std::set<BuildingID>()); | ||||||
| 	ERROR_RET_VAL_IF(!t->town->buildings.count(ID), "No such building!", std::set<BuildingID>()); | 	ERROR_RET_VAL_IF(!t->town->buildings.count(ID), "No such building!", std::set<BuildingID>()); | ||||||
|  |  | ||||||
| 	std::set<int> used; | 	std::set<int> used; | ||||||
| 	used.insert(ID); | 	used.insert(ID); | ||||||
| 	auto reqs = t->town->buildings.at(ID)->requirements; | 	auto reqs = t->town->buildings.at(ID)->requirements; | ||||||
|  |  | ||||||
| 	bool found; | 	bool found; | ||||||
| 	do | 	do | ||||||
| 	{ | 	{ | ||||||
| 		found = false; | 		found = false; | ||||||
| 		for(auto i=reqs.begin();i!=reqs.end();i++) | 		for(auto i=reqs.begin();i!=reqs.end();i++) | ||||||
| 		{ | 		{ | ||||||
| 			if(used.find(*i)==used.end()) //we haven't added requirements for this building | 			if(used.find(*i)==used.end()) //we haven't added requirements for this building | ||||||
| 			{ | 			{ | ||||||
| 				found = true; | 				found = true; | ||||||
| 				auto & requires = t->town->buildings.at(*i)->requirements; | 				auto & requires = t->town->buildings.at(*i)->requirements; | ||||||
|  |  | ||||||
| 				used.insert(*i); | 				used.insert(*i); | ||||||
| 				for(auto & require : requires) | 				for(auto & require : requires) | ||||||
| 					reqs.insert(require);//creating full list of requirements | 					reqs.insert(require);//creating full list of requirements | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user