mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	* Fixed enchantments (#1265). Their effects were not properly added when reading config. Battle interface will be little less likely to block itself after corrupted spell cast.
* Fail gracefully when the file from which game is started is in invalid version. * Bumped versions.
This commit is contained in:
		| @@ -97,22 +97,30 @@ void startGame(StartInfo * options, CConnection *serv = NULL); | ||||
|  | ||||
| void startGameFromFile(const std::string &fname) | ||||
| { | ||||
| 	if(fname.size() && boost::filesystem::exists(fname)) | ||||
| 	StartInfo si; | ||||
| 	try //attempt retrieving start info from given file | ||||
| 	{ | ||||
| 		StartInfo si; | ||||
| 		if(!fname.size() || !boost::filesystem::exists(fname)) | ||||
| 			throw std::runtime_error("Startfile \"" + fname + "\" does not exist!"); | ||||
|  | ||||
| 		CLoadFile out(fname); | ||||
| 		if(!out.sfile || !*out.sfile) | ||||
| 		{ | ||||
|             logGlobal->errorStream() << "Failed to open startfile, falling back to the main menu!"; | ||||
| 			GH.curInt = CGPreGame::create(); | ||||
| 			return; | ||||
| 			throw std::runtime_error("Cannot read from startfile \"" + fname + "\"!"); | ||||
| 		} | ||||
| 		out >> si; | ||||
| 		while(GH.topInt()) | ||||
| 			GH.popIntTotally(GH.topInt()); | ||||
|  | ||||
| 		startGame(&si); | ||||
| 	} | ||||
| 	catch(std::exception &e) | ||||
| 	{ | ||||
| 		logGlobal->errorStream() << "Failed to start from the file: " + fname << ". Error: " << e.what()  | ||||
| 			<< " Falling back to main menu."; | ||||
| 		GH.curInt = CGPreGame::create(); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	while(GH.topInt()) | ||||
| 		GH.popIntTotally(GH.topInt()); | ||||
| 	startGame(&si); | ||||
| } | ||||
|  | ||||
| void init() | ||||
|   | ||||
| @@ -2493,10 +2493,7 @@ void CBattleInterface::projectileShowHelper(SDL_Surface * to) | ||||
| void CBattleInterface::endAction(const BattleAction* action) | ||||
| { | ||||
| 	const CStack * stack = curInt->cb->battleGetStackByID(action->stackNumber); | ||||
| 	//if((action->actionType==2 || (action->actionType==6 && action->destinationTile!=cb->battleGetPos(action->stackNumber)))) //activating interface when move is finished | ||||
| // 	{ | ||||
| // 		activate(); | ||||
| // 	} | ||||
|  | ||||
| 	if(action->actionType == Battle::HERO_SPELL) | ||||
| 	{ | ||||
| 		if(action->side) | ||||
| @@ -2536,6 +2533,12 @@ void CBattleInterface::endAction(const BattleAction* action) | ||||
|  | ||||
| 	if( action->actionType == Battle::HERO_SPELL) //we have activated next stack after sending request that has been just realized -> blockmap due to movement has changed | ||||
| 		redrawBackgroundWithHexes(activeStack); | ||||
|  | ||||
| 	if(activeStack && !animsAreDisplayed.get() && pendingAnims.empty() && !active) | ||||
| 	{ | ||||
| 		logGlobal->warnStream() << "Something wrong... interface was deactivated but there is no animation. Reactivating..."; | ||||
| 		activate(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CBattleInterface::hideQueue() | ||||
|   | ||||
| @@ -248,14 +248,19 @@ CSpell::ETargetType CSpell::getTargetType() const | ||||
|  | ||||
| void CSpell::getEffects(std::vector<Bonus>& lst, const int level) const | ||||
| { | ||||
| 	if (level < 0 || level>3) | ||||
| 	if (level < 0 || level >= GameConstants::SPELL_SCHOOL_LEVELS) | ||||
| 	{ | ||||
|         logGlobal->errorStream() << __FUNCTION__ << " invalid school level " << level; | ||||
| 		return; | ||||
| 	} | ||||
| 	if (effects.empty()) | ||||
| 	{ | ||||
|         logGlobal->errorStream() << __FUNCTION__ << " This spell has no bonus effects! " << name; | ||||
|         logGlobal->errorStream() << __FUNCTION__ << " This spell ("  + name + ") has no bonus effects! " << name; | ||||
| 		return; | ||||
| 	} | ||||
| 	if (effects.size() <= level) | ||||
| 	{ | ||||
| 		logGlobal->errorStream() << __FUNCTION__ << " This spell ("  + name + ") is missing entry for level " << level; | ||||
| 		return; | ||||
| 	} | ||||
| 	lst.reserve(lst.size() + effects[level].size()); | ||||
| @@ -440,7 +445,8 @@ CSpellHandler::CSpellHandler() | ||||
| 	spells.push_back(spells[SpellID::ACID_BREATH_DEFENSE]); //clone Acid Breath attributes for Acid Breath damage effect | ||||
|  | ||||
| 	//loading of additional spell traits | ||||
| 	const JsonNode config(ResourceID("config/spell_info.json")); | ||||
| 	JsonNode config(ResourceID("config/spell_info.json")); | ||||
| 	config.setMeta("core"); | ||||
|  | ||||
| 	BOOST_FOREACH(auto &spell, config["spells"].Struct()) | ||||
| 	{ | ||||
| @@ -493,7 +499,14 @@ CSpellHandler::CSpellHandler() | ||||
| 			auto v = v_node.convertTo<std::vector<int> >(); | ||||
| 			auto a = a_node.convertTo<std::vector<int> >(); | ||||
|  | ||||
| 			for (int i=0; i<s->effects.size() ; i++) | ||||
| 			if(v.size() && v.size() != GameConstants::SPELL_SCHOOL_LEVELS) | ||||
| 				logGlobal->errorStream() << s->name << " should either have no values or exactly " << GameConstants::SPELL_SCHOOL_LEVELS; | ||||
| 			if(a.size() && a.size() != GameConstants::SPELL_SCHOOL_LEVELS) | ||||
| 				logGlobal->errorStream() << s->name << " should either have no ainfos or exactly " << GameConstants::SPELL_SCHOOL_LEVELS; | ||||
| 			 | ||||
| 			s->effects.resize(GameConstants::SPELL_SCHOOL_LEVELS); | ||||
|  | ||||
| 			for (int i = 0; i < GameConstants::SPELL_SCHOOL_LEVELS; i++) | ||||
| 			{ | ||||
| 				Bonus * b = JsonUtils::parseBonus(bonus_node); | ||||
| 				b->sid = s->id; //for all | ||||
|   | ||||
| @@ -27,7 +27,7 @@ | ||||
| #include "mapping/CCampaignHandler.h" //for CCampaignState | ||||
| #include "rmg/CMapGenerator.h" // for CMapGenOptions | ||||
|  | ||||
| const ui32 version = 739; | ||||
| const ui32 version = 740; | ||||
|  | ||||
| class CConnection; | ||||
| class CGObjectInstance; | ||||
|   | ||||
| @@ -14,7 +14,7 @@ | ||||
|  | ||||
| namespace GameConstants | ||||
| { | ||||
| 	const std::string VCMI_VERSION = "VCMI 0.92"; | ||||
| 	const std::string VCMI_VERSION = "VCMI 0.92b"; | ||||
|  | ||||
| 	const int BFIELD_WIDTH = 17; | ||||
| 	const int BFIELD_HEIGHT = 11; | ||||
| @@ -30,6 +30,7 @@ namespace GameConstants | ||||
| 	const ui16 BACKPACK_START = 19; | ||||
| 	const int CREATURES_PER_TOWN = 7; //without upgrades | ||||
| 	const int SPELL_LEVELS = 5; | ||||
| 	const int SPELL_SCHOOL_LEVELS = 4; | ||||
| 	const int CRE_LEVELS = 10; // number of creature experience levels | ||||
|  | ||||
| 	const int SPELLBOOK_GOLD_COST = 500; | ||||
|   | ||||
| @@ -1538,6 +1538,8 @@ CGObjectInstance * CMapLoaderH3M::readHero(ObjectInstanceID idToBeGiven) | ||||
| 	PlayerColor owner = PlayerColor(reader.readUInt8()); | ||||
| 	nhi->subID = reader.readUInt8(); | ||||
|  | ||||
| 	//If hero of this type has been predefined, use that as a base. | ||||
| 	//Instance data will overwrite the predefined values where appropriate. | ||||
| 	for(int j = 0; j < map->predefinedHeroes.size(); ++j) | ||||
| 	{ | ||||
| 		if(map->predefinedHeroes[j]->subID == nhi->subID) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user