mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	- moved json-related functions (e.g. ParseBonus) into JsonUtils namespace
- replaced JsonNode::toStdVector with more universal convertTo - some renaming in StartInfo
This commit is contained in:
		| @@ -294,7 +294,7 @@ void CTownList::CTownItem::update() | ||||
| { | ||||
| 	size_t iconIndex = town->town->clientInfo.icons[town->hasFort()][town->builded >= CGI->modh->settings.MAX_BUILDING_PER_TURN]; | ||||
|  | ||||
| 	picture->setFrame(iconIndex + 2); | ||||
| 	picture->setFrame(iconIndex); | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -1202,6 +1202,8 @@ void CAnimImage::setFrame(size_t Frame, size_t Group) | ||||
| 			pos.h = img->height(); | ||||
| 		} | ||||
| 	} | ||||
| 	else | ||||
| 		tlog1 << "Error: accessing unavailable frame " << Group << ":" << Frame << " in CAnimation!\n"; | ||||
| } | ||||
|  | ||||
| void CAnimImage::playerColored(int currPlayer) | ||||
|   | ||||
| @@ -860,7 +860,7 @@ void startGame(StartInfo * options, CConnection *serv/* = NULL*/) | ||||
| 	{ | ||||
| 		for(auto it = options->playerInfos.begin(); it != options->playerInfos.end(); ++it) | ||||
| 		{ | ||||
| 			it->second.human = false; | ||||
| 			it->second.playerID = PlayerSettings::PLAYER_AI; | ||||
| 		} | ||||
| 	} | ||||
| /*	const JsonNode& res = settings["video"]["screenRes"]; | ||||
|   | ||||
| @@ -120,12 +120,12 @@ static void setPlayersFromGame() | ||||
|  | ||||
| static void swapPlayers(PlayerSettings &a, PlayerSettings &b) | ||||
| { | ||||
| 	std::swap(a.human, b.human); | ||||
| 	std::swap(a.playerID, b.playerID); | ||||
| 	std::swap(a.name, b.name); | ||||
|  | ||||
| 	if(a.human == 1) | ||||
| 	if(a.playerID == 1) | ||||
| 		playerColor = a.color; | ||||
| 	else if(b.human == 1) | ||||
| 	else if(b.playerID == 1) | ||||
| 		playerColor = b.color; | ||||
| } | ||||
|  | ||||
| @@ -136,7 +136,7 @@ void setPlayer(PlayerSettings &pset, TPlayerColor player, const std::map<TPlayer | ||||
| 	else | ||||
| 		pset.name = CGI->generaltexth->allTexts[468];//Computer | ||||
|  | ||||
| 	pset.human = player; | ||||
| 	pset.playerID = player; | ||||
| 	if(player == playerNames.begin()->first) | ||||
| 		playerColor = pset.color; | ||||
| } | ||||
| @@ -844,7 +844,7 @@ void CSelectionScreen::startGame() | ||||
| 		//there must be at least one human player before game can be started | ||||
| 		std::map<TPlayerColor, PlayerSettings>::const_iterator i; | ||||
| 		for(i = SEL->sInfo.playerInfos.cbegin(); i != SEL->sInfo.playerInfos.cend(); i++) | ||||
| 			if(i->second.human) | ||||
| 			if(i->second.playerID != PlayerSettings::PLAYER_AI) | ||||
| 				break; | ||||
|  | ||||
| 		if(i == SEL->sInfo.playerInfos.cend()) | ||||
| @@ -951,7 +951,7 @@ void CSelectionScreen::setSInfo(const StartInfo &si) | ||||
| 	std::map<TPlayerColor, PlayerSettings>::const_iterator i; | ||||
| 	for(i = si.playerInfos.cbegin(); i != si.playerInfos.cend(); i++) | ||||
| 	{ | ||||
| 		if(i->second.human == myNameID) | ||||
| 		if(i->second.playerID == myNameID) | ||||
| 		{ | ||||
| 			playerColor = i->first; | ||||
| 			break; | ||||
| @@ -1988,10 +1988,10 @@ void InfoCard::showAll(SDL_Surface * to) | ||||
| 			int playerSoFar = 0; | ||||
| 			for (auto i = SEL->sInfo.playerInfos.cbegin(); i != SEL->sInfo.playerInfos.cend(); i++) | ||||
| 			{ | ||||
| 				if(i->second.human) | ||||
| 				if(i->second.playerID != PlayerSettings::PLAYER_AI) | ||||
| 				{ | ||||
| 					printAtLoc(i->second.name, 24, 285 + playerSoFar++ * graphics->fonts[FONT_SMALL]->height, FONT_SMALL, Colors::WHITE, to); | ||||
| 					playerNames.erase(i->second.human); | ||||
| 					playerNames.erase(i->second.playerID); | ||||
| 				} | ||||
| 			} | ||||
|  | ||||
| @@ -2244,7 +2244,7 @@ void OptionsTab::nextCastle( int player, int dir ) | ||||
| 	} | ||||
|  | ||||
| 	PlayerSettings &s = SEL->sInfo.playerInfos[player]; | ||||
| 	si32 &cur = s.castle; | ||||
| 	si16 &cur = s.castle; | ||||
| 	auto & allowed = SEL->current->mapHeader->players[s.color].allowedFactions; | ||||
|  | ||||
| 	if (cur == -2) //no castle - no change | ||||
| @@ -2274,8 +2274,8 @@ void OptionsTab::nextCastle( int player, int dir ) | ||||
|  | ||||
| 	if(s.hero >= 0) | ||||
| 		s.hero = -1; | ||||
| 	if(cur < 0  &&  s.bonus == PlayerSettings::bresource) | ||||
| 		s.bonus = PlayerSettings::brandom; | ||||
| 	if(cur < 0  &&  s.bonus == PlayerSettings::RESOURCE) | ||||
| 		s.bonus = PlayerSettings::RANDOM; | ||||
|  | ||||
| 	entries[player]->selectButtons(); | ||||
|  | ||||
| @@ -2293,7 +2293,7 @@ void OptionsTab::nextHero( int player, int dir ) | ||||
|  | ||||
| 	PlayerSettings &s = SEL->sInfo.playerInfos[player]; | ||||
| 	int old = s.hero; | ||||
| 	if (s.castle < 0  ||  !s.human  ||  s.hero == -2) | ||||
| 	if (s.castle < 0  ||  s.playerID == PlayerSettings::PLAYER_AI  ||  s.hero == PlayerSettings::NONE) | ||||
| 		return; | ||||
|  | ||||
| 	if (s.hero == -1) //random => first/last available | ||||
| @@ -2359,23 +2359,23 @@ void OptionsTab::nextBonus( int player, int dir ) | ||||
| 	PlayerSettings &s = SEL->sInfo.playerInfos[player]; | ||||
| 	si8 &ret = s.bonus += dir; | ||||
|  | ||||
| 	if (s.hero==-2 && !SEL->current->mapHeader->players[s.color].heroesNames.size() && ret==PlayerSettings::bartifact) //no hero - can't be artifact | ||||
| 	if (s.hero==-2 && !SEL->current->mapHeader->players[s.color].heroesNames.size() && ret==PlayerSettings::ARTIFACT) //no hero - can't be artifact | ||||
| 	{ | ||||
| 		if (dir<0) | ||||
| 			ret=PlayerSettings::brandom; | ||||
| 		else ret=PlayerSettings::bgold; | ||||
| 			ret=PlayerSettings::RANDOM; | ||||
| 		else ret=PlayerSettings::GOLD; | ||||
| 	} | ||||
|  | ||||
| 	if(ret > PlayerSettings::bresource) | ||||
| 		ret = PlayerSettings::brandom; | ||||
| 	if(ret < PlayerSettings::brandom) | ||||
| 		ret = PlayerSettings::bresource; | ||||
| 	if(ret > PlayerSettings::RESOURCE) | ||||
| 		ret = PlayerSettings::RANDOM; | ||||
| 	if(ret < PlayerSettings::RANDOM) | ||||
| 		ret = PlayerSettings::RESOURCE; | ||||
|  | ||||
| 	if (s.castle==-1 && ret==PlayerSettings::bresource) //random castle - can't be resource | ||||
| 	if (s.castle==-1 && ret==PlayerSettings::RESOURCE) //random castle - can't be resource | ||||
| 	{ | ||||
| 		if (dir<0) | ||||
| 			ret=PlayerSettings::bgold; | ||||
| 		else ret=PlayerSettings::brandom; | ||||
| 			ret=PlayerSettings::GOLD; | ||||
| 		else ret=PlayerSettings::RANDOM; | ||||
| 	} | ||||
|  | ||||
| 	SEL->propagateOptions(); | ||||
| @@ -2427,7 +2427,7 @@ void OptionsTab::flagPressed( int color ) | ||||
| 	else | ||||
| 	{ | ||||
| 		//identify clicked player | ||||
| 		int clickedNameID = clicked.human; //human is a number of player, zero means AI | ||||
| 		int clickedNameID = clicked.playerID; //human is a number of player, zero means AI | ||||
|  | ||||
| 		if(clickedNameID > 0  &&  playerToRestore.id == clickedNameID) //player to restore is about to being replaced -> put him back to the old place | ||||
| 		{ | ||||
| @@ -2463,10 +2463,10 @@ void OptionsTab::flagPressed( int color ) | ||||
| 		{ | ||||
| 			for(auto i = SEL->sInfo.playerInfos.begin(); i != SEL->sInfo.playerInfos.end(); i++) | ||||
| 			{ | ||||
| 				int curNameID = i->second.human; | ||||
| 				int curNameID = i->second.playerID; | ||||
| 				if(i->first != color  &&  curNameID == newPlayer) | ||||
| 				{ | ||||
| 					assert(i->second.human); | ||||
| 					assert(i->second.playerID); | ||||
| 					playerToRestore.color = i->first; | ||||
| 					playerToRestore.id = newPlayer; | ||||
| 					SEL->setPlayer(i->second, 0); //set computer | ||||
| @@ -2584,7 +2584,7 @@ void OptionsTab::PlayerOptionsEntry::selectButtons() | ||||
| 		btns[1]->enable(); | ||||
| 	} | ||||
|  | ||||
| 	if( (pi.defaultHero() != -1  ||  !s.human  ||  s.castle < 0) //fixed hero | ||||
| 	if( (pi.defaultHero() != -1  ||  !s.playerID  ||  s.castle < 0) //fixed hero | ||||
| 		|| (SEL->isGuest() && s.color != playerColor))//or not our player | ||||
| 	{ | ||||
| 		btns[2]->disable(); | ||||
| @@ -2792,20 +2792,20 @@ void OptionsTab::SelectedBox::clickRight( tribool down, bool previousState ) | ||||
| 			{ | ||||
| 				switch(val) | ||||
| 				{ | ||||
| 				case PlayerSettings::brandom: | ||||
| 				case PlayerSettings::RANDOM: | ||||
| 					title = &CGI->generaltexth->allTexts[86]; //{Random Bonus} | ||||
| 					description = &CGI->generaltexth->allTexts[94]; //Gold, wood and ore, or an artifact is randomly chosen as your starting bonus | ||||
| 					break; | ||||
| 				case PlayerSettings::bartifact: | ||||
| 				case PlayerSettings::ARTIFACT: | ||||
| 					title = &CGI->generaltexth->allTexts[83]; //{Artifact Bonus} | ||||
| 					description = &CGI->generaltexth->allTexts[90]; //An artifact is randomly chosen and equipped to your starting hero | ||||
| 					break; | ||||
| 				case PlayerSettings::bgold: | ||||
| 				case PlayerSettings::GOLD: | ||||
| 					title = &CGI->generaltexth->allTexts[84]; //{Gold Bonus} | ||||
| 					subTitle = &CGI->generaltexth->allTexts[87]; //500-1000 | ||||
| 					description = &CGI->generaltexth->allTexts[92]; //At the start of the game, 500-1000 gold is added to your Kingdom's resource pool | ||||
| 					break; | ||||
| 				case PlayerSettings::bresource: | ||||
| 				case PlayerSettings::RESOURCE: | ||||
| 					{ | ||||
| 						title = &CGI->generaltexth->allTexts[85]; //{Resource Bonus} | ||||
| 						switch(CGI->townh->towns[s.castle].primaryRes) | ||||
| @@ -2909,7 +2909,7 @@ CScenarioInfo::CScenarioInfo(const CMapHeader *mapHeader, const StartInfo *start | ||||
|  | ||||
| 	for(auto it = startInfo->playerInfos.cbegin(); it != startInfo->playerInfos.cend(); ++it) | ||||
| 	{ | ||||
| 		if(it->second.human) | ||||
| 		if(it->second.playerID) | ||||
| 		{ | ||||
| 			playerColor = it->first; | ||||
| 		} | ||||
| @@ -3406,7 +3406,7 @@ void CBonusSelection::updateBonusSelection() | ||||
| 					int faction = -1; | ||||
| 					for(auto it = sInfo.playerInfos.begin(); it != sInfo.playerInfos.end(); ++it) | ||||
| 					{ | ||||
| 						if (it->second.human) | ||||
| 						if (it->second.playerID) | ||||
| 						{ | ||||
| 							faction = it->second.castle; | ||||
| 							break; | ||||
| @@ -3775,7 +3775,7 @@ void PlayerJoined::apply(CSelectionScreen *selScreen) | ||||
| 	//put new player in first slot with AI | ||||
| 	for(auto i = SEL->sInfo.playerInfos.begin(); i != SEL->sInfo.playerInfos.end(); i++) | ||||
| 	{ | ||||
| 		if(!i->second.human) | ||||
| 		if(!i->second.playerID) | ||||
| 		{ | ||||
| 			selScreen->setPlayer(i->second, connectionID); | ||||
| 			selScreen->opt->entries[i->second.color]->selectButtons(); | ||||
|   | ||||
| @@ -449,10 +449,10 @@ public: | ||||
|  | ||||
| 	void processPacks(); | ||||
| 	void setSInfo(const StartInfo &si); | ||||
| 	void update() OVERRIDE; | ||||
| 	void propagateOptions() OVERRIDE; | ||||
| 	void postRequest(ui8 what, ui8 dir) OVERRIDE; | ||||
| 	void postChatMessage(const std::string &txt) OVERRIDE; | ||||
| 	void update() override; | ||||
| 	void propagateOptions() override; | ||||
| 	void postRequest(ui8 what, ui8 dir) override; | ||||
| 	void postChatMessage(const std::string &txt) override; | ||||
| 	void propagateNames(); | ||||
| 	void showAll(SDL_Surface *to); | ||||
| }; | ||||
|   | ||||
| @@ -304,9 +304,9 @@ void CClient::newGame( CConnection *con, StartInfo *si ) | ||||
|  | ||||
| 	for(auto it = si->playerInfos.begin(); it != si->playerInfos.end(); ++it) | ||||
| 	{ | ||||
| 		if((networkMode == SINGLE)												//single - one client has all player | ||||
| 		   || (networkMode != SINGLE && serv->connectionID == it->second.human)	//multi - client has only "its players" | ||||
| 		   || (networkMode == HOST && it->second.human == false))				//multi - host has all AI players | ||||
| 		if((networkMode == SINGLE)                                                      //single - one client has all player | ||||
| 		   || (networkMode != SINGLE && serv->connectionID == it->second.playerID)      //multi - client has only "its players" | ||||
| 		   || (networkMode == HOST && it->second.playerID == PlayerSettings::PLAYER_AI))//multi - host has all AI players | ||||
| 		{ | ||||
| 			myPlayers.insert(it->first); //add player | ||||
| 		} | ||||
| @@ -368,7 +368,7 @@ void CClient::newGame( CConnection *con, StartInfo *si ) | ||||
| 		if(si->mode != StartInfo::DUEL) | ||||
| 		{ | ||||
| 			auto cb = make_shared<CCallback>(gs,color,this); | ||||
| 			if(!it->second.human)  | ||||
| 			if(it->second.playerID == PlayerSettings::PLAYER_AI) | ||||
| 			{ | ||||
| 				std::string AItoGive = settings["server"]["playerAI"].String(); | ||||
| 				if(!sensibleAILimit) | ||||
|   | ||||
| @@ -24,7 +24,6 @@ using namespace boost::assign; | ||||
|  */ | ||||
|  | ||||
| extern boost::rand48 ran; | ||||
| extern Bonus * ParseBonus (const JsonVector &ability_vec); | ||||
|  | ||||
| const std::string & CArtifact::Name() const | ||||
| { | ||||
| @@ -366,11 +365,11 @@ void CArtHandler::loadArtifacts(bool onlyTxt) | ||||
| 			auto ga = dynamic_cast <CGrowingArtifact *>(artifacts[artifact["id"].Float()].get()); | ||||
| 			BOOST_FOREACH (auto b, artifact["bonusesPerLevel"].Vector()) | ||||
| 			{ | ||||
| 				ga->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *ParseBonus (b["bonus"].Vector()))); | ||||
| 				ga->bonusesPerLevel.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector()))); | ||||
| 			} | ||||
| 			BOOST_FOREACH (auto b, artifact["thresholdBonuses"].Vector()) | ||||
| 			{ | ||||
| 				ga->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *ParseBonus (b["bonus"].Vector()))); | ||||
| 				ga->thresholdBonuses.push_back (std::pair <ui16, Bonus> (b["level"].Float(), *JsonUtils::parseBonus (b["bonus"].Vector()))); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| @@ -614,7 +613,7 @@ void CArtHandler::addBonuses() | ||||
| 		 | ||||
| 		BOOST_FOREACH (auto b, artifact["bonuses"].Vector()) | ||||
| 		{ | ||||
| 			ga->addNewBonus(ParseBonus (b)); | ||||
| 			ga->addNewBonus(JsonUtils::parseBonus (b)); | ||||
| 		} | ||||
| 		if(artifact["type"].String() == "Creature") | ||||
| 			makeItCreatureArt(ga->id); | ||||
|   | ||||
| @@ -59,7 +59,7 @@ void SettingsStorage::init() | ||||
| { | ||||
| 	JsonNode(ResourceID("config/settings.json")).swap(config); | ||||
| 	JsonNode schema(ResourceID("config/defaultSettings.json")); | ||||
| 	config.validate(schema); | ||||
| 	JsonUtils::validate(config, schema); | ||||
| } | ||||
|  | ||||
| void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath) | ||||
| @@ -71,7 +71,7 @@ void SettingsStorage::invalidateNode(const std::vector<std::string> &changedPath | ||||
| 	JsonNode schema(ResourceID("config/defaultSettings.json")); | ||||
|  | ||||
| 	savedConf.Struct().erase("session"); | ||||
| 	savedConf.minimize(schema); | ||||
| 	JsonUtils::minimize(savedConf, schema); | ||||
|  | ||||
| 	CResourceHandler::get()->createResource("CONFIG/settings.json"); | ||||
|  | ||||
|   | ||||
| @@ -500,7 +500,7 @@ void CCreatureHandler::loadCreatures() | ||||
| 	} | ||||
| 	BOOST_FOREACH (auto bonus, config3["bonusPerLevel"].Vector()) | ||||
| 	{ | ||||
| 		commanderLevelPremy.push_back(ParseBonus (bonus.Vector())); | ||||
| 		commanderLevelPremy.push_back(JsonUtils::parseBonus (bonus.Vector())); | ||||
| 	} | ||||
|  | ||||
| 	int i = 0; | ||||
| @@ -517,7 +517,7 @@ void CCreatureHandler::loadCreatures() | ||||
| 	BOOST_FOREACH (auto ability, config3["abilityRequirements"].Vector()) | ||||
| 	{ | ||||
| 		std::pair <Bonus, std::pair <ui8, ui8> > a; | ||||
| 		a.first = *ParseBonus (ability["ability"].Vector()); | ||||
| 		a.first = *JsonUtils::parseBonus (ability["ability"].Vector()); | ||||
| 		a.second.first = ability["skills"].Vector()[0].Float(); | ||||
| 		a.second.second = ability["skills"].Vector()[1].Float(); | ||||
| 		skillRequirements.push_back (a); | ||||
| @@ -674,7 +674,7 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node) | ||||
|  | ||||
| 	BOOST_FOREACH (const JsonNode &bonus, node["abilities"].Vector()) | ||||
| 	{ | ||||
| 		auto b = ParseBonus(bonus); | ||||
| 		auto b = JsonUtils::parseBonus(bonus); | ||||
| 		b->source = Bonus::CREATURE_ABILITY; | ||||
| 		b->duration = Bonus::PERMANENT; | ||||
| 		cre->addNewBonus(b); | ||||
| @@ -682,7 +682,7 @@ CCreature * CCreatureHandler::loadCreature(const JsonNode & node) | ||||
|  | ||||
| 	BOOST_FOREACH (const JsonNode &exp, node["stackExperience"].Vector()) | ||||
| 	{ | ||||
| 		auto bonus = ParseBonus (exp["bonus"]); | ||||
| 		auto bonus = JsonUtils::parseBonus (exp["bonus"]); | ||||
| 		bonus->source = Bonus::STACK_EXPERIENCE; | ||||
| 		bonus->duration = Bonus::PERMANENT; | ||||
| 		const JsonVector &values = exp["values"].Vector(); | ||||
|   | ||||
| @@ -841,7 +841,7 @@ void CGameState::init(StartInfo * si) | ||||
| 		for(auto it = scenarioOps->playerInfos.cbegin(); | ||||
| 			it != scenarioOps->playerInfos.cend(); ++it) | ||||
| 		{ | ||||
| 			if(it->second.human) | ||||
| 			if(it->second.playerID != PlayerSettings::PLAYER_AI) | ||||
| 				ret.push_back(&it->second); | ||||
| 		} | ||||
|  | ||||
| @@ -996,7 +996,7 @@ void CGameState::init(StartInfo * si) | ||||
| 	{ | ||||
| 		std::pair<TPlayerColor,PlayerState> ins(it->first,PlayerState()); | ||||
| 		ins.second.color=ins.first; | ||||
| 		ins.second.human = it->second.human; | ||||
| 		ins.second.human = it->second.playerID; | ||||
| 		ins.second.team = map->players[ins.first].team; | ||||
| 		teams[ins.second.team].id = ins.second.team;//init team | ||||
| 		teams[ins.second.team].players.insert(ins.first);//add player to team | ||||
| @@ -1021,7 +1021,8 @@ void CGameState::init(StartInfo * si) | ||||
| 		for(auto it = scenarioOps->playerInfos.begin(); it != scenarioOps->playerInfos.end(); ++it) | ||||
| 		{ | ||||
| 			const PlayerInfo &p = map->players[it->first]; | ||||
| 			bool generateHero = (p.generateHeroAtMainTown || (it->second.human && campaignGiveHero)) && p.hasMainTown; | ||||
| 			bool generateHero = (p.generateHeroAtMainTown || | ||||
| 			                     (it->second.playerID != PlayerSettings::PLAYER_AI && campaignGiveHero)) && p.hasMainTown; | ||||
| 			if(generateHero && vstd::contains(scenarioOps->playerInfos, it->first)) | ||||
| 			{ | ||||
| 				int3 hpos = p.posOfMainTown; | ||||
| @@ -1041,7 +1042,6 @@ void CGameState::init(StartInfo * si) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
|  | ||||
| 	/*************************replace hero placeholders*****************************/ | ||||
| 	tlog4 << "\tReplacing hero placeholders"; | ||||
| 	if (scenarioOps->campState) | ||||
| @@ -1301,14 +1301,14 @@ void CGameState::init(StartInfo * si) | ||||
| 	for(auto k=players.begin(); k!=players.end(); ++k) | ||||
| 	{ | ||||
| 		//starting bonus | ||||
| 		if(scenarioOps->playerInfos[k->first].bonus==PlayerSettings::brandom) | ||||
| 		if(scenarioOps->playerInfos[k->first].bonus==PlayerSettings::RANDOM) | ||||
| 			scenarioOps->playerInfos[k->first].bonus = ran()%3; | ||||
| 		switch(scenarioOps->playerInfos[k->first].bonus) | ||||
| 		{ | ||||
| 		case PlayerSettings::bgold: | ||||
| 		case PlayerSettings::GOLD: | ||||
| 			k->second.resources[Res::GOLD] += 500 + (ran()%6)*100; | ||||
| 			break; | ||||
| 		case PlayerSettings::bresource: | ||||
| 		case PlayerSettings::RESOURCE: | ||||
| 			{ | ||||
| 				int res = VLC->townh->towns[scenarioOps->playerInfos[k->first].castle].primaryRes; | ||||
| 				if(res == 127) | ||||
| @@ -1322,7 +1322,7 @@ void CGameState::init(StartInfo * si) | ||||
| 				} | ||||
| 				break; | ||||
| 			} | ||||
| 		case PlayerSettings::bartifact: | ||||
| 		case PlayerSettings::ARTIFACT: | ||||
| 			{ | ||||
|  				if(!k->second.heroes.size()) | ||||
| 				{ | ||||
|   | ||||
| @@ -106,9 +106,9 @@ void CHeroHandler::loadObstacles() | ||||
| 			obi.defName = obs["defname"].String(); | ||||
| 			obi.width = obs["width"].Float(); | ||||
| 			obi.height = obs["height"].Float(); | ||||
| 			obi.allowedTerrains = obs["allowedTerrain"].StdVector<ui8>(); | ||||
| 			obi.allowedSpecialBfields = obs["specialBattlefields"].StdVector<ui8>(); | ||||
| 			obi.blockedTiles = obs["blockedTiles"].StdVector<si16>(); | ||||
| 			obi.allowedTerrains = obs["allowedTerrain"].convertTo<std::vector<ui8> >(); | ||||
| 			obi.allowedSpecialBfields = obs["specialBattlefields"].convertTo<std::vector<ui8> >(); | ||||
| 			obi.blockedTiles = obs["blockedTiles"].convertTo<std::vector<si16> >(); | ||||
| 			obi.isAbsoluteObstacle = absolute; | ||||
| 		} | ||||
| 	}; | ||||
|   | ||||
| @@ -5363,7 +5363,7 @@ void CGEvent::onHeroVisit( const CGHeroInstance * h ) const | ||||
| { | ||||
| 	if(!(availableFor & (1 << h->tempOwner))) | ||||
| 		return; | ||||
| 	if(cb->getPlayerSettings(h->tempOwner)->human) | ||||
| 	if(cb->getPlayerSettings(h->tempOwner)->playerID) | ||||
| 	{ | ||||
| 		if(humanActivate) | ||||
| 			activated(h); | ||||
|   | ||||
| @@ -364,7 +364,7 @@ void CSpellHandler::loadSpells() | ||||
| 		BOOST_FOREACH(const JsonNode &range, spell["ranges"].Vector()) | ||||
| 			s->range[idx++] = range.String(); | ||||
|  | ||||
| 		s->counteredSpells = spell["counters"].StdVector<TSpell>(); | ||||
| 		s->counteredSpells = spell["counters"].convertTo<std::vector<TSpell> >(); | ||||
| 	} | ||||
| 	//spell fixes | ||||
|  | ||||
|   | ||||
| @@ -394,7 +394,7 @@ void CTownHandler::loadTown(CTown &town, const JsonNode & source) | ||||
| 	town.mageLevel = source["mageGuild"].Float(); | ||||
| 	town.primaryRes  = source["primaryResource"].Float(); | ||||
| 	town.warMachine = source["warMachine"].Float(); | ||||
| 	town.names = source["names"].StdVector<std::string>(); | ||||
| 	town.names = source["names"].convertTo<std::vector<std::string> >(); | ||||
|  | ||||
| 	//  Horde building creature level | ||||
| 	BOOST_FOREACH(const JsonNode &node, source["horde"].Vector()) | ||||
| @@ -515,7 +515,7 @@ void CTownHandler::load() | ||||
| 					JsonNode & legacyBuilding = legacyBuildings[building["id"].Float()]; | ||||
|  | ||||
| 					if (!legacyBuilding.isNull()) //merge if h3 config was found for this building | ||||
| 						JsonNode::merge(building, legacyBuilding); | ||||
| 						JsonUtils::merge(building, legacyBuilding); | ||||
| 				} | ||||
| 			} | ||||
| 		} | ||||
| @@ -523,12 +523,12 @@ void CTownHandler::load() | ||||
| 	load(buildingsConf); | ||||
| } | ||||
|  | ||||
| std::set<ui32> CTownHandler::getDefaultAllowedFactions() const | ||||
| std::set<TFaction> CTownHandler::getDefaultAllowedFactions() const | ||||
| { | ||||
| 	std::set<ui32> allowedFactions; | ||||
| 	for(int i = 0; i <= 8; ++i) | ||||
| 	std::set<TFaction> allowedFactions; | ||||
| 	BOOST_FOREACH(auto town, towns) | ||||
| 	{ | ||||
| 		allowedFactions.insert(i); | ||||
| 		allowedFactions.insert(town.first); | ||||
| 	} | ||||
| 	return allowedFactions; | ||||
| } | ||||
|   | ||||
| @@ -225,7 +225,7 @@ public: | ||||
| 	 * | ||||
| 	 * @return a list of allowed factions, the index which is unique is the faction id | ||||
| 	 */ | ||||
| 	std::set<ui32> getDefaultAllowedFactions() const; | ||||
| 	std::set<TFaction> getDefaultAllowedFactions() const; | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
|   | ||||
							
								
								
									
										100
									
								
								lib/JsonNode.cpp
									
									
									
									
									
								
							
							
						
						
									
										100
									
								
								lib/JsonNode.cpp
									
									
									
									
									
								
							| @@ -4,7 +4,9 @@ | ||||
| #include "HeroBonus.h" | ||||
| #include "Filesystem/CResourceLoader.h" | ||||
|  | ||||
| const JsonNode JsonNode::nullNode; | ||||
| using namespace JsonDetail; | ||||
|  | ||||
| static const JsonNode nullNode; | ||||
|  | ||||
| JsonNode::JsonNode(JsonType Type): | ||||
| 	type(DATA_NULL) | ||||
| @@ -99,16 +101,6 @@ bool JsonNode::operator != (const JsonNode &other) const | ||||
| 	return !(*this == other); | ||||
| } | ||||
|  | ||||
| void JsonNode::minimize(const JsonNode& schema) | ||||
| { | ||||
| 	JsonValidator validator(*this, schema, true); | ||||
| } | ||||
|  | ||||
| void JsonNode::validate(const JsonNode& schema) | ||||
| { | ||||
| 	JsonValidator validator(*this, schema, false); | ||||
| } | ||||
|  | ||||
| JsonNode::JsonType JsonNode::getType() const | ||||
| { | ||||
| 	return type; | ||||
| @@ -238,39 +230,6 @@ const JsonNode & JsonNode::operator[](std::string child) const | ||||
| } | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| void JsonNode::merge(JsonNode & dest, JsonNode & source) | ||||
| { | ||||
| 	switch (source.getType()) | ||||
| 	{ | ||||
| 		break; case DATA_NULL:   dest.setType(DATA_NULL); | ||||
| 		break; case DATA_BOOL:   std::swap(dest.Bool(), source.Bool()); | ||||
| 		break; case DATA_FLOAT:  std::swap(dest.Float(), source.Float()); | ||||
| 		break; case DATA_STRING: std::swap(dest.String(), source.String()); | ||||
| 		break; case DATA_VECTOR: | ||||
| 		{ | ||||
| 			//reserve place and *move* data from source to dest | ||||
| 			source.Vector().reserve(source.Vector().size() + dest.Vector().size()); | ||||
|  | ||||
| 			std::move(source.Vector().begin(), source.Vector().end(), | ||||
| 			          std::back_inserter(dest.Vector())); | ||||
| 		} | ||||
| 		break; case DATA_STRUCT: | ||||
| 		{ | ||||
| 			//recursively merge all entries from struct | ||||
| 			BOOST_FOREACH(auto & node, source.Struct()) | ||||
| 				merge(dest[node.first], node.second); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonNode::mergeCopy(JsonNode & dest, JsonNode source) | ||||
| { | ||||
| 	// uses copy created in stack to safely merge two nodes | ||||
| 	merge(dest, source); | ||||
| } | ||||
|  | ||||
| //////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| template<typename Iterator> | ||||
| void JsonWriter::writeContainer(Iterator begin, Iterator end) | ||||
| { | ||||
| @@ -830,7 +789,7 @@ bool JsonValidator::validateProperties(JsonNode &node, const JsonNode &schema) | ||||
| 	{ | ||||
| 		if (nodeIter->first < schemaIter->first) //No schema for entry | ||||
| 		{ | ||||
| 			validateNode(nodeIter->second, JsonNode::nullNode, nodeIter->first); | ||||
| 			validateNode(nodeIter->second, nullNode, nodeIter->first); | ||||
|  | ||||
| 			JsonMap::iterator toRemove = nodeIter++; | ||||
| 			node.Struct().erase(toRemove); | ||||
| @@ -853,7 +812,7 @@ bool JsonValidator::validateProperties(JsonNode &node, const JsonNode &schema) | ||||
| 	} | ||||
| 	while (nodeIter != node.Struct().end()) | ||||
| 	{ | ||||
| 		validateNode(nodeIter->second, JsonNode::nullNode, nodeIter->first); | ||||
| 		validateNode(nodeIter->second, nullNode, nodeIter->first); | ||||
| 		JsonMap::iterator toRemove = nodeIter++; | ||||
| 		node.Struct().erase(toRemove); | ||||
| 	} | ||||
| @@ -910,7 +869,7 @@ JsonValidator::JsonValidator(JsonNode &root, const JsonNode &schema, bool Minimi | ||||
| 	tlog3<<errors; | ||||
| } | ||||
|  | ||||
| Bonus * ParseBonus (const JsonVector &ability_vec) //TODO: merge with AddAbility, create universal parser for all bonus properties | ||||
| Bonus * JsonUtils::parseBonus (const JsonVector &ability_vec) //TODO: merge with AddAbility, create universal parser for all bonus properties | ||||
| { | ||||
| 	Bonus * b = new Bonus(); | ||||
| 	std::string type = ability_vec[0].String(); | ||||
| @@ -950,7 +909,7 @@ const T & parseByMap(const std::map<std::string, T> & map, const JsonNode * val, | ||||
| 		return defaultValue; | ||||
| }; | ||||
|  | ||||
| Bonus * ParseBonus (const JsonNode &ability) | ||||
| Bonus * JsonUtils::parseBonus (const JsonNode &ability) | ||||
| { | ||||
|  | ||||
| 	Bonus * b = new Bonus(); | ||||
| @@ -1029,7 +988,7 @@ Key reverseMapFirst(const Val & val, const std::map<Key, Val> map) | ||||
| 	return ""; | ||||
| } | ||||
|  | ||||
| DLL_LINKAGE void UnparseBonus( JsonNode &node, const Bonus * bonus ) | ||||
| void JsonUtils::unparseBonus( JsonNode &node, const Bonus * bonus ) | ||||
| { | ||||
| 	node["type"].String() = reverseMapFirst<std::string, int>(bonus->type, bonusNameMap); | ||||
| 	node["subtype"].Float() = bonus->subtype; | ||||
| @@ -1050,6 +1009,45 @@ DLL_LINKAGE void UnparseBonus( JsonNode &node, const Bonus * bonus ) | ||||
| 	{ | ||||
| 		node["propagator"].String() = reverseMapFirst<std::string, TPropagatorPtr>(bonus->propagator, bonusPropagatorMap); | ||||
| 	} | ||||
| 	 | ||||
| 	 | ||||
| } | ||||
|  | ||||
| void JsonUtils::minimize(JsonNode & node, const JsonNode& schema) | ||||
| { | ||||
| 	JsonValidator validator(node, schema, true); | ||||
| } | ||||
|  | ||||
| void JsonUtils::validate(JsonNode & node, const JsonNode& schema) | ||||
| { | ||||
| 	JsonValidator validator(node, schema, false); | ||||
| } | ||||
|  | ||||
| void JsonUtils::merge(JsonNode & dest, JsonNode & source) | ||||
| { | ||||
| 	switch (source.getType()) | ||||
| 	{ | ||||
| 		break; case JsonNode::DATA_NULL:   dest.setType(JsonNode::DATA_NULL); | ||||
| 		break; case JsonNode::DATA_BOOL:   std::swap(dest.Bool(), source.Bool()); | ||||
| 		break; case JsonNode::DATA_FLOAT:  std::swap(dest.Float(), source.Float()); | ||||
| 		break; case JsonNode::DATA_STRING: std::swap(dest.String(), source.String()); | ||||
| 		break; case JsonNode::DATA_VECTOR: | ||||
| 		{ | ||||
| 			//reserve place and *move* data from source to dest | ||||
| 			source.Vector().reserve(source.Vector().size() + dest.Vector().size()); | ||||
|  | ||||
| 			std::move(source.Vector().begin(), source.Vector().end(), | ||||
| 			          std::back_inserter(dest.Vector())); | ||||
| 		} | ||||
| 		break; case JsonNode::DATA_STRUCT: | ||||
| 		{ | ||||
| 			//recursively merge all entries from struct | ||||
| 			BOOST_FOREACH(auto & node, source.Struct()) | ||||
| 				merge(dest[node.first], node.second); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void JsonUtils::mergeCopy(JsonNode & dest, JsonNode source) | ||||
| { | ||||
| 	// uses copy created in stack to safely merge two nodes | ||||
| 	merge(dest, source); | ||||
| } | ||||
							
								
								
									
										329
									
								
								lib/JsonNode.h
									
									
									
									
									
								
							
							
						
						
									
										329
									
								
								lib/JsonNode.h
									
									
									
									
									
								
							| @@ -53,11 +53,6 @@ public: | ||||
| 	bool operator == (const JsonNode &other) const; | ||||
| 	bool operator != (const JsonNode &other) const; | ||||
|  | ||||
| 	//removes all nodes that are identical to default entry in schema | ||||
| 	void minimize(const JsonNode& schema); | ||||
| 	//check schema | ||||
| 	void validate(const JsonNode& schema); | ||||
|  | ||||
| 	//Convert node to another type. Converting to NULL will clear all data | ||||
| 	void setType(JsonType Type); | ||||
| 	JsonType getType() const; | ||||
| @@ -78,29 +73,19 @@ public: | ||||
| 	const JsonVector & Vector() const; | ||||
| 	const JsonMap & Struct() const; | ||||
|  | ||||
| 	template<typename T> | ||||
| 	std::vector<T> StdVector() const; | ||||
| 	/// convert json tree into specified type. Json tree must have same type as Type | ||||
| 	/// Valid types: bool, string, any numeric, map and vector | ||||
| 	/// example: convertTo< std::map< std::vector<int> > >(); | ||||
| 	template<typename Type> | ||||
| 	Type convertTo() const; | ||||
|  | ||||
| 	//operator [], for structs only - get child node by name | ||||
| 	JsonNode & operator[](std::string child); | ||||
| 	const JsonNode & operator[](std::string child) const; | ||||
|  | ||||
| 	//error value for const operator[] | ||||
| 	static const JsonNode nullNode; | ||||
|  | ||||
| 	/// recursivly merges source into dest, replacing identical fields | ||||
| 	/// struct : recursively calls this function | ||||
| 	/// arrays : append array in dest with data from source | ||||
| 	/// values : value in source will replace value in dest | ||||
| 	/// null   : if value in source is present but set to null it will delete entry in dest | ||||
|  | ||||
| 	/// this function will destroy data in source | ||||
| 	static void merge(JsonNode & dest, JsonNode & source); | ||||
| 	/// this function will preserve data stored in source by creating copy | ||||
| 	static void mergeCopy(JsonNode & dest, JsonNode source); | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		// simple saving - save json in its string interpretation | ||||
| 		if (h.saving) | ||||
| 		{ | ||||
| 			std::ostringstream stream; | ||||
| @@ -117,129 +102,199 @@ public: | ||||
| 	} | ||||
| }; | ||||
|  | ||||
| template<> | ||||
| inline std::vector<std::string> JsonNode::StdVector() const | ||||
| namespace JsonUtils | ||||
| { | ||||
| 	std::vector<std::string> ret; | ||||
| 	BOOST_FOREACH(const JsonNode &node, Vector()) | ||||
| 	{ | ||||
| 		ret.push_back(node.String()); | ||||
| 	} | ||||
| 	return ret; | ||||
| 	DLL_LINKAGE Bonus * parseBonus (const JsonVector &ability_vec); | ||||
| 	DLL_LINKAGE Bonus * parseBonus (const JsonNode &bonus); | ||||
| 	DLL_LINKAGE void unparseBonus (JsonNode &node, const Bonus * bonus); | ||||
|  | ||||
| 	/// recursivly merges source into dest, replacing identical fields | ||||
| 	/// struct : recursively calls this function | ||||
| 	/// arrays : append array in dest with data from source | ||||
| 	/// values : value in source will replace value in dest | ||||
| 	/// null   : if value in source is present but set to null it will delete entry in dest | ||||
|  | ||||
| 	/// this function will destroy data in source | ||||
| 	DLL_LINKAGE void merge(JsonNode & dest, JsonNode & source); | ||||
| 	/// this function will preserve data stored in source by creating copy | ||||
| 	DLL_LINKAGE void mergeCopy(JsonNode & dest, JsonNode source); | ||||
|  | ||||
| 	/// removes all nodes that are identical to default entry in schema | ||||
| 	DLL_LINKAGE void minimize(JsonNode & node, const JsonNode& schema); | ||||
|  | ||||
| 	/// check schema | ||||
| 	DLL_LINKAGE void validate(JsonNode & node, const JsonNode& schema); | ||||
| } | ||||
|  | ||||
| template<typename T> | ||||
| std::vector<T> JsonNode::StdVector() const | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
| // End of public section of the file. Anything below should be only used internally in JsonNode.cpp // | ||||
| ////////////////////////////////////////////////////////////////////////////////////////////////////// | ||||
|  | ||||
| namespace JsonDetail | ||||
| { | ||||
| 	static_assert(std::is_arithmetic<T>::value, "This works with numbers only."); | ||||
| 	std::vector<T> ret; | ||||
| 	BOOST_FOREACH(const JsonNode &node, Vector()) | ||||
| 	// convertion helpers for JsonNode::convertTo (partial template function instantiation is illegal in c++) | ||||
| 	template<typename Type> | ||||
| 	struct JsonConverter | ||||
| 	{ | ||||
| 		ret.push_back(node.Float()); | ||||
| 	} | ||||
| 	return ret; | ||||
| } | ||||
|  | ||||
| class JsonWriter | ||||
| { | ||||
| 	//prefix for each line (tabulation) | ||||
| 	std::string prefix; | ||||
| 	std::ostream &out; | ||||
| public: | ||||
| 	template<typename Iterator> | ||||
| 	void writeContainer(Iterator begin, Iterator end); | ||||
| 	void writeEntry(JsonMap::const_iterator entry); | ||||
| 	void writeEntry(JsonVector::const_iterator entry); | ||||
| 	void writeString(const std::string &string); | ||||
| 	void writeNode(const JsonNode &node); | ||||
| 	JsonWriter(std::ostream &output, const JsonNode &node); | ||||
| }; | ||||
|  | ||||
| //Tiny string class that uses const char* as data for speed, members are private | ||||
| //for ease of debugging and some compatibility with std::string | ||||
| class constString | ||||
| { | ||||
| 	const char *data; | ||||
| 	const size_t datasize; | ||||
|  | ||||
| public: | ||||
| 	constString(const char * inputString, size_t stringSize): | ||||
| 		data(inputString), | ||||
| 		datasize(stringSize) | ||||
| 	{ | ||||
| 	} | ||||
|  | ||||
| 	inline size_t size() const | ||||
| 	{ | ||||
| 		return datasize; | ||||
| 		static Type convert(const JsonNode & node) | ||||
| 		{ | ||||
| 			///this should be triggered only for numeric types | ||||
| 			static_assert(std::is_arithmetic<Type>::value, "Unsupported type for JsonNode::convertTo()!"); | ||||
| 			return node.Float(); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	inline const char& operator[] (size_t position) | ||||
| 	template<typename Type> | ||||
| 	struct JsonConverter<std::map<std::string, Type> > | ||||
| 	{ | ||||
| 		assert (position < datasize); | ||||
| 		return data[position]; | ||||
| 	} | ||||
| }; | ||||
| 		static std::map<std::string, Type> convert(const JsonNode & node) | ||||
| 		{ | ||||
| 			std::map<std::string, Type> ret; | ||||
| 			BOOST_FOREACH(auto entry, node.Struct()) | ||||
| 			{ | ||||
| 				ret.insert(entry.first, entry.second.convertTo<Type>()); | ||||
| 			} | ||||
| 			return ret; | ||||
|  | ||||
| //Internal class for string -> JsonNode conversion | ||||
| class JsonParser | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	template<typename Type> | ||||
| 	struct JsonConverter<std::vector<Type> > | ||||
| 	{ | ||||
| 		static std::vector<Type> convert(const JsonNode & node) | ||||
| 		{ | ||||
| 			std::vector<Type> ret; | ||||
| 			BOOST_FOREACH(auto entry, node.Vector()) | ||||
| 			{ | ||||
| 				ret.push_back(entry.convertTo<Type>()); | ||||
| 			} | ||||
| 			return ret; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	struct JsonConverter<std::string> | ||||
| 	{ | ||||
| 		static std::string convert(const JsonNode & node) | ||||
| 		{ | ||||
| 			return node.String(); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	template<> | ||||
| 	struct JsonConverter<bool> | ||||
| 	{ | ||||
| 		static bool convert(const JsonNode & node) | ||||
| 		{ | ||||
| 			return node.Bool(); | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	class JsonWriter | ||||
| 	{ | ||||
| 		//prefix for each line (tabulation) | ||||
| 		std::string prefix; | ||||
| 		std::ostream &out; | ||||
| 	public: | ||||
| 		template<typename Iterator> | ||||
| 		void writeContainer(Iterator begin, Iterator end); | ||||
| 		void writeEntry(JsonMap::const_iterator entry); | ||||
| 		void writeEntry(JsonVector::const_iterator entry); | ||||
| 		void writeString(const std::string &string); | ||||
| 		void writeNode(const JsonNode &node); | ||||
| 		JsonWriter(std::ostream &output, const JsonNode &node); | ||||
| 	}; | ||||
|  | ||||
| 	//Tiny string class that uses const char* as data for speed, members are private | ||||
| 	//for ease of debugging and some compatibility with std::string | ||||
| 	class constString | ||||
| 	{ | ||||
| 		const char *data; | ||||
| 		const size_t datasize; | ||||
|  | ||||
| 	public: | ||||
| 		constString(const char * inputString, size_t stringSize): | ||||
| 			data(inputString), | ||||
| 			datasize(stringSize) | ||||
| 		{ | ||||
| 		} | ||||
|  | ||||
| 		inline size_t size() const | ||||
| 		{ | ||||
| 			return datasize; | ||||
| 		}; | ||||
|  | ||||
| 		inline const char& operator[] (size_t position) | ||||
| 		{ | ||||
| 			assert (position < datasize); | ||||
| 			return data[position]; | ||||
| 		} | ||||
| 	}; | ||||
|  | ||||
| 	//Internal class for string -> JsonNode conversion | ||||
| 	class JsonParser | ||||
| 	{ | ||||
| 		std::string errors;     // Contains description of all encountered errors | ||||
| 		constString input;      // Input data | ||||
| 		ui32 lineCount; // Currently parsed line, starting from 1 | ||||
| 		size_t lineStart;       // Position of current line start | ||||
| 		size_t pos;             // Current position of parser | ||||
|  | ||||
| 		//Helpers | ||||
| 		bool extractEscaping(std::string &str); | ||||
| 		bool extractLiteral(const std::string &literal); | ||||
| 		bool extractString(std::string &string); | ||||
| 		bool extractWhitespace(bool verbose = true); | ||||
| 		bool extractSeparator(); | ||||
| 		bool extractElement(JsonNode &node, char terminator); | ||||
|  | ||||
| 		//Methods for extracting JSON data | ||||
| 		bool extractArray(JsonNode &node); | ||||
| 		bool extractFalse(JsonNode &node); | ||||
| 		bool extractFloat(JsonNode &node); | ||||
| 		bool extractNull(JsonNode &node); | ||||
| 		bool extractString(JsonNode &node); | ||||
| 		bool extractStruct(JsonNode &node); | ||||
| 		bool extractTrue(JsonNode &node); | ||||
| 		bool extractValue(JsonNode &node); | ||||
|  | ||||
| 		//Add error\warning message to list | ||||
| 		bool error(const std::string &message, bool warning=false); | ||||
|  | ||||
| 	public: | ||||
| 		JsonParser(const char * inputString, size_t stringSize, JsonNode &root); | ||||
| 	}; | ||||
|  | ||||
| 	//Internal class for Json validation, used automaticaly in JsonNode constructor. Behaviour: | ||||
| 	// - "schema" entry from root node is used for validation and will be removed | ||||
| 	// - any missing entries will be replaced with default value from schema (if present) | ||||
| 	// - if entry uses different type than defined in schema it will be removed | ||||
| 	// - entries nod described in schema will be kept unchanged | ||||
| 	class JsonValidator | ||||
| 	{ | ||||
| 		std::string errors;     // Contains description of all encountered errors | ||||
| 		std::list<std::string> currentPath; // path from root node to current one | ||||
| 		bool minimize; | ||||
|  | ||||
| 		bool validateType(JsonNode &node, const JsonNode &schema, JsonNode::JsonType type); | ||||
| 		bool validateSchema(JsonNode::JsonType &type, const JsonNode &schema); | ||||
| 		bool validateNode(JsonNode &node, const JsonNode &schema, const std::string &name); | ||||
| 		bool validateItems(JsonNode &node, const JsonNode &schema); | ||||
| 		bool validateProperties(JsonNode &node, const JsonNode &schema); | ||||
|  | ||||
| 		bool addMessage(const std::string &message); | ||||
| 	public: | ||||
| 		// validate node with "schema" entry | ||||
| 		JsonValidator(JsonNode &root, bool minimize=false); | ||||
| 		// validate with external schema | ||||
| 		JsonValidator(JsonNode &root, const JsonNode &schema, bool minimize=false); | ||||
| 	}; | ||||
|  | ||||
| } // namespace JsonDetail | ||||
|  | ||||
| template<typename Type> | ||||
| Type JsonNode::convertTo() const | ||||
| { | ||||
| 	std::string errors;     // Contains description of all encountered errors | ||||
| 	constString input;      // Input data | ||||
| 	ui32 lineCount; // Currently parsed line, starting from 1 | ||||
| 	size_t lineStart;       // Position of current line start | ||||
| 	size_t pos;             // Current position of parser | ||||
|  | ||||
| 	//Helpers | ||||
| 	bool extractEscaping(std::string &str); | ||||
| 	bool extractLiteral(const std::string &literal); | ||||
| 	bool extractString(std::string &string); | ||||
| 	bool extractWhitespace(bool verbose = true); | ||||
| 	bool extractSeparator(); | ||||
| 	bool extractElement(JsonNode &node, char terminator); | ||||
|  | ||||
| 	//Methods for extracting JSON data | ||||
| 	bool extractArray(JsonNode &node); | ||||
| 	bool extractFalse(JsonNode &node); | ||||
| 	bool extractFloat(JsonNode &node); | ||||
| 	bool extractNull(JsonNode &node); | ||||
| 	bool extractString(JsonNode &node); | ||||
| 	bool extractStruct(JsonNode &node); | ||||
| 	bool extractTrue(JsonNode &node); | ||||
| 	bool extractValue(JsonNode &node); | ||||
|  | ||||
| 	//Add error\warning message to list | ||||
| 	bool error(const std::string &message, bool warning=false); | ||||
|  | ||||
| public: | ||||
| 	JsonParser(const char * inputString, size_t stringSize, JsonNode &root); | ||||
| }; | ||||
|  | ||||
| //Internal class for Json validation, used automaticaly in JsonNode constructor. Behaviour: | ||||
| // - "schema" entry from root node is used for validation and will be removed | ||||
| // - any missing entries will be replaced with default value from schema (if present) | ||||
| // - if entry uses different type than defined in schema it will be removed | ||||
| // - entries nod described in schema will be kept unchanged | ||||
| class JsonValidator | ||||
| { | ||||
| 	std::string errors;     // Contains description of all encountered errors | ||||
| 	std::list<std::string> currentPath; // path from root node to current one | ||||
| 	bool minimize; | ||||
|  | ||||
| 	bool validateType(JsonNode &node, const JsonNode &schema, JsonNode::JsonType type); | ||||
| 	bool validateSchema(JsonNode::JsonType &type, const JsonNode &schema); | ||||
| 	bool validateNode(JsonNode &node, const JsonNode &schema, const std::string &name); | ||||
| 	bool validateItems(JsonNode &node, const JsonNode &schema); | ||||
| 	bool validateProperties(JsonNode &node, const JsonNode &schema); | ||||
|  | ||||
| 	bool addMessage(const std::string &message); | ||||
| public: | ||||
| 	// validate node with "schema" entry | ||||
| 	JsonValidator(JsonNode &root, bool minimize=false); | ||||
| 	// validate with external schema | ||||
| 	JsonValidator(JsonNode &root, const JsonNode &schema, bool minimize=false); | ||||
| }; | ||||
|  | ||||
| DLL_LINKAGE Bonus * ParseBonus (const JsonVector &ability_vec); | ||||
| DLL_LINKAGE Bonus * ParseBonus (const JsonNode &bonus); | ||||
| DLL_LINKAGE void UnparseBonus (JsonNode &node, const Bonus * bonus); | ||||
| 	return JsonDetail::JsonConverter<Type>::convert(*this); | ||||
| } | ||||
| @@ -102,7 +102,7 @@ struct DLL_LINKAGE PlayerInfo | ||||
| 	EAiTactic::EAiTactic aiTactic; | ||||
|  | ||||
| 	/** A list of unique IDs of allowed factions. */ | ||||
| 	std::set<ui32> allowedFactions; | ||||
| 	std::set<TFaction> allowedFactions; | ||||
|  | ||||
| 	/** Unused. True if the faction should be chosen randomly. */ | ||||
| 	bool isFactionRandom; | ||||
|   | ||||
| @@ -25,7 +25,7 @@ void CMapInfo::countPlayers() | ||||
|  | ||||
| 	if(scenarioOpts) | ||||
| 		for (auto i = scenarioOpts->playerInfos.cbegin(); i != scenarioOpts->playerInfos.cend(); i++) | ||||
| 			if(i->second.human) | ||||
| 			if(i->second.playerID != PlayerSettings::PLAYER_AI) | ||||
| 				actualHumanPlayers++; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -19,19 +19,31 @@ class CCampaignState; | ||||
| /// Struct which describes the name, the color, the starting bonus of a player | ||||
| struct PlayerSettings | ||||
| { | ||||
| 	enum Ebonus {brandom=-1,bartifact, bgold, bresource}; | ||||
| 	enum { PLAYER_AI = 0 }; // for use in playerID | ||||
|  | ||||
| 	enum Ebonus { | ||||
| 		NONE     = -2, | ||||
| 		RANDOM   = -1, | ||||
| 		ARTIFACT =  0, | ||||
| 		GOLD     =  1, | ||||
| 		RESOURCE =  2 | ||||
| 	}; | ||||
|  | ||||
| 	//uses enum type Ebonus | ||||
| 	si8 bonus; | ||||
| 	si16 castle; | ||||
| 	si32 hero, | ||||
| 	     heroPortrait; //-1 if default, else ID | ||||
|  | ||||
| 	si32 castle, hero,  //ID, if -1 then random, if -2 then none | ||||
| 		heroPortrait; //-1 if default, else ID | ||||
| 	std::string heroName; | ||||
| 	si8 bonus; //uses enum type Ebonus | ||||
| 	TPlayerColor color; //from 0 -  | ||||
| 	ui8 handicap;//0-no, 1-mild, 2-severe | ||||
| 	ui8 team; | ||||
|  | ||||
| 	std::string name; | ||||
| 	ui8 human; //0 - AI, non-0 serves as player id | ||||
| 	template <typename Handler> 	void serialize(Handler &h, const int version) | ||||
| 	ui8 playerID; //0 - AI, non-0 serves as player id | ||||
| 	template <typename Handler> | ||||
| 	void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & castle; | ||||
| 		h & hero; | ||||
| @@ -41,13 +53,13 @@ struct PlayerSettings | ||||
| 		h & color; | ||||
| 		h & handicap; | ||||
| 		h & name; | ||||
| 		h & human; | ||||
| 		h & playerID; | ||||
| 		h & team; | ||||
| 	} | ||||
|  | ||||
| 	PlayerSettings() | ||||
| 	{ | ||||
| 		bonus = brandom; | ||||
| 		bonus = RANDOM; | ||||
| 		castle = -2; | ||||
| 		heroPortrait = -1; | ||||
| 	} | ||||
| @@ -85,13 +97,14 @@ struct StartInfo | ||||
| 	PlayerSettings *getPlayersSettings(const ui8 nameID) | ||||
| 	{ | ||||
| 		for(auto it=playerInfos.begin(); it != playerInfos.end(); ++it) | ||||
| 			if(it->second.human == nameID) | ||||
| 			if(it->second.playerID == nameID) | ||||
| 				return &it->second; | ||||
|  | ||||
| 		return NULL; | ||||
| 	} | ||||
|  | ||||
| 	template <typename Handler> void serialize(Handler &h, const int version) | ||||
| 	template <typename Handler> | ||||
| 	void serialize(Handler &h, const int version) | ||||
| 	{ | ||||
| 		h & mode; | ||||
| 		h & difficulty; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user