mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Basic Configuration for bonus types
* introduced new handler BonusTypeHandler * config\bonusnames.json converted to common format and splitted info main and localizable parts * hanlders initialization refactored
This commit is contained in:
		| @@ -22,13 +22,13 @@ | ||||
| #include "../lib/CArtHandler.h" | ||||
| #include "../lib/NetPacks.h" //ArtifactLocation | ||||
| #include "../lib/CModHandler.h" | ||||
| #include "../lib/IBonusTypeHandler.h" | ||||
|  | ||||
| #include "UIFramework/CGuiHandler.h" | ||||
| #include "UIFramework/CIntObjectClasses.h" | ||||
|  | ||||
| using namespace CSDL_Ext; | ||||
|  | ||||
| class CBonusItem; | ||||
| class CCreatureArtifactInstance; | ||||
| class CSelectableSkill; | ||||
|  | ||||
| @@ -269,24 +269,24 @@ void CCreatureWindow::init(const CStackInstance *Stack, const CBonusSystemNode * | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	int magicResistance = 0; //handle it separately :/ | ||||
|  | ||||
| 	//handle Magic resistance separately :/ | ||||
| 	const IBonusBearer *temp = stack; | ||||
| 	 | ||||
| 	if (battleStack) | ||||
| 	{ | ||||
| 		magicResistance = battleStack->magicResistance(); //include Aura of Resistance | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		magicResistance = stack->magicResistance(); //include Resiatance hero skill | ||||
| 		temp = battleStack; | ||||
| 	} | ||||
|  | ||||
| 	int magicResistance = temp->magicResistance();  | ||||
| 	 | ||||
| 	if (magicResistance) | ||||
| 	{ | ||||
| 		std::map<Bonus::BonusType, std::pair<std::string, std::string> >::const_iterator it = CGI->creh->stackBonuses.find(Bonus::MAGIC_RESISTANCE); | ||||
| 		std::string description; | ||||
| 		text = it->second.first; | ||||
| 		description = it->second.second; | ||||
| 		boost::algorithm::replace_first(description, "%d", boost::lexical_cast<std::string>(magicResistance)); | ||||
| 		Bonus b; | ||||
| 		b.type = Bonus::MAGIC_RESISTANCE; | ||||
| 		 | ||||
| 		text = VLC->getBth()->bonusToString(&b,temp,false); | ||||
| 		const std::string description = VLC->getBth()->bonusToString(&b,temp,true); | ||||
| 		bonusItems.push_back (new CBonusItem(genRect(0, 0, 251, 57), text, description, stack->bonusToGraphics(&b))); | ||||
| 	} | ||||
|  | ||||
|   | ||||
| @@ -117,7 +117,6 @@ public: | ||||
| 	CBonusItem(const Rect &Pos, const std::string &Name, const std::string &Description, const std::string &graphicsName); | ||||
| 	~CBonusItem(); | ||||
|  | ||||
| 	void setBonus (const Bonus &bonus); | ||||
| 	void showAll (SDL_Surface * to); | ||||
| }; | ||||
|  | ||||
|   | ||||
							
								
								
									
										526
									
								
								config/bonuses.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										526
									
								
								config/bonuses.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,526 @@ | ||||
