mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	SpellSchool: use identifier instead of int
Needs redifinition of MAGIC_SCHOOL_SKILL in all mods
This commit is contained in:
		| @@ -82,11 +82,11 @@ public: | ||||
| 			return false; | ||||
|  | ||||
|  | ||||
| 		for(ui8 schoolId = 0; schoolId < 4; schoolId++) | ||||
| 		for(auto schoolId = 0; schoolId < GameConstants::DEFAULT_SCHOOLS; schoolId++) | ||||
| 		{ | ||||
| 			if(A->school.at((ESpellSchool)schoolId) && !B->school.at((ESpellSchool)schoolId)) | ||||
| 			if(A->school.at(SpellSchool(schoolId)) && !B->school.at(SpellSchool(schoolId))) | ||||
| 				return true; | ||||
| 			if(!A->school.at((ESpellSchool)schoolId) && B->school.at((ESpellSchool)schoolId)) | ||||
| 			if(!A->school.at(SpellSchool(schoolId)) && B->school.at(SpellSchool(schoolId))) | ||||
| 				return false; | ||||
| 		} | ||||
|  | ||||
| @@ -320,7 +320,7 @@ void CSpellWindow::computeSpellsPerArea() | ||||
| 	for(const CSpell * spell : mySpells) | ||||
| 	{ | ||||
| 		if(spell->isCombat() ^ !battleSpellsOnly | ||||
| 			&& ((selectedTab == 4) || spell->school.at((ESpellSchool)selectedTab)) | ||||
| 			&& ((selectedTab == 4) || spell->school.at(SpellSchool(selectedTab))) | ||||
| 			) | ||||
| 		{ | ||||
| 			spellsCurSite.push_back(spell); | ||||
|   | ||||
| @@ -1185,7 +1185,7 @@ | ||||
| 		"bonuses" : [ | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE", | ||||
| 				"subtype" : 0, | ||||
| 				"subtype" : "spellSchool.air", | ||||
| 				"val" : 50, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -1198,7 +1198,7 @@ | ||||
| 		"bonuses" : [ | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE", | ||||
| 				"subtype" : 3, | ||||
| 				"subtype" : "spellSchool.earth", | ||||
| 				"val" : 50, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -1211,7 +1211,7 @@ | ||||
| 		"bonuses" : [ | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE", | ||||
| 				"subtype" : 1, | ||||
| 				"subtype" : "spellSchool.fire", | ||||
| 				"val" : 50, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -1224,7 +1224,7 @@ | ||||
| 		"bonuses" : [ | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE", | ||||
| 				"subtype" : 2, | ||||
| 				"subtype" : "spellSchool.water", | ||||
| 				"val" : 50, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 0, | ||||
| 				"subtype" : "spellSchool.any", | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -29,7 +29,7 @@ | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 2, | ||||
| 				"subtype" : "spellSchool.fire", | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -41,7 +41,7 @@ | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 8, | ||||
| 				"subtype" : "spellSchool.earth", | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -53,7 +53,7 @@ | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 1, | ||||
| 				"subtype" : "spellSchool.air", | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
| @@ -65,7 +65,7 @@ | ||||
| 		"bonuses": [ | ||||
| 			{ | ||||
| 				"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 				"subtype" : 4, | ||||
| 				"subtype" : "spellSchool.water", | ||||
| 				"val" : 3, | ||||
| 				"valueType" : "BASE_NUMBER" | ||||
| 			} | ||||
|   | ||||
| @@ -10,7 +10,7 @@ | ||||
| 			"magicResistance" : | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 				"subtype" : -1, | ||||
| 				"subtype" : "spellSchool.any", | ||||
| 				"val" : 85 | ||||
| 			}, | ||||
| 			"nonliving" : | ||||
| @@ -41,7 +41,7 @@ | ||||
| 			"magicResistance" : | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 				"subtype" : -1, | ||||
| 				"subtype" : "spellSchool.any", | ||||
| 				"val" : 95 | ||||
| 			}, | ||||
| 			"nonliving" : | ||||
|   | ||||
| @@ -105,7 +105,7 @@ | ||||
| 			"magicResistance" : | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 				"subtype" : -1, | ||||
| 				"subtype" : "spellSchool.any", | ||||
| 				"val" : 50 | ||||
| 			}, | ||||
| 			"nonliving" : | ||||
| @@ -137,7 +137,7 @@ | ||||
| 			"magicResistance" : | ||||
| 			{ | ||||
| 				"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 				"subtype" : -1, | ||||
| 				"subtype" : "spellSchool.any", | ||||
| 				"val" : 75 | ||||
| 			}, | ||||
| 			"nonliving" : | ||||
|   | ||||
| @@ -215,6 +215,7 @@ | ||||
| 				"spellDamage" :  | ||||
| 				{ | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"val" : 100, | ||||
| 					"valueType" : "BASE_NUMBER" | ||||
| 				}, | ||||
|   | ||||
| @@ -186,6 +186,7 @@ | ||||
| 				"sorcery" : { | ||||
| 					"targetSourceType" : "SECONDARY_SKILL", | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"updater" : "TIMES_HERO_LEVEL", | ||||
| 					"val" : 5, | ||||
| 					"valueType" : "PERCENT_TO_TARGET_TYPE" | ||||
|   | ||||
| @@ -262,6 +262,7 @@ | ||||
| 				"sorcery" : { | ||||
| 					"targetSourceType" : "SECONDARY_SKILL", | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"updater" : "TIMES_HERO_LEVEL", | ||||
| 					"val" : 5, | ||||
| 					"valueType" : "PERCENT_TO_TARGET_TYPE" | ||||
|   | ||||
| @@ -261,6 +261,7 @@ | ||||
| 				"sorcery" : { | ||||
| 					"targetSourceType" : "SECONDARY_SKILL", | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"updater" : "TIMES_HERO_LEVEL", | ||||
| 					"val" : 5, | ||||
| 					"valueType" : "PERCENT_TO_TARGET_TYPE" | ||||
|   | ||||
| @@ -192,6 +192,7 @@ | ||||
| 				"sorcery" : { | ||||
| 					"targetSourceType" : "SECONDARY_SKILL", | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"updater" : "TIMES_HERO_LEVEL", | ||||
| 					"val" : 5, | ||||
| 					"valueType" : "PERCENT_TO_TARGET_TYPE" | ||||
|   | ||||
| @@ -135,6 +135,7 @@ | ||||
| 				"sorcery" : { | ||||
| 					"targetSourceType" : "SECONDARY_SKILL", | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"updater" : "TIMES_HERO_LEVEL", | ||||
| 					"val" : 5, | ||||
| 					"valueType" : "PERCENT_TO_TARGET_TYPE" | ||||
| @@ -239,6 +240,7 @@ | ||||
| 				"sorcery" : { | ||||
| 					"targetSourceType" : "SECONDARY_SKILL", | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"updater" : "TIMES_HERO_LEVEL", | ||||
| 					"val" : 5, | ||||
| 					"valueType" : "PERCENT_TO_TARGET_TYPE" | ||||
|   | ||||
| @@ -406,7 +406,7 @@ | ||||
| 		"base" : { | ||||
| 			"effects" : { | ||||
| 				"main" : { | ||||
| 					"subtype" : 2, | ||||
| 					"subtype" : "spellSchool.fire", | ||||
| 					"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 					"valueType" : "BASE_NUMBER" | ||||
| 				} | ||||
| @@ -434,7 +434,7 @@ | ||||
| 		"base" : { | ||||
| 			"effects" : { | ||||
| 				"main" : { | ||||
| 					"subtype" : 1, | ||||
| 					"subtype" : "spellSchool.air", | ||||
| 					"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 					"valueType" : "BASE_NUMBER" | ||||
| 				} | ||||
| @@ -462,7 +462,7 @@ | ||||
| 		"base" : { | ||||
| 			"effects" : { | ||||
| 				"main" : { | ||||
| 					"subtype" : 4, | ||||
| 					"subtype" : "spellSchool.water", | ||||
| 					"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 					"valueType" : "BASE_NUMBER" | ||||
| 				} | ||||
| @@ -490,7 +490,7 @@ | ||||
| 		"base" : { | ||||
| 			"effects" : { | ||||
| 				"main" : { | ||||
| 					"subtype" : 8, | ||||
| 					"subtype" : "spellSchool.earth", | ||||
| 					"type" : "MAGIC_SCHOOL_SKILL", | ||||
| 					"valueType" : "BASE_NUMBER" | ||||
| 				} | ||||
| @@ -737,6 +737,7 @@ | ||||
| 			"effects" : { | ||||
| 				"main" : { | ||||
| 					"type" : "SPELL_DAMAGE", | ||||
| 					"subtype" : "spellSchool.any", | ||||
| 					"valueType" : "BASE_NUMBER" | ||||
| 				} | ||||
| 			} | ||||
|   | ||||
| @@ -104,7 +104,7 @@ | ||||
| 				"effects" : { | ||||
| 					"spellDamageReduction" : { | ||||
| 						"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 						"subtype" : 0, | ||||
| 						"subtype" : "spellSchool.air", | ||||
| 						"duration" : "N_TURNS", | ||||
| 						"val" : 30 | ||||
| 					} | ||||
| @@ -147,7 +147,7 @@ | ||||
| 				"effects" : { | ||||
| 					"spellDamageReduction" : { | ||||
| 						"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 						"subtype" : 1, | ||||
| 						"subtype" : "spellSchool.fire", | ||||
| 						"duration" : "N_TURNS", | ||||
| 						"val" : 30 | ||||
| 					} | ||||
| @@ -190,7 +190,7 @@ | ||||
| 				"effects" : { | ||||
| 					"spellDamageReduction" : { | ||||
| 						"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 						"subtype" : 2, | ||||
| 						"subtype" : "spellSchool.water", | ||||
| 						"duration" : "N_TURNS", | ||||
| 						"val" : 30 | ||||
| 					} | ||||
| @@ -233,7 +233,7 @@ | ||||
| 				"effects" : { | ||||
| 					"spellDamageReduction" : { | ||||
| 						"type" : "SPELL_DAMAGE_REDUCTION", | ||||
| 						"subtype" : 3, | ||||
| 						"subtype" : "spellSchool.earth", | ||||
| 						"duration" : "N_TURNS", | ||||
| 						"val" : 30 | ||||
| 					} | ||||
|   | ||||
| @@ -1059,7 +1059,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars | ||||
| 		b.type = BonusType::FEAR; break; | ||||
| 	case 'g': | ||||
| 		b.type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 		b.subtype = -1; //all magic schools | ||||
| 		b.subtype = SpellSchool(ESpellSchool::ANY); | ||||
| 		break; | ||||
| 	case 'P': | ||||
| 		b.type = BonusType::CASTS; break; | ||||
| @@ -1179,7 +1179,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars | ||||
| 				break; | ||||
| 			case 'O': | ||||
| 				b.type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 				b.subtype = 1; //Fire school | ||||
| 				b.subtype = SpellSchool(ESpellSchool::FIRE); | ||||
| 				b.val = 100; //Full damage immunity | ||||
| 				break; | ||||
| 			case 'f': | ||||
| @@ -1192,7 +1192,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars | ||||
| 				break; | ||||
| 			case 'W': | ||||
| 				b.type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 				b.subtype = 2; //Water school | ||||
| 				b.subtype = SpellSchool(ESpellSchool::WATER); | ||||
| 				b.val = 100; //Full damage immunity | ||||
| 				break; | ||||
| 			case 'w': | ||||
| @@ -1201,7 +1201,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars | ||||
| 				break; | ||||
| 			case 'E': | ||||
| 				b.type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 				b.subtype = 3; //Earth school | ||||
| 				b.subtype = SpellSchool(ESpellSchool::EARTH); | ||||
| 				b.val = 100; //Full damage immunity | ||||
| 				break; | ||||
| 			case 'e': | ||||
| @@ -1210,7 +1210,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars | ||||
| 				break; | ||||
| 			case 'A': | ||||
| 				b.type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 				b.subtype = 0; //Air school | ||||
| 				b.subtype = SpellSchool(ESpellSchool::AIR); | ||||
| 				b.val = 100; //Full damage immunity | ||||
| 				break; | ||||
| 			case 'a': | ||||
| @@ -1219,7 +1219,7 @@ void CCreatureHandler::loadStackExp(Bonus & b, BonusList & bl, CLegacyConfigPars | ||||
| 				break; | ||||
| 			case 'D': | ||||
| 				b.type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 				b.subtype = -1; //all | ||||
| 				b.subtype = SpellSchool(ESpellSchool::ANY); | ||||
| 				b.val = 100; //Full damage immunity | ||||
| 				break; | ||||
| 			case '0': | ||||
|   | ||||
| @@ -7,6 +7,7 @@ | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| #include "GameConstants.h" | ||||
| #include "StdInc.h" | ||||
| #include "CModHandler.h" | ||||
| #include "mapObjects/CObjectClassesHandler.h" | ||||
| @@ -745,6 +746,12 @@ void CModInfo::setEnabled(bool on) | ||||
|  | ||||
| CModHandler::CModHandler() : content(std::make_shared<CContentHandler>()) | ||||
| { | ||||
| 	//TODO: moddable spell schools | ||||
| 	for (auto i = 0; i < GameConstants::DEFAULT_SCHOOLS; ++i) | ||||
| 		identifiers.registerObject(CModHandler::scopeBuiltin(), "spellSchool", SpellConfig::SCHOOL[i].jsonName, SpellConfig::SCHOOL[i].id); | ||||
|  | ||||
| 	identifiers.registerObject(CModHandler::scopeBuiltin(), "spellSchool", "any", SpellSchool(ESpellSchool::ANY)); | ||||
|  | ||||
| 	for (int i = 0; i < GameConstants::RESOURCE_QUANTITY; ++i) | ||||
| 	{ | ||||
| 		identifiers.registerObject(CModHandler::scopeBuiltin(), "resource", GameConstants::RESOURCE_NAMES[i], i); | ||||
|   | ||||
| @@ -50,6 +50,7 @@ namespace GameConstants | ||||
| 	constexpr int CREATURES_PER_TOWN = 7; //without upgrades | ||||
| 	constexpr int SPELL_LEVELS = 5; | ||||
| 	constexpr int SPELL_SCHOOL_LEVELS = 4; | ||||
| 	constexpr int DEFAULT_SCHOOLS = 4; | ||||
| 	constexpr int CRE_LEVELS = 10; // number of creature experience levels | ||||
|  | ||||
| 	constexpr int HERO_GOLD_COST = 2500; | ||||
| @@ -1296,14 +1297,17 @@ class Obstacle : public BaseForID<Obstacle, si32> | ||||
| 	DLL_LINKAGE static Obstacle fromString(const std::string & identifier); | ||||
| }; | ||||
|  | ||||
| enum class ESpellSchool: ui8 | ||||
| enum class ESpellSchool: int8_t | ||||
| { | ||||
| 	ANY 	= -1, | ||||
| 	AIR 	= 0, | ||||
| 	FIRE 	= 1, | ||||
| 	WATER 	= 2, | ||||
| 	EARTH 	= 3 | ||||
| 	EARTH 	= 3, | ||||
| }; | ||||
|  | ||||
| using SpellSchool = Identifier<ESpellSchool>; | ||||
|  | ||||
| enum class EMetaclass: ui8 | ||||
| { | ||||
| 	INVALID = 0, | ||||
|   | ||||
| @@ -74,7 +74,10 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu | ||||
| 			valueType = BonusValueType::PERCENT_TO_BASE; | ||||
| 		} | ||||
| 		else if(deprecatedSubtype == SecondarySkill::SORCERY || deprecatedSubtypeStr == "skill.sorcery") | ||||
| 		{ | ||||
| 			type = BonusType::SPELL_DAMAGE; | ||||
| 			subtype = SpellSchool(ESpellSchool::ANY); | ||||
| 		} | ||||
| 		else if(deprecatedSubtype == SecondarySkill::SCHOLAR || deprecatedSubtypeStr == "skill.scholar") | ||||
| 			type = BonusType::LEARN_MEETING_SPELL_LIMIT; | ||||
| 		else if(deprecatedSubtype == SecondarySkill::ARCHERY|| deprecatedSubtypeStr == "skill.archery") | ||||
| @@ -112,22 +115,22 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu | ||||
| 		else if(deprecatedSubtype == SecondarySkill::AIR_MAGIC || deprecatedSubtypeStr == "skill.airMagic") | ||||
| 		{ | ||||
| 			type = BonusType::MAGIC_SCHOOL_SKILL; | ||||
| 			subtype = 4; | ||||
| 			subtype = SpellSchool(ESpellSchool::AIR); | ||||
| 		} | ||||
| 		else if(deprecatedSubtype == SecondarySkill::WATER_MAGIC || deprecatedSubtypeStr == "skill.waterMagic") | ||||
| 		{ | ||||
| 			type = BonusType::MAGIC_SCHOOL_SKILL; | ||||
| 			subtype = 1; | ||||
| 			subtype = SpellSchool(ESpellSchool::WATER); | ||||
| 		} | ||||
| 		else if(deprecatedSubtype == SecondarySkill::FIRE_MAGIC || deprecatedSubtypeStr == "skill.fireMagic") | ||||
| 		{ | ||||
| 			type = BonusType::MAGIC_SCHOOL_SKILL; | ||||
| 			subtype = 2; | ||||
| 			subtype = SpellSchool(ESpellSchool::FIRE); | ||||
| 		} | ||||
| 		else if(deprecatedSubtype == SecondarySkill::EARTH_MAGIC || deprecatedSubtypeStr == "skill.earthMagic") | ||||
| 		{ | ||||
| 			type = BonusType::MAGIC_SCHOOL_SKILL; | ||||
| 			subtype = 8; | ||||
| 			subtype = SpellSchool(ESpellSchool::EARTH); | ||||
| 		} | ||||
| 		else if (deprecatedSubtype == SecondarySkill::ARTILLERY || deprecatedSubtypeStr == "skill.artillery") | ||||
| 		{ | ||||
| @@ -215,47 +218,48 @@ BonusParams::BonusParams(std::string deprecatedTypeStr, std::string deprecatedSu | ||||
| 	else if (deprecatedTypeStr == "DIRECT_DAMAGE_IMMUNITY") | ||||
| 	{ | ||||
| 		type = BonusType::SPELL_DAMAGE_REDUCTION; | ||||
| 		subtype = SpellSchool(ESpellSchool::ANY); | ||||
| 		val = 100; | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "AIR_SPELL_DMG_PREMY") | ||||
| 	{ | ||||
| 		type = BonusType::SPELL_DAMAGE; | ||||
| 		subtype = 0; | ||||
| 		subtype = SpellSchool(ESpellSchool::AIR); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "FIRE_SPELL_DMG_PREMY") | ||||
| 	{ | ||||
| 		type = BonusType::SPELL_DAMAGE; | ||||
| 		subtype = 1; | ||||
| 		subtype = SpellSchool(ESpellSchool::FIRE); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "WATER_SPELL_DMG_PREMY") | ||||
| 	{ | ||||
| 		type = BonusType::SPELL_DAMAGE; | ||||
| 		subtype = 2; | ||||
| 		subtype = SpellSchool(ESpellSchool::WATER); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "EARTH_SPELL_DMG_PREMY") | ||||
| 	{ | ||||
| 		type = BonusType::SPELL_DAMAGE; | ||||
| 		subtype = 3; | ||||
| 		subtype = SpellSchool(ESpellSchool::EARTH); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "AIR_SPELLS") | ||||
| 	{ | ||||
| 		type = BonusType::SPELLS_OF_SCHOOL; | ||||
| 		subtype = 0; | ||||
| 		subtype = SpellSchool(ESpellSchool::AIR); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "FIRE_SPELLS") | ||||
| 	{ | ||||
| 		type = BonusType::SPELLS_OF_SCHOOL; | ||||
| 		subtype = 1; | ||||
| 		subtype = SpellSchool(ESpellSchool::FIRE); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "WATER_SPELLS") | ||||
| 	{ | ||||
| 		type = BonusType::SPELLS_OF_SCHOOL; | ||||
| 		subtype = 2; | ||||
| 		subtype = SpellSchool(ESpellSchool::WATER); | ||||
| 	} | ||||
| 	else if (deprecatedTypeStr == "EARTH_SPELLS") | ||||
| 	{ | ||||
| 		type = BonusType::SPELLS_OF_SCHOOL; | ||||
| 		subtype = 3; | ||||
| 		subtype = SpellSchool(ESpellSchool::EARTH); | ||||
| 	} | ||||
| 	else | ||||
| 		isConverted = false; | ||||
|   | ||||
| @@ -589,7 +589,7 @@ int32_t CGHeroInstance::getSpellSchoolLevel(const spells::Spell * spell, int32_t | ||||
|  | ||||
| 	spell->forEachSchool([&, this](const spells::SchoolInfo & cnf, bool & stop) | ||||
| 	{ | ||||
| 		int32_t thisSchool = valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, 1 << (static_cast<ui8>(cnf.id))); //FIXME: Bonus shouldn't be additive (Witchking Artifacts : Crown of Skies) | ||||
| 		int32_t thisSchool = valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, cnf.id); //FIXME: Bonus shouldn't be additive (Witchking Artifacts : Crown of Skies) | ||||
| 		if(thisSchool > skill) | ||||
| 		{ | ||||
| 			skill = thisSchool; | ||||
| @@ -598,7 +598,7 @@ int32_t CGHeroInstance::getSpellSchoolLevel(const spells::Spell * spell, int32_t | ||||
| 		} | ||||
| 	}); | ||||
|  | ||||
| 	vstd::amax(skill, valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, 0)); //any school bonus | ||||
| 	vstd::amax(skill, valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, SpellSchool(ESpellSchool::ANY))); //any school bonus | ||||
| 	vstd::amax(skill, valOfBonuses(BonusType::SPELL, spell->getIndex())); //given by artifact or other effect | ||||
|  | ||||
| 	vstd::amax(skill, 0); //in case we don't know any school | ||||
| @@ -611,7 +611,7 @@ int64_t CGHeroInstance::getSpellBonus(const spells::Spell * spell, int64_t base, | ||||
| 	//applying sorcery secondary skill | ||||
|  | ||||
| 	if(spell->isMagical()) | ||||
| 		base = static_cast<int64_t>(base * (valOfBonuses(BonusType::SPELL_DAMAGE)) / 100.0); | ||||
| 		base = static_cast<int64_t>(base * (valOfBonuses(BonusType::SPELL_DAMAGE, SpellSchool(ESpellSchool::ANY))) / 100.0); | ||||
|  | ||||
| 	base = static_cast<int64_t>(base * (100 + valOfBonuses(BonusType::SPECIFIC_SPELL_DAMAGE, spell->getIndex())) / 100.0); | ||||
|  | ||||
| @@ -619,7 +619,7 @@ int64_t CGHeroInstance::getSpellBonus(const spells::Spell * spell, int64_t base, | ||||
|  | ||||
| 	spell->forEachSchool([&maxSchoolBonus, this](const spells::SchoolInfo & cnf, bool & stop) | ||||
| 	{ | ||||
| 		vstd::amax(maxSchoolBonus, valOfBonuses(BonusType::SPELL_DAMAGE, vstd::to_underlying(cnf.id))); | ||||
| 		vstd::amax(maxSchoolBonus, valOfBonuses(BonusType::SPELL_DAMAGE, cnf.id)); | ||||
| 	}); | ||||
|  | ||||
| 	base = static_cast<int64_t>(base * (100 + maxSchoolBonus) / 100.0); | ||||
| @@ -708,7 +708,7 @@ bool CGHeroInstance::canCastThisSpell(const spells::Spell * spell) const | ||||
|  | ||||
| 	spell->forEachSchool([this, &schoolBonus](const spells::SchoolInfo & cnf, bool & stop) | ||||
| 	{ | ||||
| 		if(hasBonusOfType(BonusType::SPELLS_OF_SCHOOL, vstd::to_underlying(cnf.id))) | ||||
| 		if(hasBonusOfType(BonusType::SPELLS_OF_SCHOOL, cnf.id)) | ||||
| 		{ | ||||
| 			schoolBonus = stop = true; | ||||
| 		} | ||||
|   | ||||
| @@ -343,7 +343,7 @@ void TreasurePlacer::addAllPossibleObjects() | ||||
| 			std::vector <CSpell *> spells; | ||||
| 			for(auto spell : VLC->spellh->objects) | ||||
| 			{ | ||||
| 				if(map.isAllowedSpell(spell->id) && spell->school[static_cast<ESpellSchool>(i)]) | ||||
| 				if(map.isAllowedSpell(spell->id) && spell->school[SpellSchool(i)]) | ||||
| 					spells.push_back(spell); | ||||
| 			} | ||||
| 			 | ||||
|   | ||||
| @@ -35,7 +35,7 @@ int32_t AbilityCaster::getSpellSchoolLevel(const Spell * spell, int32_t * outSel | ||||
|  | ||||
| 	if(spell->getLevel() > 0) | ||||
| 	{ | ||||
| 		vstd::amax(skill, unit->valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, 0)); | ||||
| 		vstd::amax(skill, unit->valOfBonuses(BonusType::MAGIC_SCHOOL_SKILL, SpellSchool(ESpellSchool::ANY))); | ||||
| 	} | ||||
|  | ||||
| 	vstd::amax(skill, 0); | ||||
|   | ||||
| @@ -38,7 +38,7 @@ namespace SpellConfig | ||||
| { | ||||
| static const std::string LEVEL_NAMES[] = {"none", "basic", "advanced", "expert"}; | ||||
|  | ||||
| static const spells::SchoolInfo SCHOOL[4] = | ||||
| const spells::SchoolInfo SCHOOL[4] = | ||||
| { | ||||
| 	{ | ||||
| 		ESpellSchool::AIR, | ||||
| @@ -63,7 +63,7 @@ static const spells::SchoolInfo SCHOOL[4] = | ||||
| }; | ||||
|  | ||||
| //order as described in http://bugs.vcmi.eu/view.php?id=91 | ||||
| static const ESpellSchool SCHOOL_ORDER[4] = | ||||
| static const SpellSchool SCHOOL_ORDER[4] = | ||||
| { | ||||
| 	ESpellSchool::AIR,  //=0 | ||||
| 	ESpellSchool::FIRE, //=1 | ||||
| @@ -150,9 +150,9 @@ spells::AimType CSpell::getTargetType() const | ||||
| void CSpell::forEachSchool(const std::function<void(const spells::SchoolInfo &, bool &)>& cb) const | ||||
| { | ||||
| 	bool stop = false; | ||||
| 	for(ESpellSchool iter : SpellConfig::SCHOOL_ORDER) | ||||
| 	for(auto iter : SpellConfig::SCHOOL_ORDER) | ||||
| 	{ | ||||
| 		const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[static_cast<ui8>(iter)]; | ||||
| 		const spells::SchoolInfo & cnf = SpellConfig::SCHOOL[iter]; | ||||
| 		if(school.at(cnf.id)) | ||||
| 		{ | ||||
| 			cb(cnf, stop); | ||||
| @@ -381,15 +381,15 @@ int64_t CSpell::adjustRawDamage(const spells::Caster * caster, const battle::Uni | ||||
| 		//applying protections - when spell has more then one elements, only one protection should be applied (I think) | ||||
| 		forEachSchool([&](const spells::SchoolInfo & cnf, bool & stop) | ||||
| 		{ | ||||
| 			if(bearer->hasBonusOfType(BonusType::SPELL_DAMAGE_REDUCTION, static_cast<ui8>(cnf.id))) | ||||
| 			if(bearer->hasBonusOfType(BonusType::SPELL_DAMAGE_REDUCTION, cnf.id)) | ||||
| 			{ | ||||
| 				ret *= 100 - bearer->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, static_cast<ui8>(cnf.id)); | ||||
| 				ret *= 100 - bearer->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, cnf.id); | ||||
| 				ret /= 100; | ||||
| 				stop = true; //only bonus from one school is used | ||||
| 			} | ||||
| 		}); | ||||
|  | ||||
| 		CSelector selector = Selector::type()(BonusType::SPELL_DAMAGE_REDUCTION).And(Selector::subtype()(-1)); | ||||
| 		CSelector selector = Selector::typeSubtype(BonusType::SPELL_DAMAGE_REDUCTION, SpellSchool(ESpellSchool::ANY)); | ||||
|  | ||||
| 		//general spell dmg reduction, works only on magical effects | ||||
| 		if(bearer->hasBonus(selector) && isMagical()) | ||||
|   | ||||
| @@ -43,13 +43,18 @@ class IBattleCast; | ||||
|  | ||||
| struct SchoolInfo | ||||
| { | ||||
| 	ESpellSchool id; //backlink | ||||
| 	SpellSchool id; //backlink | ||||
| 	BonusType immunityBonus; | ||||
| 	std::string jsonName; | ||||
| }; | ||||
|  | ||||
| } | ||||
|  | ||||
| namespace SpellConfig | ||||
| { | ||||
| 	extern const spells::SchoolInfo SCHOOL[4]; | ||||
| } | ||||
|  | ||||
| enum class VerticalPosition : ui8{TOP, CENTER, BOTTOM}; | ||||
|  | ||||
| class DLL_LINKAGE CSpell : public spells::Spell | ||||
| @@ -185,7 +190,7 @@ public: | ||||
|  | ||||
| 	si32 level; | ||||
|  | ||||
| 	std::map<ESpellSchool, bool> school; | ||||
| 	std::map<SpellSchool, bool> school; | ||||
|  | ||||
| 	si32 power; //spell's power | ||||
|  | ||||
|   | ||||
| @@ -85,11 +85,11 @@ bool Damage::isReceptive(const Mechanics * m, const battle::Unit * unit) const | ||||
| 	if(!UnitEffect::isReceptive(m, unit)) | ||||
| 		return false; | ||||
|  | ||||
| 	bool isImmune = m->getSpell()->isMagical() && (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, -1) >= 100); //General spell damage immunity | ||||
| 	bool isImmune = m->getSpell()->isMagical() && (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, SpellSchool(ESpellSchool::ANY)) >= 100); //General spell damage immunity | ||||
| 	//elemental immunity for damage | ||||
| 	m->getSpell()->forEachSchool([&](const SchoolInfo & cnf, bool & stop) | ||||
| 	{ | ||||
| 		isImmune |= (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, static_cast<ui8>(cnf.id)) >= 100); //100% reduction is immunity | ||||
| 		isImmune |= (unit->getBonusBearer()->valOfBonuses(BonusType::SPELL_DAMAGE_REDUCTION, cnf.id) >= 100); //100% reduction is immunity | ||||
| 	}); | ||||
|  | ||||
| 	return !isImmune; | ||||
|   | ||||
| @@ -56,7 +56,7 @@ TEST_F(AbilityCasterTest, MagicAbilityAffectedByGenericBonus) | ||||
| { | ||||
| 	EXPECT_CALL(spellMock, getLevel()).WillRepeatedly(Return(1)); | ||||
|  | ||||
| 	casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, 0)); | ||||
| 	casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, SpellSchool(ESpellSchool::ANY))); | ||||
|  | ||||
| 	EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1)); | ||||
| 	EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0)); | ||||
| @@ -70,7 +70,7 @@ TEST_F(AbilityCasterTest, MagicAbilityIngoresSchoolBonus) | ||||
| { | ||||
| 	EXPECT_CALL(spellMock, getLevel()).WillRepeatedly(Return(1)); | ||||
|  | ||||
| 	casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, 1)); | ||||
| 	casterBonuses.addNewBonus(std::make_shared<Bonus>(BonusDuration::ONE_BATTLE, BonusType::MAGIC_SCHOOL_SKILL, BonusSource::OTHER, 2, 0, SpellSchool(ESpellSchool::AIR))); | ||||
|  | ||||
| 	EXPECT_CALL(actualCaster, getAllBonuses(_, _, _, _)).Times(AtLeast(1)); | ||||
| 	EXPECT_CALL(actualCaster, getTreeVersion()).Times(AtLeast(0)); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user