| //TODO: selector-based config | ||||
| // SECONDARY_SKILL_PREMY | ||||
| // school immunities | ||||
| // LEVEL_SPELL_IMMUNITY | ||||
|  | ||||
| { | ||||
| 	"ADDITIONAL_ATTACK": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DOUBLE" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"ADDITIONAL_RETALIATION": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_RETAIL1" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"AIR_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" | ||||
| 		} | ||||
| 	}, | ||||
| 			 | ||||
| 	"ATTACKS_ALL_ADJACENT": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_ROUND" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"BLOCKS_RETALIATION": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_RETAIL" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"CATAPULT": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/Catapult" | ||||
| 		} | ||||
| 	},	 | ||||
| 	 | ||||
| 	"CHANGES_SPELL_COST_FOR_ALLY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_MANA" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"CHANGES_SPELL_COST_FOR_ENEMY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/MagicDamper" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"CHARGE_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/ChargeImmune" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"DAEMON_SUMMONING": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/RiseDemons" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"DARKNESS": | ||||
| 	{ | ||||
| 	},				 | ||||
| 	 | ||||
| 	"DEATH_STARE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DEATH" | ||||
| 		} | ||||
| 	},	 | ||||
| 		 | ||||
| 	"DEFENSIVE_STANCE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DEFBON" | ||||
| 		} | ||||
| 	}, | ||||
| 		 | ||||
| 	"DOUBLE_DAMAGE_CHANCE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DBLOW" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"DRAGON_NATURE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DRAGON" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"DIRECT_DAMAGE_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_SPDIR" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"EARTH_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" | ||||
| 		} | ||||
| 	}, | ||||
| 					 | ||||
| 	"ENCHANTER": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_CAST1" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"ENCHANTED": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_BLESS" | ||||
| 		} | ||||
| 	},		 | ||||
|  | ||||
|  | ||||
|  | ||||
| 	"ENEMY_DEFENCE_REDUCTION": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_RDEF" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"FIRE_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"FIRE_SHIELD": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/FireShield" | ||||
| 		}		 | ||||
| 	}, | ||||
| 	"FEAR": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_FEAR" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"FEARLESS": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_FEARL" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"FLYING": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_FLY" | ||||
| 		} | ||||
|  | ||||
| 	},		 | ||||
|  | ||||
| 	"FREE_SHOOTING": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_SHOOTA" | ||||
| 		} | ||||
|  | ||||
| 	}, | ||||
|  | ||||
| 	"FULL_HP_REGENERATION": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_TROLL" | ||||
| 		} | ||||
| 	}, | ||||
| 			 | ||||
| 	"HATE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_HATE" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"HEALER": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/Healer" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"HP_REGENERATION": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_TROLL" | ||||
| 		} | ||||
| 	}, | ||||
| 	"JOUSTING": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_CHAMP" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"KING1": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_KING1" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"KING2": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_KING2" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"KING3": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_KING3" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"LEVEL_SPELL_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"LIFE_DRAIN": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/DrainLife" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"MANA_CHANNELING": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/ManaChannel" | ||||
| 		} | ||||
| 	}, | ||||
| 	"MANA_DRAIN": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/ManaDrain" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"MAGIC_MIRROR": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/MagicMirror" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"MAGIC_RESISTANCE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DWARF" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"MIND_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_MIND" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"NO_DISTANCE_PENALTY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_DIST" | ||||
| 		} | ||||
| 	}, | ||||
| 	"NO_MELEE_PENALTY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_MELEE" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"NO_MORALE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_MORAL" | ||||
| 		}		 | ||||
| 	},		 | ||||
| 	"NO_WALL_PENALTY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_OBST" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"NON_LIVING": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/NonLiving" | ||||
| 		} | ||||
| 	},	 | ||||
|  | ||||
| 	"RANDOM_SPELLCASTER": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/RandomBoost" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"RECEPTIVE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_NOFRIM" | ||||
| 		} | ||||
| 	}, | ||||
| 	"REBIRTH": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_REBIRTH" | ||||
| 		} | ||||
| 	}, | ||||
| 								 | ||||
| 	"RETURN_AFTER_STRIKE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_HARPY" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"SECONDARY_SKILL_PREMY": | ||||
| 	{ | ||||
| 		"hidden": true | ||||
| 		//todo: selector based config | ||||
| 	}, | ||||
| 	 | ||||
| 	"SELF_LUCK": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"SELF_MORALE": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_MINOT" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"SHOOTER": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_SHOOT" | ||||
| 		} | ||||
| 	},	 | ||||
| 	"SPELLCASTER": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_CASTER" | ||||
| 		} | ||||
| 	}, | ||||
| 					 | ||||
| 	"SPELL_AFTER_ATTACK": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_CAST" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"SPELL_BEFORE_ATTACK": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_CAST2" | ||||
| 		} | ||||
| 	}, | ||||
| 	 | ||||
| 	"SPELL_DAMAGE_REDUCTION": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_GOLEM" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"SPELL_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" //todo: configurable use from spell handler | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	 | ||||
| 	"SPELL_LIKE_ATTACK": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/SpellLikeAttack" | ||||
| 		} | ||||
| 	}, | ||||
| 			 | ||||
| 	"SPELL_RESISTANCE_AURA": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_UNIC" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"TWO_HEX_ATTACK_BREATH": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_BREATH" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
|  | ||||
| 	"THREE_HEADED_ATTACK": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/ThreeHeaded" | ||||
| 		} | ||||
| 	}, | ||||
|  | ||||
| 	"UNDEAD": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_UNDEAD" | ||||
| 		} | ||||
| 	}, | ||||
| 	"UNLIMITED_RETALIATIONS": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "zvs/Lib1.res/E_RETAIL1" | ||||
| 		} | ||||
| 	}, | ||||
| 	"WATER_IMMUNITY": | ||||
| 	{ | ||||
| 		"graphics": | ||||
| 		{ | ||||
| 			"icon":  "" | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
							
								
								
									
										387
									
								
								config/bonuses_texts.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										387
									
								
								config/bonuses_texts.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,387 @@ | ||||
| // macros: | ||||
| // ${val} - value of bonuses; Selector: type,subtype | ||||
| // ${subtype.creature} - creature name  | ||||
| // ${subtype.spell} - spell name | ||||
| // ${MR} - magic resistance of bearer | ||||
|  | ||||
|  | ||||
| { | ||||
| 	"ADDITIONAL_ATTACK": | ||||
| 	{ | ||||
| 		"name": "Double Strike", | ||||
| 		"description": "Attacks twice" | ||||
| 	}, | ||||
| 	 | ||||
| 	"ADDITIONAL_RETALIATION": | ||||
| 	{ | ||||
| 		"name": "Additional retaliations", | ||||
| 		"description": "May Retaliate ${val} extra times" | ||||
| 	}, | ||||
| 	 | ||||
| 	"AIR_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to Air", | ||||
| 		"description": "" | ||||
| 	}, | ||||
| 			 | ||||
| 	"ATTACKS_ALL_ADJACENT": | ||||
| 	{ | ||||
| 		"name": "Attack all around", | ||||
| 		"description": "Attacks all adjacent enemies" | ||||
| 	}, | ||||
|  | ||||
| 	"BLOCKS_RETALIATION": | ||||
| 	{ | ||||
| 		"name": "No retaliation", | ||||
| 		"description": "Enemy cannot Retaliate" | ||||
| 	}, | ||||
| 	 | ||||
| 	"CATAPULT": | ||||
| 	{ | ||||
| 		"name": "Catapult", | ||||
| 		"description": "Attacks siege walls" | ||||
| 	},	 | ||||
| 	 | ||||
| 	"CHANGES_SPELL_COST_FOR_ALLY": | ||||
| 	{ | ||||
| 		"name": "Reduce Casting Cost (${val})", | ||||
| 		"description": "Reduce Casting Cost for hero" | ||||
| 	}, | ||||
| 	 | ||||
| 	"CHANGES_SPELL_COST_FOR_ENEMY": | ||||
| 	{ | ||||
| 		"name": "Magic Damper (${val})", | ||||
| 		"description": "Increase Cost of enemy spells" | ||||
| 	}, | ||||
|  | ||||
| 	"CHARGE_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to Charge", | ||||
| 		"description": "Immune to Champion charge" | ||||
| 	}, | ||||
| 	 | ||||
| 	"DAEMON_SUMMONING": | ||||
| 	{ | ||||
| 		"name": "Summoner (${subtype.creature})", | ||||
| 		"description": "Can rise creatures from corpses"  | ||||
| 	}, | ||||
| 	 | ||||
| 	"DARKNESS":		 | ||||
| 	{ | ||||
| 		"name": "Darness cover", | ||||
| 		"description": "Adds ${val} darkness radius" | ||||
| 	}, | ||||
| 			 | ||||
| 	"DEATH_STARE": | ||||
| 	{ | ||||
| 		"name": "Death Stare (${val}%)", | ||||
| 		"description": "Chance to kill single creature" | ||||
| 	},	 | ||||
| 		 | ||||
| 	"DEFENSIVE_STANCE": | ||||
| 	{ | ||||
| 		"name": "Defense Bonus", | ||||
| 		"description": "+${val} Defense when defending" | ||||
| 	}, | ||||
| 		 | ||||
| 	"DOUBLE_DAMAGE_CHANCE": | ||||
| 	{ | ||||
| 		"name": "Death Blow", | ||||
| 		"description": "${val}% chance for double damage" | ||||
| 	}, | ||||
|  | ||||
| 	"DRAGON_NATURE": | ||||
| 	{ | ||||
| 		"name": "Dragon", | ||||
| 		"description": "Creature has a Dragon Nature" | ||||
| 	}, | ||||
| 	 | ||||
| 	"DIRECT_DAMAGE_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Direct Damage Immunity", | ||||
| 		"description": "Immune to direct damage spells" | ||||
| 	}, | ||||
|  | ||||
| 	"EARTH_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to Earth", | ||||
| 		"description": "" | ||||
| 	}, | ||||
| 					 | ||||
| 	"ENCHANTER": | ||||
| 	{ | ||||
| 		"name": "Enchanter (${subtype.spell})", | ||||
| 		"description": "Casts mass spell every turn" | ||||
| 	}, | ||||
| 	 | ||||
| 	"ENCHANTED": | ||||
| 	{ | ||||
| 		"name": "Enchanted (${subtype.spell})", | ||||
| 		"description": "Affected by permanent spell" | ||||
| 	},		 | ||||
|  | ||||
| 	"ENEMY_DEFENCE_REDUCTION": | ||||
| 	{ | ||||
| 		"name": "Reduce Enemy Defense (${val}%)", | ||||
| 		"description": "Reduces Defense for one attack" | ||||
| 	}, | ||||
| 	 | ||||
| 	"FIRE_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to Fire", | ||||
| 		"description": "" | ||||
| 	}, | ||||
|  | ||||
| 	"FIRE_SHIELD": | ||||
| 	{ | ||||
| 		"name": "Fire Shield (${val}%)", | ||||
| 		"description": "Reflects melee damage"		 | ||||
| 	}, | ||||
| 	"FEAR": | ||||
| 	{ | ||||
| 		"name": "Fear", | ||||
| 		"description": "Causes Fear on an enemy stack" | ||||
| 	}, | ||||
| 	 | ||||
| 	"FEARLESS": | ||||
| 	{ | ||||
| 		"name": "Fearless", | ||||
| 		"description": "Immune to Fear ability" | ||||
| 	}, | ||||
| 	 | ||||
| 	"FLYING": | ||||
| 	{ | ||||
| 		"name": "Fly", | ||||
| 		"description": "Can Fly (ignores obstacles)" | ||||
| 	},		 | ||||
|  | ||||
| 	"FREE_SHOOTING": | ||||
| 	{ | ||||
| 		"name": "Shoot Close", | ||||
| 		"description": "Can shoot in Close Combat" | ||||
| 	}, | ||||
|  | ||||
| 	"FULL_HP_REGENERATION": | ||||
| 	{ | ||||
| 		"name": "Regeneration", | ||||
| 		"description": "May Regenerate full Health" | ||||
| 	}, | ||||
| 			 | ||||
| 	"HATE": | ||||
| 	{ | ||||
| 		"name": "Hates ${subtype.creature}", | ||||
| 		"description": "Does ${val}% more damage" | ||||
| 	}, | ||||
| 	 | ||||
| 	"HEALER": | ||||
| 	{ | ||||
| 		"name": "Healer", | ||||
| 		"description": "Heals allied units" | ||||
| 	}, | ||||
| 	 | ||||
| 	"HP_REGENERATION": | ||||
| 	{ | ||||
| 		"name": "Regeneration", | ||||
| 		"description": "Heals ${val} hit points every round" | ||||
| 	}, | ||||
| 	"JOUSTING": | ||||
| 	{ | ||||
| 		"name": "Champion Charge", | ||||
| 		"description": "+5% damage per hex travelled" | ||||
| 	}, | ||||
| 	 | ||||
| 	"KING1": | ||||
| 	{ | ||||
| 	}, | ||||
| 	 | ||||
| 	"KING2": | ||||
| 	{ | ||||
| 	}, | ||||
| 	 | ||||
| 	"KING3": | ||||
| 	{ | ||||
| 	}, | ||||
| 	 | ||||
| 	"LEVEL_SPELL_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Spell immunity 1-${val}", | ||||
| 		"description": "Immune to spells levels 1-${val}" | ||||
| 	}, | ||||
| 	 | ||||
| 	"LIFE_DRAIN": | ||||
| 	{ | ||||
| 		"name": "Drain life (${val}%)", | ||||
| 		"description": "Drains ${val}% of damage dealt" | ||||
| 	}, | ||||
|  | ||||
| 	"MANA_CHANNELING": | ||||
| 	{ | ||||
| 		"name": "Magic Channel ${val}%", | ||||
| 		"description": "Gives mana spent by enemy" | ||||
| 	}, | ||||
| 	"MANA_DRAIN": | ||||
| 	{ | ||||
| 		"name": "Mana Drain", | ||||
| 		"description": "Drains ${val} mana every turn" | ||||
| 	}, | ||||
|  | ||||
| 	"MAGIC_MIRROR": | ||||
| 	{ | ||||
| 		"name": "Magic Mirror (${val}%)", | ||||
| 		"description": "${val}% chance to redirects offensive spell to enemy" | ||||
| 	}, | ||||
|  | ||||
| 	"MAGIC_RESISTANCE": | ||||
| 	{ | ||||
| 		"name": "Magic Resistance(${MR}%)", | ||||
| 		"description": "${MR}% chance to resist enemy spell" | ||||
| 	}, | ||||
|  | ||||
| 	"MIND_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to mind spells", | ||||
| 		"description": "" | ||||
| 	}, | ||||
|  | ||||
| 	"NO_DISTANCE_PENALTY": | ||||
| 	{ | ||||
| 		"name": "No distance penalty", | ||||
| 		"description": "Full damage from any distance" | ||||
| 	}, | ||||
| 	"NO_MELEE_PENALTY": | ||||
| 	{ | ||||
| 		"name": "No melee penalty", | ||||
| 		"description": "Creature has no Melee Penalty" | ||||
| 	}, | ||||
| 	 | ||||
| 	 | ||||
| 	"NO_MORALE": | ||||
| 	{ | ||||
| 	 | ||||
| 	},	 | ||||
| 		 | ||||
| 	"NO_WALL_PENALTY": | ||||
| 	{ | ||||
| 		"name": "No wall penalty", | ||||
| 		"description": "Full damage during siege" | ||||
| 	}, | ||||
|  | ||||
| 	"NON_LIVING": | ||||
| 	{ | ||||
| 		"name": "Non living", | ||||
| 		"description": "Immunity to many effects" | ||||
| 	},	 | ||||
|  | ||||
| 	"RANDOM_SPELLCASTER": | ||||
| 	{ | ||||
| 		"name": "Random spellcaster", | ||||
| 		"description": "Can cast random spell" | ||||
| 	}, | ||||
|  | ||||
| 	"RECEPTIVE": | ||||
| 	{ | ||||
| 		"name": "Receptive", | ||||
| 		"description": "No Immunity to Friendly Spells" | ||||
| 	}, | ||||
| 	"REBIRTH": | ||||
| 	{ | ||||
| 		"name": "Rebirth (${val}%)", | ||||
| 		"description": "${val}% of stack will rise after death" | ||||
| 	}, | ||||
| 								 | ||||
| 	"RETURN_AFTER_STRIKE": | ||||
| 	{ | ||||
| 		"name": "Attack and Return", | ||||
| 		"description": "Returns after melee attack" | ||||
| 	}, | ||||
| 	 | ||||
| 	"SELF_LUCK": | ||||
| 	{ | ||||
| 		"name": "Positive luck", | ||||
| 		"description": "Always has Positive Luck" | ||||
| 	}, | ||||
| 	 | ||||
| 	"SELF_MORALE": | ||||
| 	{ | ||||
| 		"name": "Positive morale", | ||||
| 		"description": "Always has Positive Morale" | ||||
| 	}, | ||||
| 	 | ||||
| 	"SHOOTER": | ||||
| 	{ | ||||
| 		"name": "Ranged", | ||||
| 		"description": "Creature can shoot" | ||||
| 	},	 | ||||
| 	"SPELLCASTER": | ||||
| 	{ | ||||
| 		"name": "Spellcaster (${subtype.spell})", | ||||
| 		"description": "Can cast spells" | ||||
| 	}, | ||||
| 					 | ||||
| 	"SPELL_AFTER_ATTACK": | ||||
| 	{ | ||||
| 		"name": "Caster - ${subtype.spell}", | ||||
| 		"description": "${val}% chance to cast after attack" | ||||
| 	}, | ||||
| 	 | ||||
| 	"SPELL_BEFORE_ATTACK": | ||||
| 	{ | ||||
| 		"name": "Caster - ${subtype.spell}", | ||||
| 		"description": "${val}% chance to cast before attack" | ||||
| 	}, | ||||
| 	 | ||||
| 	"SPELL_DAMAGE_REDUCTION": | ||||
| 	{ | ||||
| 		"name": "Spell Resistance", | ||||
| 		"description": "Damage from spells reduced ${val}%." | ||||
| 	}, | ||||
|  | ||||
| 	"SPELL_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to ${subtype.spell}", | ||||
| 		"description": "" | ||||
| 	}, | ||||
|  | ||||
| 	 | ||||
| 	"SPELL_LIKE_ATTACK": | ||||
| 	{ | ||||
| 		"name": "Spell-like attack", | ||||
| 		"description": "Attacks with ${subtype.spell}" | ||||
| 	}, | ||||
| 			 | ||||
| 	"SPELL_RESISTANCE_AURA": | ||||
| 	{ | ||||
| 		"name": "Aura of Resistance", | ||||
| 		"description": "Nearby stacks get ${val}% resistance" | ||||
| 	}, | ||||
|  | ||||
| 	"TWO_HEX_ATTACK_BREATH": | ||||
| 	{ | ||||
| 		"name": "Breath", | ||||
| 		"description": "Breath Attack (2-hex range)" | ||||
| 	}, | ||||
|  | ||||
|  | ||||
|  | ||||
| 	"THREE_HEADED_ATTACK": | ||||
| 	{ | ||||
| 		"name": "Three-headed attack", | ||||
| 		"description": "Attacks three adjacent units" | ||||
| 	}, | ||||
|  | ||||
| 	"UNDEAD": | ||||
| 	{ | ||||
| 		"name": "Undead", | ||||
| 		"description": "Creature is Undead" | ||||
| 	}, | ||||
| 	"UNLIMITED_RETALIATIONS": | ||||
| 	{ | ||||
| 		"name": "Unlimited retaliations", | ||||
| 		"description": "Retaliate any number of attacks" | ||||
| 	}, | ||||
| 	"WATER_IMMUNITY": | ||||
| 	{ | ||||
| 		"name": "Immune to Water", | ||||
| 		"description": "" | ||||
| 	} | ||||
| } | ||||
| @@ -1,66 +0,0 @@ | ||||
| { | ||||
| 	"bonuses": | ||||
| 		[ | ||||
| 			{ "id": "ADDITIONAL_RETALIATION", "name": "Additional retaliations", "description": "May Retaliate %d extra times" }, | ||||
| 			{ "id": "ATTACKS_ALL_ADJACENT", "name": "Attack all around", "description": "Attacks all adjacent enemies" }, | ||||
| 			{ "id": "RETURN_AFTER_STRIKE", "name": "Attack and Return", "description": "Returns after melee attack" }, | ||||
| 			{ "id": "SPELL_RESISTANCE_AURA", "name": "Aura of Resistance", "description": "Nearby stacks get %d% resistance" }, | ||||
| 			{ "id": "TWO_HEX_ATTACK_BREATH", "name": "Breath", "description": "Breath Attack (2-hex range)" }, | ||||
| 			{ "id": "SPELL_AFTER_ATTACK", "name": "Caster - %s", "description": "%d% chance to cast after attack" }, | ||||
| 			{ "id": "SPELL_BEFORE_ATTACK", "name": "Caster - %s", "description": "%d% chance to cast before attack" }, | ||||
| 			{ "id": "SPELL_LIKE_ATTACK", "name": "Spell-like attack", "description": "Attacks with %s" }, | ||||
| 			{ "id": "CATAPULT", "name": "Catapult", "description": "Attacks siege walls" }, | ||||
| 			{ "id": "JOUSTING", "name": "Champion Charge", "description": "+5% damage per hex travelled" }, | ||||
| 			{ "id": "DOUBLE_DAMAGE_CHANCE", "name": "Death Blow", "description": "%d% chance for double damage" }, | ||||
| 			{ "id": "DEFENSIVE_STANCE", "name": "Defense Bonus", "description": "+%d Defense when defending" }, | ||||
| 			{ "id": "ADDITIONAL_ATTACK", "name": "Double Strike", "description": "Attacks twice" }, | ||||
| 			{ "id": "DRAGON_NATURE", "name": "Dragon", "description": "Creature has a Dragon Nature" }, | ||||
| 			{ "id": "LIFE_DRAIN", "name": "Drain life (%d%)", "description": "Drains life equal to damage dealt" }, | ||||
| 			{ "id": "FEAR", "name": "Fear", "description": "Causes Fear on an enemy stack" }, | ||||
| 			{ "id": "FEARLESS", "name": "Fearless", "description": "Immune to Fear ability" }, | ||||
| 			{ "id": "FLYING", "name": "Fly", "description": "Can Fly (ignores obstacles)" }, | ||||
| 			{ "id": "HATE", "name": "Hates %s", "description": "Does %d% more damage" }, | ||||
| 			{ "id": "HEALER", "name": "Healer", "description": "Heals allied units" }, | ||||
| 			{ "id": "SPELL_IMMUNITY", "name": "Immune to %s", "description": "" }, | ||||
| 			{ "id": "CHARGE_IMMUNITY", "name": "Immune to Charge", "description": "Immune to Champion charge" }, | ||||
| 			{ "id": "MANA_CHANNELING", "name": "Magic Channel %d%", "description": "Gives mana spent by enemy" }, | ||||
| 			{ "id": "MANA_DRAIN", "name": "Mana Drain", "description": "Drains %d mana every turn" }, | ||||
| 			{ "id": "CHANGES_SPELL_COST_FOR_ENEMY", "name": "Magic Damper (%d)", "description": "Increase Cost of enemy spells" }, | ||||
| 			{ "id": "MAGIC_MIRROR", "name": "Magic Mirror (%d%)", "description": "Redirects offensive spell to enemy" }, | ||||
| 			{ "id": "MAGIC_RESISTANCE", "name": "Magic Resistance", "description": "%d% chance to resist enemy spell" }, | ||||
| 			{ "id": "NO_DISTANCE_PENALTY", "name": "No distance penalty", "description": "Full damage from any distance" }, | ||||
| 			{ "id": "NO_MELEE_PENALTY", "name": "No melee penalty", "description": "Creature has no Melee Penalty" }, | ||||
| 			{ "id": "NO_WALL_PENALTY", "name": "No wall penalty", "description": "Full damage during siege" }, | ||||
| 			{ "id": "BLOCKS_RETALIATION", "name": "No retaliation", "description": "Enemy cannot Retaliate" }, | ||||
| 			{ "id": "NON_LIVING", "name": "Non living", "description": "Immunity to many effects" }, | ||||
| 			{ "id": "SELF_LUCK", "name": "Positive luck", "description": "Always has Positive Luck" }, | ||||
| 			{ "id": "SELF_MORALE", "name": "Positive morale", "description": "Always has Positive Morale" }, | ||||
| 			{ "id": "SHOOTER", "name": "Ranged", "description": "Creature can shoot" }, | ||||
| 			{ "id": "CHANGES_SPELL_COST_FOR_ALLY", "name": "Reduce Casting Cost (%d)", "description": "Reduce Casting Cost for hero" }, | ||||
| 			{ "id": "ENEMY_DEFENCE_REDUCTION", "name": "Reduce Enemy Defense (%d%)", "description": "Reduces Defense for one attack" }, | ||||
| 			{ "id": "FULL_HP_REGENERATION", "name": "Regeneration", "description": "May Regenerate full Health" }, | ||||
| 			{ "id": "HP_REGENERATION", "name": "Regeneration", "description": "Heals %d hit points every round" }, | ||||
| 			{ "id": "FREE_SHOOTING", "name": "Shoot Close", "description": "Can shoot in Close Combat" }, | ||||
| 			{ "id": "LEVEL_SPELL_IMMUNITY", "name": "Spell immunity 1-%d", "description": "Immune to spells levels 1-%d" }, | ||||
| 			{ "id": "SPELL_DAMAGE_REDUCTION", "name": "Spell Resistance", "description": "Damage from spells reduced %d%." }, | ||||
| 			{ "id": "THREE_HEADED_ATTACK", "name": "Three-headed attack", "description": "Attacks three adjacent units" }, | ||||
| 			{ "id": "UNDEAD", "name": "Undead", "description": "Creature is Undead" }, | ||||
| 			{ "id": "UNLIMITED_RETALIATIONS", "name": "Unlimited retaliations", "description": "Retaliate any number of attacks" }, | ||||
| 			{ "id": "DEATH_STARE", "name": "Death Stare (%d%)", "description": "Chance to kill single creature" }, | ||||
| 			{ "id": "FIRE_IMMUNITY", "name": "Immune to Fire", "description": "" }, | ||||
| 			{ "id": "WATER_IMMUNITY", "name": "Immune to Water", "description": "" }, | ||||
| 			{ "id": "AIR_IMMUNITY", "name": "Immune to Air", "description": "" }, | ||||
| 			{ "id": "EARTH_IMMUNITY", "name": "Immune to Earth", "description": "" }, | ||||
| 			{ "id": "MIND_IMMUNITY", "name": "Immune to mind spells", "description": "" }, | ||||
| 			{ "id": "DIRECT_DAMAGE_IMMUNITY", "name": "Direct Damage Immunity", "description": "Immune to direct damage spells" }, | ||||
| 			{ "id": "RECEPTIVE", "name": "Receptive", "description": "No Immunity to Friendly Spells" }, | ||||
| 			{ "id": "REBIRTH", "name": "Rebirth (%d%)", "description": "Stack will rise after death" }, | ||||
| 			{ "id": "SPELLCASTER", "name": "Spellcaster (%s)", "description": "Can cast spells" }, | ||||
| 			{ "id": "ENCHANTER", "name": "Enchanter (%s)", "description": "Casts mass spell every turn" }, | ||||
| 			{ "id": "ENCHANTED", "name": "Enchanted (%s)", "description": "Affected by permanent spell" }, | ||||
| 			{ "id": "FIRE_SHIELD", "name": "Fire Shield (%d%)", "description": "Reflects melee damage" }, | ||||
| 			{ "id": "MAGIC_MIRROR", "name": "Magic Mirror (%d%)", "description": "Chance to reflect hostile spell" }, | ||||
| 			{ "id": "RANDOM_SPELLCASTER", "name": "Random spellcaster", "description": "Can cast random spell" }, | ||||
| 			{ "id": "DAEMON_SUMMONING", "name": "Summoner (%s)", "description": "Can rise creatures from corpses" } | ||||
| 		] | ||||
| } | ||||
| @@ -45,4 +45,10 @@ | ||||
| 		"config/heroes/conflux.json", | ||||
| 		"config/heroes/special.json" | ||||
| 	], | ||||
| 	 | ||||
| 	"bonuses" : | ||||
| 	[ | ||||
| 		"config/bonuses.json", | ||||
| 		"config/bonuses_texts.json" | ||||
| 	] | ||||
| } | ||||
|   | ||||
| @@ -79,8 +79,6 @@ struct DLL_LINKAGE BattleInfo : public CBonusSystemNode, public CBattleInfoCallb | ||||
| 	BattleInfo(); | ||||
| 	~BattleInfo(){}; | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| 	//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| 	CStack * getStackT(BattleHex tileID, bool onlyAlive = true); | ||||
| 	CStack * getStack(int stackID, bool onlyAlive = true); | ||||
|   | ||||
| @@ -161,7 +161,7 @@ CArtHandler::~CArtHandler() | ||||
| { | ||||
| } | ||||
|  | ||||
| void CArtHandler::loadArtifacts(bool onlyTxt) | ||||
| void CArtHandler::load(bool onlyTxt) | ||||
| { | ||||
| 	if (onlyTxt) | ||||
| 		return; // looks to be broken anyway... | ||||
|   | ||||
| @@ -59,8 +59,8 @@ public: | ||||
| 	bool isBig () const; | ||||
|  | ||||
| 	int getArtClassSerial() const; //0 - treasure, 1 - minor, 2 - major, 3 - relic, 4 - spell scroll, 5 - other | ||||
| 	std::string nodeName() const override; | ||||
| 	void addNewBonus(Bonus *b) override; | ||||
| 	std::string nodeName() const OVERRIDE; | ||||
| 	void addNewBonus(Bonus *b) OVERRIDE; | ||||
|  | ||||
| 	virtual void levelUpArtifact (CArtifactInstance * art){}; | ||||
|  | ||||
| @@ -198,7 +198,7 @@ public: | ||||
| 	std::set<ArtifactID> bigArtifacts; // Artifacts that cannot be moved to backpack, e.g. war machines. | ||||
| 	std::set<ArtifactID> growingArtifacts; | ||||
|  | ||||
| 	void loadArtifacts(bool onlyTxt); | ||||
| 	void load(bool onlyTxt = false); | ||||
| 	/// load artifact from json structure | ||||
| 	void load(std::string objectID, const JsonNode & node); | ||||
| 	/// load one artifact from json config | ||||
|   | ||||
							
								
								
									
										337
									
								
								lib/CBonusTypeHandler.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										337
									
								
								lib/CBonusTypeHandler.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,337 @@ | ||||
| /* | ||||
|  * CBonusTypeHandler.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" | ||||
| #include "CBonusTypeHandler.h" | ||||
|  | ||||
| #include "JsonNode.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
| #include "Filesystem/ISimpleResourceLoader.h" | ||||
|  | ||||
|  | ||||
| #include "VCMI_Lib.h" | ||||
| #include "CCreatureHandler.h" | ||||
| #include "CSpellHandler.h" | ||||
|  | ||||
| ///Helpers | ||||
|  | ||||
| static inline void jsonSetString(const JsonNode& source, const std::string& name, std::string& dest) | ||||
| { | ||||
| 	const JsonNode& val = source[name]; | ||||
| 	if(!val.isNull()) | ||||
| 	{ | ||||
| 		dest = val.String(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static inline void jsonSetBool(const JsonNode& source, const std::string& name, bool& dest) | ||||
| { | ||||
| 	const JsonNode& val = source[name]; | ||||
| 	if(!val.isNull()) | ||||
| 	{ | ||||
| 		dest = val.Bool(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| ///MacroString | ||||
|  | ||||
| MacroString::MacroString(const std::string &format) | ||||
| { | ||||
| 	static const std::string MACRO_START = "${"; | ||||
| 	static const std::string MACRO_END = "}"; | ||||
| 	static const size_t MACRO_START_L = 2; | ||||
| 	static const size_t MACRO_END_L = 1; | ||||
| 	 | ||||
| 	size_t end_pos = 0;	 | ||||
| 	size_t start_pos = std::string::npos; | ||||
| 	 | ||||
| 	tlog5 << "Parsing format " << format << std::endl; | ||||
| 	 | ||||
| 	do | ||||
| 	{ | ||||
| 		start_pos = format.find(MACRO_START, end_pos); | ||||
| 		 | ||||
| 		if (!(start_pos == std::string::npos)) | ||||
| 		{ | ||||
| 			//chunk before macro | ||||
| 			items.push_back(Item(Item::STRING,format.substr(end_pos, start_pos-end_pos))); | ||||
| 			 | ||||
| 			start_pos += MACRO_START_L; | ||||
| 			end_pos = format.find(MACRO_END, start_pos); | ||||
| 			 | ||||
| 			if (end_pos == std::string::npos) | ||||
| 			{ | ||||
| 				tlog2 << "Format error in: " << format <<std::endl; | ||||
| 				end_pos = start_pos; | ||||
| 				break; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				items.push_back(Item(Item::MACRO,format.substr(start_pos,end_pos-start_pos))); | ||||
| 				end_pos += MACRO_END_L; | ||||
| 			} | ||||
| 		}		 | ||||
| 	} | ||||
| 	while (!start_pos == std::string::npos); | ||||
| 	 | ||||
| 	//no more macros | ||||
| 	items.push_back(Item(Item::STRING,format.substr(end_pos))); | ||||
|  | ||||
| 	 | ||||
| } | ||||
|  | ||||
| std::string MacroString::build(const GetValue& getValue) const | ||||
| { | ||||
| 	std::string result; | ||||
| 	 | ||||
| 	BOOST_FOREACH(const Item &i, items) | ||||
| 	{ | ||||
| 		switch (i.type) | ||||
| 		{ | ||||
| 			case Item::MACRO: | ||||
| 			{ | ||||
| 				result += getValue(i.value); | ||||
| 				break; | ||||
| 			}			 | ||||
| 			case Item::STRING: | ||||
| 			{ | ||||
| 				result += i.value; | ||||
| 				break; | ||||
| 			}			 | ||||
| 		}		 | ||||
| 	} | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| ///CBonusType | ||||
|  | ||||
| CBonusType::CBonusType() | ||||
| { | ||||
| 	hidden = true; | ||||
| 	icon = nameTemplate = descriptionTemplate = "";  | ||||
| } | ||||
|  | ||||
| CBonusType::~CBonusType() | ||||
| { | ||||
| 	 | ||||
| } | ||||
|  | ||||
| void CBonusType::buildMacros() | ||||
| { | ||||
| 	name = MacroString(nameTemplate); | ||||
| 	description = MacroString(descriptionTemplate); | ||||
| } | ||||
|  | ||||
|  | ||||
| ///CBonusTypeHandler | ||||
|  | ||||
| CBonusTypeHandler::CBonusTypeHandler() | ||||
| { | ||||
| 	//register predefined bonus types | ||||
|  | ||||
| 	#define BONUS_NAME(x) \ | ||||
| 		do{\ | ||||
| 			bonusTypes.push_back(CBonusType());\ | ||||
| 		}while (0); | ||||
| 		 | ||||
| 	 | ||||
| 	BONUS_LIST; | ||||
| 	#undef BONUS_NAME | ||||
| } | ||||
|  | ||||
| CBonusTypeHandler::~CBonusTypeHandler() | ||||
| { | ||||
| 	//dtor | ||||
| } | ||||
|  | ||||
| std::string CBonusTypeHandler::bonusToString(Bonus *bonus, const IBonusBearer *bearer, bool description) const | ||||
| { | ||||
| 	auto getValue = [=](const std::string &name) -> std::string | ||||
| 	{ | ||||
| 		if (name == "val") | ||||
| 		{ | ||||
| 			return boost::lexical_cast<std::string>(bearer->valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype))); | ||||
| 		} | ||||
| 		else if (name == "subtype.creature") | ||||
| 		{ | ||||
| 			return VLC->creh->creatures[bonus->subtype]->namePl; | ||||
| 		} | ||||
| 		else if (name == "subtype.spell") | ||||
| 		{ | ||||
| 			 return VLC->spellh->spells[bonus->subtype]->name; | ||||
| 		}		 | ||||
| 		else if (name == "MR") | ||||
| 		{ | ||||
| 			 return boost::lexical_cast<std::string>(bearer->magicResistance()); | ||||
| 		}			 | ||||
| 		else | ||||
| 		{ | ||||
| 			tlog2 << "Unknown macro in bonus config: " << name << std::endl; | ||||
| 			return "[error]"; | ||||
| 		} | ||||
| 	}; | ||||
| 	 | ||||
| 	const CBonusType& bt = bonusTypes[bonus->type]; | ||||
| 	 | ||||
| 	std::string text; | ||||
| 	 | ||||
| 	if (description) | ||||
| 	{ | ||||
| 		text = bt.description.build(getValue); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		text = bt.name.build(getValue); | ||||
| 	} | ||||
| 	 | ||||
| 	return text;	 | ||||
| } | ||||
|  | ||||
| std::string CBonusTypeHandler::bonusToGraphics(Bonus* bonus) const | ||||
| { | ||||
| 	std::string fileName; | ||||
| 	bool fullPath = false; | ||||
|  | ||||
| 	switch (bonus->type) | ||||
| 	{ | ||||
| 		case Bonus::SECONDARY_SKILL_PREMY: | ||||
| 			if (bonus->subtype == SecondarySkill::RESISTANCE) | ||||
| 			{ | ||||
| 				fileName = "E_DWARF.bmp"; | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::SPELL_IMMUNITY: | ||||
| 		{ | ||||
| 			fullPath = true; | ||||
| 			const CSpell * sp = SpellID(bonus->subtype).toSpell(); | ||||
| 			fileName = sp->getIconImmune(); | ||||
| 			break; | ||||
| 		} | ||||
| 		case Bonus::FIRE_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPFIRE.bmp"; break; //all | ||||
| 				case 1: | ||||
| 					fileName =  "E_SPFIRE1.bmp"; break; //not positive | ||||
| 				case 2: | ||||
| 					fileName =  "E_FIRE.bmp"; break; //direct damage | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::WATER_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPWATER.bmp"; break; //all | ||||
| 				case 1: | ||||
| 					fileName =  "E_SPWATER1.bmp"; break; //not positive | ||||
| 				case 2: | ||||
| 					fileName =  "E_SPCOLD.bmp"; break; //direct damage | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::AIR_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPAIR.bmp"; break; //all | ||||
| 				case 1: | ||||
| 					fileName =  "E_SPAIR1.bmp"; break; //not positive | ||||
| 				case 2: | ||||
| 					fileName = "E_LIGHT.bmp"; break;//direct damage | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::EARTH_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPEATH.bmp"; break; //all | ||||
| 				case 1: | ||||
| 				case 2: //no specific icon for direct damage immunity | ||||
| 					fileName =  "E_SPEATH1.bmp"; break; //not positive | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::LEVEL_SPELL_IMMUNITY: | ||||
| 		{ | ||||
| 			if (vstd::iswithin(bonus->val, 1 , 5)) | ||||
| 			{ | ||||
| 				fileName = "E_SPLVL" + boost::lexical_cast<std::string>(bonus->val) + ".bmp"; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 		 | ||||
| 		default:  | ||||
| 		{ | ||||
|  | ||||
| 			const CBonusType& bt = bonusTypes[bonus->type]; | ||||
| 			 | ||||
| 			fileName = bt.icon; | ||||
| 			fullPath = true; | ||||
| 			break; | ||||
| 		}		 | ||||
| 	} | ||||
| 	 | ||||
| 	if(!fileName.empty() && !fullPath) | ||||
| 		fileName = "zvs/Lib1.res/" + fileName; | ||||
| 	return fileName;	 | ||||
| } | ||||
|  | ||||
|  | ||||
| void CBonusTypeHandler::load() | ||||
| { | ||||
| 	const JsonNode gameConf(ResourceID("config/gameConfig.json")); | ||||
| 	const JsonNode config(JsonUtils::assembleFromFiles(gameConf["bonuses"].convertTo<std::vector<std::string> >())); | ||||
| 	 | ||||
| 	load(config); | ||||
| } | ||||
|  | ||||
| void CBonusTypeHandler::load(const JsonNode& config) | ||||
| { | ||||
| 	BOOST_FOREACH(auto & node, config.Struct()) | ||||
| 	{ | ||||
| 		auto it = bonusNameMap.find(node.first); | ||||
| 		 | ||||
| 		if(it == bonusNameMap.end()) | ||||
| 		{ | ||||
| 			//TODO: new bonus | ||||
| 			CBonusType bt; | ||||
| 			loadItem(node.second, bt); | ||||
| 			 | ||||
| 			auto new_id = bonusTypes.size(); | ||||
| 			 | ||||
| 			bonusTypes.push_back(bt); | ||||
| 			 | ||||
| 			tlog2 << "Adding new bonuses not implemented (" << node.first << ")" << std::endl; | ||||
| 		} | ||||
| 		else | ||||
| 		{ | ||||
| 			CBonusType& bt = bonusTypes[it->second]; | ||||
| 			 | ||||
| 			loadItem(node.second, bt); | ||||
| 			tlog5 << "Loaded bonus type " << node.first << std::endl; | ||||
| 		}	 | ||||
| 	}		 | ||||
| } | ||||
|  | ||||
| void CBonusTypeHandler::loadItem(const JsonNode& source, CBonusType& dest) | ||||
| { | ||||
| 	dest.hidden = false; | ||||
| 	jsonSetString(source,"name", dest.nameTemplate); | ||||
| 	jsonSetString(source,"description", dest.descriptionTemplate); | ||||
| 	 | ||||
| 	jsonSetBool(source,"hidden", dest.hidden); | ||||
| 	 | ||||
| 	const JsonNode& graphics = source["graphics"]; | ||||
| 	 | ||||
| 	if(!graphics.isNull()) | ||||
| 	{ | ||||
| 		jsonSetString(graphics,"icon", dest.icon); | ||||
| 	}	 | ||||
| 	dest.buildMacros(); | ||||
| } | ||||
|  | ||||
							
								
								
									
										93
									
								
								lib/CBonusTypeHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										93
									
								
								lib/CBonusTypeHandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,93 @@ | ||||
| /* | ||||
|  * CBonusTypeHandler.h, 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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #pragma once  | ||||
|  | ||||
| #include "IBonusTypeHandler.h" | ||||
| #include "HeroBonus.h" | ||||
|  | ||||
|  | ||||
| class JsonNode; | ||||
|  | ||||
| typedef Bonus::BonusType BonusTypeID; | ||||
|  | ||||
| class MacroString | ||||
| { | ||||
| 	struct Item | ||||
| 	{ | ||||
| 		enum ItemType | ||||
| 		{ | ||||
| 			STRING, MACRO | ||||
| 		}; | ||||
| 		Item(ItemType _type, std::string _value): type(_type), value(_value){}; | ||||
| 		ItemType type; | ||||
| 		std::string value; //consant string or macro name | ||||
| 	}; | ||||
| 	std::vector<Item> items; | ||||
| public: | ||||
| 	typedef std::function <std::string(const std::string&)> GetValue; | ||||
| 	 | ||||
| 	MacroString(){}; | ||||
| 	MacroString(const std::string &format); | ||||
| 	 | ||||
| 	std::string build(const GetValue& getValue) const; | ||||
| }; | ||||
|  | ||||
| class DLL_LINKAGE CBonusType | ||||
| { | ||||
| public: | ||||
| 	CBonusType(); | ||||
| 	~CBonusType(); | ||||
| 	 | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & icon & nameTemplate & descriptionTemplate & hidden; | ||||
| 		 | ||||
| 		if (!h.saving) | ||||
| 			buildMacros(); | ||||
| 	} | ||||
| protected: | ||||
| 	 | ||||
| private: | ||||
| 	void buildMacros(); | ||||
| 	MacroString name, description; | ||||
| 	 | ||||
| 	friend class CBonusTypeHandler; | ||||
| 	std::string icon; | ||||
| 	std::string nameTemplate, descriptionTemplate; | ||||
| 	 | ||||
| 	bool hidden; | ||||
| }; | ||||
|  | ||||
|   | ||||
| class DLL_LINKAGE CBonusTypeHandler : public IBonusTypeHandler | ||||
| { | ||||
| public: | ||||
| 	CBonusTypeHandler(); | ||||
| 	virtual ~CBonusTypeHandler(); | ||||
| 	 | ||||
| 	std::string bonusToString(Bonus *bonus, const IBonusBearer *bearer, bool description) const override; | ||||
| 	std::string bonusToGraphics(Bonus *bonus) const override; | ||||
| 	 | ||||
| 	void load(); | ||||
| 	void load(const JsonNode& config); | ||||
| 	 | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & bonusTypes; | ||||
| 	} | ||||
| private: | ||||
| 	 | ||||
| 	void loadItem(const JsonNode &source, CBonusType &dest); | ||||
| 	 | ||||
| 	std::vector<CBonusType> bonusTypes; //index = BonusTypeID  | ||||
|  | ||||
| }; | ||||
| @@ -127,10 +127,7 @@ void CCreature::addBonus(int val, Bonus::BonusType type, int subtype /*= -1*/) | ||||
| 	Bonus *added = new Bonus(Bonus::PERMANENT, type, Bonus::CREATURE_ABILITY, val, idNumber, subtype, Bonus::BASE_NUMBER); | ||||
| 	addNewBonus(added); | ||||
| } | ||||
| // void CCreature::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const | ||||
| // { | ||||
| // 	out.insert (VLC->creh->globalEffects); | ||||
| // } | ||||
|  | ||||
| bool CCreature::isMyUpgrade(const CCreature *anotherCre) const | ||||
| { | ||||
| 	//TODO upgrade of upgrade? | ||||
| @@ -251,7 +248,8 @@ void CCreatureHandler::loadBonuses(CCreature & ncre, std::string bonuses) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CCreatureHandler::loadCreatures() | ||||
|  | ||||
| void CCreatureHandler::load() | ||||
| { | ||||
| 	tlog5 << "\t\tReading ZCRTRAIT.TXT" << std::endl; | ||||
|  | ||||
| @@ -373,24 +371,6 @@ void CCreatureHandler::loadCreatures() | ||||
|  | ||||
| 	loadAnimationInfo(); | ||||
|  | ||||
| 	//reading creature ability names | ||||
| 	const JsonNode config2(ResourceID("config/bonusnames.json")); | ||||
|  | ||||
| 	BOOST_FOREACH(const JsonNode &bonus, config2["bonuses"].Vector()) | ||||
| 	{ | ||||
| 		const std::string bonusID = bonus["id"].String(); | ||||
|  | ||||
| 		auto it_map = bonusNameMap.find(bonusID); | ||||
| 		if (it_map != bonusNameMap.end()) | ||||
| 			stackBonuses[it_map->second] = std::pair<std::string, std::string>(bonus["name"].String(), bonus["description"].String()); | ||||
| 		else | ||||
| 			tlog2 << "Bonus " << bonusID << " not recognized, ignoring\n"; | ||||
| 	} | ||||
|  | ||||
| 	//handle magic resistance secondary skill premy, potentialy may be buggy | ||||
| 	//std::map<Bonus::BonusType, std::pair<std::string, std::string> >::iterator it = stackBonuses.find(Bonus::MAGIC_RESISTANCE); | ||||
| 	//stackBonuses[Bonus::SECONDARY_SKILL_PREMY] = std::pair<std::string, std::string>(it->second.first, it->second.second); | ||||
|  | ||||
| 	if (VLC->modh->modules.STACK_EXP) 	//reading default stack experience bonuses | ||||
| 	{ | ||||
| 		CLegacyConfigParser parser("DATA/CREXPBON.TXT"); | ||||
|   | ||||
| @@ -106,7 +106,6 @@ public: | ||||
|  | ||||
| 	void addBonus(int val, Bonus::BonusType type, int subtype = -1); | ||||
| 	std::string nodeName() const override; | ||||
| 	//void getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const; | ||||
|  | ||||
| 	template<typename RanGen> | ||||
| 	int getRandomAmount(RanGen ranGen) const | ||||
| @@ -148,7 +147,6 @@ public: | ||||
| 	std::vector<ConstTransitivePtr<CCreature> > creatures; //creature ID -> creature info. | ||||
|  | ||||
| 	//stack exp | ||||
| 	std::map<Bonus::BonusType, std::pair<std::string, std::string> > stackBonuses; // bonus => name, description | ||||
| 	std::vector<std::vector<ui32> > expRanks; // stack experience needed for certain rank, index 0 for other tiers (?) | ||||
| 	std::vector<ui32> maxExpPerBattle; //%, tiers same as above | ||||
| 	si8 expAfterUpgrade;//multiplier in % | ||||
| @@ -163,7 +161,7 @@ public: | ||||
| 	/// adding abilities from ZCRTRAIT.TXT | ||||
| 	void loadBonuses(CCreature & creature, std::string bonuses); | ||||
| 	/// load all creatures from H3 files | ||||
| 	void loadCreatures(); | ||||
| 	void load(); | ||||
| 	/// load creature from json structure | ||||
| 	void load(std::string creatureID, const JsonNode & node); | ||||
| 	/// load one creature from json config | ||||
| @@ -191,7 +189,7 @@ public: | ||||
| 	{ | ||||
| 		//TODO: should be optimized, not all these informations needs to be serialized (same for ccreature) | ||||
| 		h & doubledCreatures & creatures; | ||||
| 		h & stackBonuses & expRanks & maxExpPerBattle & expAfterUpgrade; | ||||
| 		h & expRanks & maxExpPerBattle & expAfterUpgrade; | ||||
| 		h & skillLevels & skillRequirements & commanderLevelPremy; | ||||
| 		h & allCreatures; | ||||
| 		h & creaturesOfLevel; | ||||
|   | ||||
| @@ -10,6 +10,7 @@ | ||||
| #include "CGeneralTextHandler.h" | ||||
| #include "CSpellHandler.h" | ||||
| #include "CHeroHandler.h" | ||||
| #include "IBonusTypeHandler.h" | ||||
|  | ||||
| /* | ||||
|  * CCreatureSet.cpp, part of VCMI engine | ||||
| @@ -561,341 +562,20 @@ void CStackInstance::setType(const CCreature *c) | ||||
| } | ||||
| std::string CStackInstance::bonusToString(Bonus *bonus, bool description) const | ||||
| { | ||||
| 	std::map<Bonus::BonusType, std::pair<std::string, std::string> >::iterator it = VLC->creh->stackBonuses.find(bonus->type); | ||||
| 	if (it != VLC->creh->stackBonuses.end()) | ||||
| 	if(Bonus::MAGIC_RESISTANCE == bonus->type) | ||||
| 	{ | ||||
| 		std::string text; | ||||
| 		if (description) //long ability description | ||||
| 		{ | ||||
| 			text = it->second.second; | ||||
| 			switch (bonus->type) | ||||
| 			{ | ||||
| 				//no additional modifiers needed | ||||
| 				case Bonus::FLYING: | ||||
| 				case Bonus::UNLIMITED_RETALIATIONS: | ||||
| 				case Bonus::SHOOTER: | ||||
| 				case Bonus::FREE_SHOOTING: | ||||
| 				case Bonus::NO_MELEE_PENALTY: | ||||
| 				case Bonus::NO_DISTANCE_PENALTY: | ||||
| 				case Bonus::NO_WALL_PENALTY: | ||||
| 				case Bonus::JOUSTING: //TODO: percent bonus? | ||||
| 				case Bonus::RETURN_AFTER_STRIKE: | ||||
| 				case Bonus::BLOCKS_RETALIATION: | ||||
| 				case Bonus::TWO_HEX_ATTACK_BREATH: | ||||
| 				case Bonus::THREE_HEADED_ATTACK: | ||||
| 				case Bonus::ATTACKS_ALL_ADJACENT: | ||||
| 				case Bonus::ADDITIONAL_ATTACK: //TODO: what with more than one attack? Axe of Ferocity for example | ||||
| 				case Bonus::FULL_HP_REGENERATION: | ||||
| 				case Bonus::MANA_DRAIN: | ||||
| 				case Bonus::LIFE_DRAIN: | ||||
| 				case Bonus::REBIRTH: | ||||
| 				case Bonus::SELF_MORALE: | ||||
| 				case Bonus::SELF_LUCK: | ||||
| 				case Bonus::FEAR: | ||||
| 				case Bonus::FEARLESS: | ||||
| 				case Bonus::CHARGE_IMMUNITY: | ||||
| 				case Bonus::HEALER: | ||||
| 				case Bonus::CATAPULT: | ||||
| 				case Bonus::DRAGON_NATURE: | ||||
| 				case Bonus::NON_LIVING: | ||||
| 				case Bonus::UNDEAD: | ||||
| 				case Bonus::FIRE_IMMUNITY: | ||||
| 				case Bonus::WATER_IMMUNITY: | ||||
| 				case Bonus::AIR_IMMUNITY: | ||||
| 				case Bonus::EARTH_IMMUNITY: | ||||
| 				case Bonus::RECEPTIVE: | ||||
| 				case Bonus::DIRECT_DAMAGE_IMMUNITY: | ||||
| 				break; | ||||
| 				//One numeric value. magic resistance handled separately | ||||
| 				case Bonus::SPELL_RESISTANCE_AURA: | ||||
| 				case Bonus::SPELL_DAMAGE_REDUCTION: | ||||
| 				case Bonus::LEVEL_SPELL_IMMUNITY: | ||||
| 				case Bonus::HP_REGENERATION: | ||||
| 				case Bonus::ADDITIONAL_RETALIATION: | ||||
| 				case Bonus::DEFENSIVE_STANCE: | ||||
| 				case Bonus::DOUBLE_DAMAGE_CHANCE: | ||||
| 				case Bonus::DARKNESS: //Darkness Dragons any1? | ||||
| 					boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)))); | ||||
| 					break; | ||||
| 				//Complex descriptions | ||||
| 				//case Bonus::SECONDARY_SKILL_PREMY: //only if there's no simple MR | ||||
| 				//	if (bonus->subtype == CGHeroInstance::RESISTANCE) | ||||
| 				//	{ | ||||
| 				//		if (!hasBonusOfType(Bonus::MAGIC_RESISTANCE)) | ||||
| 				//			boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>( magicResistance() )); | ||||
| 				//	} | ||||
| 				//	break; | ||||
| 				//case Bonus::MAGIC_RESISTANCE: | ||||
| 				//		boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>( magicResistance() )); | ||||
| 				//	break; | ||||
| 				case Bonus::HATE: | ||||
| 					boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)))); | ||||
| 					boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl); | ||||
| 					break; | ||||
| 				case Bonus::SPELL_AFTER_ATTACK: | ||||
| 				case Bonus::SPELL_BEFORE_ATTACK: | ||||
| 				{ | ||||
| 					boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)))); | ||||
| 					boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name); | ||||
| 					break; | ||||
| 				} | ||||
| 				case Bonus::SPELL_LIKE_ATTACK: | ||||
| 				{ | ||||
| 					boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name); | ||||
| 					break; | ||||
| 				} | ||||
| 				default: | ||||
| 					{}//TODO: allow custom bonus types... someday, somehow | ||||
| 			} | ||||
| 		} | ||||
| 		else //short name | ||||
| 		{ | ||||
| 			text = it->second.first; | ||||
| 			switch (bonus->type) | ||||
| 			{ | ||||
| 				case Bonus::MANA_CHANNELING: | ||||
| 				case Bonus::MAGIC_MIRROR: | ||||
| 				case Bonus::CHANGES_SPELL_COST_FOR_ALLY: | ||||
| 				case Bonus::CHANGES_SPELL_COST_FOR_ENEMY: | ||||
| 				case Bonus::ENEMY_DEFENCE_REDUCTION: | ||||
| 				case Bonus::REBIRTH: | ||||
| 				case Bonus::DEATH_STARE: | ||||
| 				case Bonus::LIFE_DRAIN: | ||||
| 				case Bonus::FIRE_SHIELD: | ||||
| 					boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(valOfBonuses(Selector::typeSubtype(bonus->type, bonus->subtype)))); | ||||
| 					break; | ||||
| 				case Bonus::HATE: | ||||
| 				case Bonus::DAEMON_SUMMONING: | ||||
| 					boost::algorithm::replace_first(text, "%s", VLC->creh->creatures[bonus->subtype]->namePl); | ||||
| 					break; | ||||
| 				case Bonus::LEVEL_SPELL_IMMUNITY: | ||||
| 					boost::algorithm::replace_first(text, "%d", boost::lexical_cast<std::string>(bonus->val)); | ||||
| 					break; | ||||
| 				case Bonus::SPELL_AFTER_ATTACK: | ||||
| 				case Bonus::SPELL_BEFORE_ATTACK: | ||||
| 				case Bonus::SPELL_IMMUNITY: | ||||
| 				case Bonus::SPELLCASTER: | ||||
| 				case Bonus::ENCHANTER: | ||||
| 				case Bonus::ENCHANTED: | ||||
| 					boost::algorithm::replace_first(text, "%s", VLC->spellh->spells[bonus->subtype]->name); | ||||
| 					break; | ||||
| 				case Bonus::MAGIC_RESISTANCE: | ||||
| 					text = ""; //handled separately | ||||
| 					break; | ||||
| 				//case Bonus::SECONDARY_SKILL_PREMY: | ||||
| 				//	if (bonus->subtype != CGHeroInstance::RESISTANCE || hasBonusOfType(Bonus::MAGIC_RESISTANCE)) //handle it there | ||||
| 				//	text = ""; | ||||
| 				//	break; | ||||
| 			} | ||||
| 		} | ||||
| 		return text; | ||||
| 		return ""; | ||||
| 	} | ||||
| 	else | ||||
| 		return ""; | ||||
| 	{ | ||||
| 		return VLC->getBth()->bonusToString(bonus, this, description); | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
|  | ||||
| std::string CStackInstance::bonusToGraphics(Bonus *bonus) const | ||||
| { | ||||
| 	std::string fileName; | ||||
| 	bool fullPath = false; | ||||
| 	switch (bonus->type) | ||||
| 	{ | ||||
| 			//"E_ALIVE.bmp" | ||||
| 			//"E_ART.bmp" | ||||
| 		case Bonus::ENCHANTED: | ||||
| 			fileName = "E_BLESS.bmp"; break; | ||||
| 			//"E_BLOCK.bmp" | ||||
| 			//"E_BLOCK1.bmp" | ||||
| 			//"E_BLOCK2.bmp" | ||||
| 		case Bonus::TWO_HEX_ATTACK_BREATH: | ||||
| 			fileName = "E_BREATH.bmp"; break; | ||||
| 		case Bonus::SPELL_AFTER_ATTACK: | ||||
| 			fileName = "E_CAST.bmp"; break; | ||||
| 		case Bonus::ENCHANTER: | ||||
| 			fileName = "E_CAST1.bmp"; break; | ||||
| 		case Bonus::RANDOM_SPELLCASTER: | ||||
| 			fileName = "RandomBoost.bmp"; break; | ||||
| 		case Bonus::SPELL_BEFORE_ATTACK: | ||||
| 			fileName ="E_CAST2.bmp"; break; | ||||
| 		case Bonus::SPELLCASTER: | ||||
| 			fileName = "E_CASTER.bmp"; break; | ||||
| 		case Bonus::JOUSTING: | ||||
| 			fileName = "E_CHAMP.bmp"; break; | ||||
| 		case Bonus::DOUBLE_DAMAGE_CHANCE: | ||||
| 			fileName = "E_DBLOW.bmp"; break; | ||||
| 		case Bonus::DEATH_STARE: | ||||
| 			fileName = "E_DEATH.bmp"; break; | ||||
| 		case Bonus::DEFENSIVE_STANCE: | ||||
| 			fileName = "E_DEFBON.bmp"; break; | ||||
| 		case Bonus::NO_DISTANCE_PENALTY: | ||||
| 			fileName = "E_DIST.bmp"; break; | ||||
| 		case Bonus::ADDITIONAL_ATTACK: | ||||
| 			fileName = "E_DOUBLE.bmp"; break; | ||||
| 		case Bonus::DRAGON_NATURE: | ||||
| 			fileName = "E_DRAGON.bmp"; break; | ||||
| 		case Bonus::MAGIC_RESISTANCE: | ||||
| 			fileName = "E_DWARF.bmp"; break; | ||||
| 		case Bonus::SECONDARY_SKILL_PREMY: | ||||
| 			if (bonus->subtype == SecondarySkill::RESISTANCE) | ||||
| 			{ | ||||
| 				fileName = "E_DWARF.bmp"; | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::FEAR: | ||||
| 			fileName = "E_FEAR.bmp"; break; | ||||
| 		case Bonus::FEARLESS: | ||||
| 			fileName = "E_FEARL.bmp"; break; | ||||
| 		case Bonus::FLYING: | ||||
| 			fileName = "E_FLY.bmp"; break; | ||||
| 		case Bonus::SPELL_DAMAGE_REDUCTION: | ||||
| 			fileName = "E_GOLEM.bmp"; break; | ||||
| 		case Bonus::RETURN_AFTER_STRIKE: | ||||
| 			fileName = "E_HARPY.bmp"; break; | ||||
| 		case Bonus::HATE: | ||||
| 			fileName = "E_HATE.bmp"; break; | ||||
| 		case Bonus::KING1: | ||||
| 			fileName = "E_KING1.bmp"; break; | ||||
| 		case Bonus::KING2: | ||||
| 			fileName = "E_KING2.bmp"; break; | ||||
| 		case Bonus::KING3: | ||||
| 			fileName = "E_KING3.bmp"; break; | ||||
| 		case Bonus::CHANGES_SPELL_COST_FOR_ALLY: | ||||
| 			fileName = "E_MANA.bmp"; break; | ||||
| 		case Bonus::CHANGES_SPELL_COST_FOR_ENEMY: | ||||
| 			fileName = "MagicDamper.bpm"; break; | ||||
| 		case Bonus::NO_MELEE_PENALTY: | ||||
| 			fileName = "E_MELEE.bmp"; break; | ||||
| 		case Bonus::MIND_IMMUNITY: | ||||
| 			fileName = "E_MIND.bmp"; break; | ||||
| 		case Bonus::SELF_MORALE: | ||||
| 			fileName = "E_MINOT.bmp"; break; | ||||
| 		case Bonus::NO_MORALE: | ||||
| 			fileName = "E_MORAL.bmp"; break; | ||||
| 		case Bonus::RECEPTIVE: | ||||
| 			fileName = "E_NOFRIM.bmp"; break; | ||||
| 		case Bonus::NO_WALL_PENALTY: | ||||
| 			fileName = "E_OBST.bmp"; break; | ||||
| 		case Bonus::ENEMY_DEFENCE_REDUCTION: | ||||
| 			fileName = "E_RDEF.bmp"; break; | ||||
| 		case Bonus::REBIRTH: | ||||
| 			fileName = "E_REBIRTH.bmp"; break; | ||||
| 		case Bonus::BLOCKS_RETALIATION: | ||||
| 			fileName = "E_RETAIL.bmp"; break; | ||||
| 		case Bonus::UNLIMITED_RETALIATIONS: | ||||
| 		case Bonus::ADDITIONAL_RETALIATION: | ||||
| 			fileName = "E_RETAIL1.bmp"; break; | ||||
| 		case Bonus::ATTACKS_ALL_ADJACENT: | ||||
| 			fileName = "E_ROUND.bmp"; break; | ||||
| 			//"E_SGNUM.bmp" | ||||
| 			//"E_SGTYPE.bmp" | ||||
| 		case Bonus::SHOOTER: | ||||
| 			fileName = "E_SHOOT.bmp"; break; | ||||
| 		case Bonus::FREE_SHOOTING: //shooter is not blocked by enemy | ||||
| 			fileName = "E_SHOOTA.bmp"; break; | ||||
| 			//"E_SHOOTN.bmp" | ||||
| 		case Bonus::SPELL_IMMUNITY: | ||||
| 		{ | ||||
| 			fullPath = true; | ||||
| 			const CSpell * sp = SpellID(bonus->subtype).toSpell(); | ||||
| 			fileName = sp->getIconImmune(); | ||||
| 			break; | ||||
| 		} | ||||
| 			//"E_SPAWILL.bmp" | ||||
| 		case Bonus::DIRECT_DAMAGE_IMMUNITY: | ||||
| 			fileName = "E_SPDIR.bmp"; break; | ||||
| 			//"E_SPDISB.bmp" | ||||
| 			//"E_SPDISP.bmp" | ||||
| 			//"E_SPEATH.bmp" | ||||
| 			//"E_SPEATH1.bmp" | ||||
| 		case Bonus::FIRE_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPFIRE.bmp"; break; //all | ||||
| 				case 1: | ||||
| 					fileName =  "E_SPFIRE1.bmp"; break; //not positive | ||||
| 				case 2: | ||||
| 					fileName =  "E_FIRE.bmp"; break; //direct damage | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::WATER_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPWATER.bmp"; break; //all | ||||
| 				case 1: | ||||
| 					fileName =  "E_SPWATER1.bmp"; break; //not positive | ||||
| 				case 2: | ||||
| 					fileName =  "E_SPCOLD.bmp"; break; //direct damage | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::AIR_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPAIR.bmp"; break; //all | ||||
| 				case 1: | ||||
| 					fileName =  "E_SPAIR1.bmp"; break; //not positive | ||||
| 				case 2: | ||||
| 					fileName = "E_LIGHT.bmp"; break;//direct damage | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::EARTH_IMMUNITY: | ||||
| 			switch (bonus->subtype) | ||||
| 			{ | ||||
| 				case 0: | ||||
| 					fileName =  "E_SPEATH.bmp"; break; //all | ||||
| 				case 1: | ||||
| 				case 2: //no specific icon for direct damage immunity | ||||
| 					fileName =  "E_SPEATH1.bmp"; break; //not positive | ||||
| 			} | ||||
| 			break; | ||||
| 		case Bonus::LEVEL_SPELL_IMMUNITY: | ||||
| 		{ | ||||
| 			if (vstd::iswithin(bonus->val, 1 , 5)) | ||||
| 			{ | ||||
| 				fileName = "E_SPLVL" + boost::lexical_cast<std::string>(bonus->val) + ".bmp"; | ||||
| 			} | ||||
| 			break; | ||||
| 		} | ||||
| 			//"E_SUMMON.bmp" | ||||
| 			//"E_SUMMON1.bmp" | ||||
| 			//"E_SUMMON2.bmp" | ||||
| 		case Bonus::FULL_HP_REGENERATION: | ||||
| 		case Bonus::HP_REGENERATION: | ||||
| 			fileName = "E_TROLL.bmp"; break; | ||||
| 		case Bonus::UNDEAD: | ||||
| 			fileName = "E_UNDEAD.bmp"; break; | ||||
| 		case Bonus::SPELL_RESISTANCE_AURA: | ||||
| 			fileName = "E_UNIC.bmp"; break; | ||||
| 		case Bonus::THREE_HEADED_ATTACK: | ||||
| 			fileName = "ThreeHeaded.bmp"; break; | ||||
| 		case Bonus::DAEMON_SUMMONING: | ||||
| 			fileName = "RiseDemons.bmp"; break; | ||||
| 		case Bonus::CHARGE_IMMUNITY: | ||||
| 			fileName = "ChargeImmune.bmp"; break; | ||||
| 		case Bonus::HEALER: | ||||
| 			fileName = "Healer.bmp"; break; | ||||
| 		case Bonus::CATAPULT: | ||||
| 			fileName = "Catapult.bmp"; break; | ||||
| 		case Bonus::MANA_CHANNELING: | ||||
| 			fileName = "ManaChannel.bmp"; break; | ||||
| 		case Bonus::MANA_DRAIN: | ||||
| 			fileName = "ManaDrain.bmp"; break; | ||||
| 		case Bonus::LIFE_DRAIN: | ||||
| 			fileName = "DrainLife.bmp"; break; | ||||
| 		case Bonus::FIRE_SHIELD: | ||||
| 			fileName = "FireShield.bmp"; break; | ||||
| 		case Bonus::MAGIC_MIRROR: | ||||
| 			fileName = "MagicMirror.bmp"; break; | ||||
| 		case Bonus::NON_LIVING: | ||||
| 			fileName = "NonLiving.bmp"; break; | ||||
| 		case Bonus::SPELL_LIKE_ATTACK: | ||||
| 			fileName = "SpellLikeAttack.bmp"; break; | ||||
| 	} | ||||
| 	if(!fileName.empty() && !fullPath) | ||||
| 		fileName = "zvs/Lib1.res/" + fileName; | ||||
| 	return fileName; | ||||
| 	return VLC->getBth()->bonusToGraphics(bonus); | ||||
| } | ||||
|  | ||||
| void CStackInstance::setArmyObj(const CArmedInstance *ArmyObj) | ||||
|   | ||||
| @@ -56,8 +56,7 @@ public: | ||||
| 	} | ||||
|  | ||||
| 	//overrides CBonusSystemNode | ||||
| 	//void getParents(TCNodes &out, const CBonusSystemNode *source = NULL) const;  //retrieves list of parent nodes (nodes to inherit bonuses from), source is the prinary asker | ||||
| 	std::string bonusToString(Bonus *bonus, bool description) const; // how would bonus description look for this particular type of node | ||||
| 	std::string bonusToString(Bonus *bonus, bool description) const override; // how would bonus description look for this particular type of node | ||||
| 	std::string bonusToGraphics(Bonus *bonus) const; //file name of graphics from StackSkills , in future possibly others | ||||
|  | ||||
| 	virtual ui64 getPower() const; | ||||
|   | ||||
| @@ -2736,20 +2736,6 @@ std::string PlayerState::nodeName() const | ||||
| 	return "Player " + (color.getNum() < VLC->generaltexth->capColors.size() ? VLC->generaltexth->capColors[color.getNum()] : boost::lexical_cast<std::string>(color)); | ||||
| } | ||||
|  | ||||
| // void PlayerState::getParents(TCNodes &out, const CBonusSystemNode *root /*= NULL*/) const | ||||
| // { | ||||
| // 	return; //no loops possible | ||||
| // } | ||||
| // | ||||
| // void PlayerState::getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root /*= NULL*/) const | ||||
| // { | ||||
| // 	for (std::vector<CGHeroInstance *>::const_iterator it = heroes.begin(); it != heroes.end(); it++) | ||||
| // 	{ | ||||
| // 		if (*it != root) | ||||
| // 			(*it)->getBonuses(out, selector, this); | ||||
| // 	} | ||||
| // } | ||||
|  | ||||
| InfoAboutArmy::InfoAboutArmy(): | ||||
|     owner(PlayerColor::NEUTRAL) | ||||
| {} | ||||
|   | ||||
| @@ -181,10 +181,6 @@ public: | ||||
| 	PlayerState(); | ||||
| 	std::string nodeName() const OVERRIDE; | ||||
|  | ||||
| 	//override | ||||
| 	//void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; | ||||
| 	//void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & color & human & currentSelection & team & resources & status; | ||||
|   | ||||
| @@ -26,6 +26,7 @@ set(lib_SRCS | ||||
| 		BattleState.cpp | ||||
| 		CArtHandler.cpp | ||||
| 		CBattleCallback.cpp | ||||
| 		CBonusTypeHandler.cpp | ||||
| 		CBuildingHandler.cpp | ||||
| 		CConfigHandler.cpp | ||||
| 		CConsoleHandler.cpp | ||||
| @@ -67,6 +68,7 @@ set(lib_HEADERS | ||||
| 		AI_Base.h | ||||
| 		CondSh.h | ||||
| 		ConstTransitivePtr.h | ||||
| 		CBonusTypeHandler.h | ||||
| 		CRandomGenerator.h | ||||
| 		CScriptingModule.h | ||||
| 		CStopWatch.h | ||||
|   | ||||
| @@ -13,7 +13,7 @@ | ||||
| #include "StringConstants.h" | ||||
|  | ||||
| /* | ||||
|  * CModHandler.h, part of VCMI engine | ||||
|  * CModHandler.cpp, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|   | ||||
| @@ -198,7 +198,7 @@ static void readBankLevel(const JsonNode &level, BankConfig &bc) | ||||
| 	bc.easiest = level["easiest"].Float(); | ||||
| } | ||||
|  | ||||
| void CObjectHandler::loadObjects() | ||||
| void CObjectHandler::load() | ||||
| { | ||||
| 	tlog5 << "\t\tReading cregens \n"; | ||||
|  | ||||
|   | ||||
| @@ -353,9 +353,6 @@ public: | ||||
| 		//visitied town pointer will be restored by map serialization method | ||||
| 	} | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| // 	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; | ||||
| // 	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| 	int3 getSightCenter() const; //"center" tile from which the sight distance is calculated | ||||
| 	int getSightRadious() const; //sight distance (should be used if player-owned structure) | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
| @@ -622,8 +619,7 @@ public: | ||||
| 	void setVisitingHero(CGHeroInstance *h); | ||||
| 	void setGarrisonedHero(CGHeroInstance *h); | ||||
| 	const CArmedInstance *getUpperArmy() const; //garrisoned hero if present or the town itself | ||||
| // 	void getParents(TCNodes &out, const CBonusSystemNode *root = NULL) const; | ||||
| // 	void getBonuses(BonusList &out, const CSelector &selector, const CBonusSystemNode *root = NULL) const; | ||||
|  | ||||
| 	////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| 	ui8 getPassableness() const; //bitmap - if the bit is set the corresponding player can pass through the visitable tiles of object, even if it's blockvis; if not set - default properties from definfo are used | ||||
| @@ -1398,7 +1394,7 @@ public: | ||||
| 	std::map <ui32, std::string> creBanksNames; //[crebank index] -> name of this creature bank | ||||
| 	std::vector<ui32> resVals; //default values of resources in gold | ||||
|  | ||||
| 	void loadObjects(); | ||||
| 	void load(); | ||||
| 	int bankObjToIndex (const CGObjectInstance * obj); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
|   | ||||
| @@ -397,7 +397,7 @@ CSpell * CSpellHandler::loadSpell(CLegacyConfigParser & parser, const SpellID id | ||||
| 	return spell; | ||||
| } | ||||
|  | ||||
| void CSpellHandler::loadSpells() | ||||
| void CSpellHandler::load() | ||||
| { | ||||
| 	CLegacyConfigParser parser("DATA/SPTRAITS.TXT"); | ||||
|  | ||||
|   | ||||
| @@ -168,7 +168,7 @@ public: | ||||
| 	CSpellHandler(); | ||||
| 	std::vector< ConstTransitivePtr<CSpell> > spells; | ||||
|  | ||||
| 	void loadSpells(); | ||||
| 	void load(); | ||||
|  | ||||
| 	/** | ||||
| 	 * Gets a list of default allowed spells. OH3 spells are all allowed by default. | ||||
|   | ||||
							
								
								
									
										25
									
								
								lib/IBonusTypeHandler.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								lib/IBonusTypeHandler.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,25 @@ | ||||
| /* | ||||
|  * IBonusTypeHandler.h, 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 | ||||
|  * | ||||
|  */ | ||||
|   | ||||
| #pragma once | ||||
|  | ||||
| class IBonusBearer; | ||||
| struct Bonus; | ||||
|  | ||||
| ///High level interface for BonusTypeHandler | ||||
|  | ||||
| class IBonusTypeHandler | ||||
| { | ||||
| public: | ||||
| 	virtual ~IBonusTypeHandler(){}; | ||||
|  | ||||
| 	virtual std::string bonusToString(Bonus *bonus, const IBonusBearer *bearer, bool description) const = 0; | ||||
| 	virtual std::string bonusToGraphics(Bonus *bonus) const = 0; | ||||
| }; | ||||
| @@ -18,6 +18,7 @@ | ||||
| #include "GameConstants.h" | ||||
| #include "CModHandler.h" | ||||
| #include "CDefObjInfoHandler.h" | ||||
| #include "CBonusTypeHandler.h" | ||||
|  | ||||
| #include "Connection.h" | ||||
|  | ||||
|   | ||||
| @@ -1,8 +1,18 @@ | ||||
| /* | ||||
|  * VCMI_Lib.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" | ||||
| #include "VCMI_Lib.h" | ||||
|  | ||||
|  | ||||
| #include "CArtHandler.h" | ||||
| #include "CBonusTypeHandler.h" | ||||
| #include "CCreatureHandler.h" | ||||
| #include "CDefObjInfoHandler.h" | ||||
| #include "CHeroHandler.h" | ||||
| @@ -17,15 +27,6 @@ | ||||
| #include "VCMIDirs.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
|  | ||||
| /* | ||||
|  * VCMI_Lib.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 | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| LibClasses * VLC = NULL; | ||||
|  | ||||
| @@ -50,6 +51,11 @@ DLL_LINKAGE void loadDLLClasses() | ||||
| 	HANDLE_EXCEPTION; | ||||
| } | ||||
|  | ||||
| const IBonusTypeHandler * LibClasses::getBth() const | ||||
| { | ||||
| 	return bth; | ||||
| } | ||||
|  | ||||
| void LibClasses::loadFilesystem() | ||||
| { | ||||
| 	CStopWatch totalTime; | ||||
| @@ -71,41 +77,40 @@ void LibClasses::loadFilesystem() | ||||
| 	tlog0<<"Basic initialization: "<<totalTime.getDiff()<<std::endl; | ||||
| } | ||||
|  | ||||
| static void logHandlerLoaded(const std::string& name, CStopWatch &timer) | ||||
| { | ||||
|    tlog0<<"\t" << name << " handler: "<<timer.getDiff()<<std::endl; | ||||
| }; | ||||
|  | ||||
| template <class Handler> void createHandler(Handler *&handler, const std::string &name, CStopWatch &timer) | ||||
| { | ||||
| 	handler = new Handler(); | ||||
| 	handler->load(); | ||||
| 	logHandlerLoaded(name, timer); | ||||
| }  | ||||
|  | ||||
| void LibClasses::init() | ||||
| { | ||||
| 	CStopWatch pomtime; | ||||
| 	 | ||||
| 	createHandler(bth, "Bonus type", pomtime); | ||||
| 	 | ||||
| 	createHandler(generaltexth, "General text", pomtime); | ||||
|  | ||||
| 	generaltexth = new CGeneralTextHandler; | ||||
| 	generaltexth->load(); | ||||
| 	tlog0<<"\tGeneral text handler: "<<pomtime.getDiff()<<std::endl; | ||||
| 	createHandler(heroh, "Hero", pomtime); | ||||
|  | ||||
| 	heroh = new CHeroHandler; | ||||
| 	heroh->load(); | ||||
| 	tlog0 <<"\tHero handler: "<<pomtime.getDiff()<<std::endl; | ||||
| 	createHandler(arth, "Artifact", pomtime); | ||||
|  | ||||
| 	arth = new CArtHandler; | ||||
| 	arth->loadArtifacts(false); | ||||
| 	tlog0<<"\tArtifact handler: "<<pomtime.getDiff()<<std::endl; | ||||
| 	createHandler(creh, "Creature", pomtime); | ||||
|  | ||||
| 	creh = new CCreatureHandler(); | ||||
| 	creh->loadCreatures(); | ||||
| 	tlog0<<"\tCreature handler: "<<pomtime.getDiff()<<std::endl; | ||||
| 	createHandler(townh, "Town", pomtime); | ||||
| 	 | ||||
| 	createHandler(objh, "Object", pomtime); | ||||
| 	 | ||||
| 	createHandler(dobjinfo, "Def information", pomtime); | ||||
|  | ||||
| 	townh = new CTownHandler; | ||||
| 	townh->load(); | ||||
| 	tlog0<<"\tTown handler: "<<pomtime.getDiff()<<std::endl; | ||||
| 	createHandler(spellh, "Spell", pomtime); | ||||
|  | ||||
| 	objh = new CObjectHandler; | ||||
| 	objh->loadObjects(); | ||||
| 	tlog0<<"\tObject handler: "<<pomtime.getDiff()<<std::endl; | ||||
|  | ||||
| 	dobjinfo = new CDefObjInfoHandler; | ||||
| 	dobjinfo->load(); | ||||
| 	tlog0<<"\tDef information handler: "<<pomtime.getDiff()<<std::endl; | ||||
|  | ||||
| 	spellh = new CSpellHandler; | ||||
| 	spellh->loadSpells(); | ||||
| 	tlog0<<"\tSpell handler: "<<pomtime.getDiff()<<std::endl; | ||||
|  | ||||
| 	modh->loadActiveMods(); | ||||
| 	modh->reload(); | ||||
| @@ -126,20 +131,22 @@ void LibClasses::clear() | ||||
| 	delete dobjinfo; | ||||
| 	delete spellh; | ||||
| 	delete modh; | ||||
| 	delete bth; | ||||
| 	makeNull(); | ||||
| } | ||||
|  | ||||
| void LibClasses::makeNull() | ||||
| { | ||||
| 	generaltexth = NULL; | ||||
| 	heroh = NULL; | ||||
| 	arth = NULL; | ||||
| 	creh = NULL; | ||||
| 	townh = NULL; | ||||
| 	objh = NULL; | ||||
| 	dobjinfo = NULL; | ||||
| 	spellh = NULL; | ||||
| 	modh = NULL; | ||||
| 	generaltexth = nullptr; | ||||
| 	heroh = nullptr; | ||||
| 	arth = nullptr; | ||||
| 	creh = nullptr; | ||||
| 	townh = nullptr; | ||||
| 	objh = nullptr; | ||||
| 	dobjinfo = nullptr; | ||||
| 	spellh = nullptr; | ||||
| 	modh = nullptr; | ||||
| 	bth = nullptr; | ||||
| } | ||||
|  | ||||
| LibClasses::LibClasses() | ||||
| @@ -152,7 +159,7 @@ void LibClasses::callWhenDeserializing() | ||||
| { | ||||
| 	generaltexth = new CGeneralTextHandler; | ||||
| 	generaltexth->load(); | ||||
| 	arth->loadArtifacts(true); | ||||
| 	arth->load(true); | ||||
| 	//modh->recreateHandlers(); | ||||
| 	//modh->loadConfigFromFile ("defaultMods"); //TODO: remember last saved config | ||||
| } | ||||
|   | ||||
| @@ -20,14 +20,21 @@ class CDefObjInfoHandler; | ||||
| class CTownHandler; | ||||
| class CGeneralTextHandler; | ||||
| class CModHandler; | ||||
| class IBonusTypeHandler; | ||||
| class CBonusTypeHandler; | ||||
|  | ||||
| /// Loads and constructs several handlers | ||||
| class DLL_LINKAGE LibClasses | ||||
| { | ||||
| 	CBonusTypeHandler * bth; | ||||
| 	 | ||||
| 	void callWhenDeserializing(); //should be called only by serialize !!! | ||||
| 	void makeNull(); //sets all handler pointers to null | ||||
| public: | ||||
| 	bool IS_AI_ENABLED; //VLC is the only object visible from both CMT and GeniusAI | ||||
| 	 | ||||
| 	const IBonusTypeHandler * getBth() const; | ||||
| 	 | ||||
| 	CArtHandler * arth; | ||||
| 	CHeroHandler * heroh; | ||||
| 	CCreatureHandler * creh; | ||||
| @@ -49,7 +56,8 @@ public: | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & heroh & arth & creh & townh & objh & dobjinfo & spellh & modh & IS_AI_ENABLED;; | ||||
| 		h & heroh & arth & creh & townh & objh & dobjinfo & spellh & modh & IS_AI_ENABLED; | ||||
| 		h & bth; | ||||
| 		if(!h.saving) | ||||
| 		{ | ||||
| 			callWhenDeserializing(); | ||||
|   | ||||
| @@ -13,6 +13,8 @@ | ||||
| 				<Option object_output="../obj/Debug/Lib" /> | ||||
| 				<Option type="3" /> | ||||
| 				<Option compiler="gcc" /> | ||||
| 				<Option host_application="D:/projects/vcmi/engine/VCMI_client.exe" /> | ||||
| 				<Option run_host_application_in_terminal="1" /> | ||||
| 				<Option createStaticLib="1" /> | ||||
| 				<Compiler> | ||||
| 					<Add option="-O1" /> | ||||
| @@ -73,6 +75,8 @@ | ||||
| 		<Unit filename="CArtHandler.h" /> | ||||
| 		<Unit filename="CBattleCallback.cpp" /> | ||||
| 		<Unit filename="CBattleCallback.h" /> | ||||
| 		<Unit filename="CBonusTypeHandler.cpp" /> | ||||
| 		<Unit filename="CBonusTypeHandler.h" /> | ||||
| 		<Unit filename="CBuildingHandler.cpp" /> | ||||
| 		<Unit filename="CBuildingHandler.h" /> | ||||
| 		<Unit filename="CConfigHandler.cpp" /> | ||||
| @@ -136,6 +140,7 @@ | ||||
| 		<Unit filename="GameConstants.h" /> | ||||
| 		<Unit filename="HeroBonus.cpp" /> | ||||
| 		<Unit filename="HeroBonus.h" /> | ||||
| 		<Unit filename="IBonusTypeHandler.h" /> | ||||
| 		<Unit filename="IGameCallback.cpp" /> | ||||
| 		<Unit filename="IGameCallback.h" /> | ||||
| 		<Unit filename="IGameEventsReceiver.h" /> | ||||
| @@ -171,6 +176,7 @@ | ||||
| 		</Unit> | ||||
| 		<Unit filename="StringConstants.h" /> | ||||
| 		<Unit filename="UnlockGuard.h" /> | ||||
| 		<Unit filename="VCMIDirs.cpp" /> | ||||
| 		<Unit filename="VCMIDirs.h" /> | ||||
| 		<Unit filename="VCMI_Lib.cpp" /> | ||||
| 		<Unit filename="VCMI_Lib.h" /> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user