mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Imprisoned heroes as well as their commanders will get full level ups, with updated specialty, mana and movement.
This commit is contained in:
		
							
								
								
									
										13
									
								
								Global.h
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								Global.h
									
									
									
									
									
								
							| @@ -481,6 +481,19 @@ namespace vstd | ||||
| 			return vf(lhs) < vf(rhs); | ||||
| 		}); | ||||
| 	} | ||||
|  | ||||
| 	static int retreiveRandNum(const boost::function<int()> &randGen) | ||||
| 	{ | ||||
| 		if (randGen) | ||||
| 			return randGen(); | ||||
| 		else | ||||
| 			return rand(); | ||||
| 	} | ||||
|  | ||||
| 	template <typename T> const T & pickRandomElementOf(const std::vector<T> &v, const boost::function<int()> &randGen) | ||||
| 	{ | ||||
| 		return v.at(retreiveRandNum(randGen) % v.size()); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| using std::shared_ptr; | ||||
|   | ||||
| @@ -537,6 +537,8 @@ void HeroLevelUp::applyCl( CClient *cl ) | ||||
| 	{ | ||||
| 		cl->playerint[h->tempOwner]->heroGotLevel(h, static_cast<int>(primskill), skills, queryID); | ||||
| 	} | ||||
| 	//else | ||||
| 	//	cb->selectionMade(0, queryID); | ||||
| } | ||||
|  | ||||
| void CommanderLevelUp::applyCl( CClient *cl ) | ||||
|   | ||||
| @@ -1011,19 +1011,6 @@ CCreatureHandler::~CCreatureHandler() | ||||
| { | ||||
| } | ||||
|  | ||||
| static int retreiveRandNum(const boost::function<int()> &randGen) | ||||
| { | ||||
| 	if(randGen) | ||||
| 		return randGen(); | ||||
| 	else | ||||
| 		return rand(); | ||||
| } | ||||
|  | ||||
| template <typename T> const T & pickRandomElementOf(const std::vector<T> &v, const boost::function<int()> &randGen) | ||||
| { | ||||
| 	return v.at(retreiveRandNum(randGen) % v.size()); | ||||
| } | ||||
|  | ||||
| int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, int tier) const | ||||
| { | ||||
| 	int r = 0; | ||||
| @@ -1031,7 +1018,7 @@ int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, i | ||||
| 	{ | ||||
| 		do  | ||||
| 		{ | ||||
| 			r = pickRandomElementOf(creatures, randGen)->idNumber; | ||||
| 			r = vstd::pickRandomElementOf(creatures, randGen)->idNumber; | ||||
| 		} while (vstd::contains(VLC->creh->notUsedMonsters,r)); | ||||
| 	} | ||||
| 	else | ||||
| @@ -1052,7 +1039,7 @@ int CCreatureHandler::pickRandomMonster(const boost::function<int()> &randGen, i | ||||
| 			return 0; | ||||
| 		} | ||||
|  | ||||
| 		return pickRandomElementOf(allowed, randGen); | ||||
| 		return vstd::pickRandomElementOf(allowed, randGen); | ||||
| 	} | ||||
| 	return r; | ||||
| } | ||||
|   | ||||
| @@ -1317,7 +1317,7 @@ void CGameState::init(StartInfo * si) | ||||
| 	} | ||||
|  | ||||
| 	/*************************FOG**OF**WAR******************************************/ | ||||
| 	tlog4 << "\tFog of war"; | ||||
| 	tlog4 << "\tFog of war"; //FIXME: should be initialized after all bonuses are set | ||||
| 	for(auto k=teams.begin(); k!=teams.end(); ++k) | ||||
| 	{ | ||||
| 		k->second.fogOfWarMap.resize(map->width); | ||||
| @@ -1520,8 +1520,6 @@ void CGameState::init(StartInfo * si) | ||||
| 	BOOST_FOREACH(CGObjectInstance *obj, map->objects) | ||||
| 	{ | ||||
| 		obj->initObj(); | ||||
| 		if(obj->ID == Obj::PRISON) //prison also needs to initialize hero | ||||
| 			static_cast<CGHeroInstance*>(obj)->initHero(); | ||||
| 	} | ||||
| 	BOOST_FOREACH(CGObjectInstance *obj, map->objects) | ||||
| 	{ | ||||
|   | ||||
| @@ -758,14 +758,6 @@ void CGHeroInstance::initHero() | ||||
| 		secSkills = type->secSkillsInit; | ||||
| 	if (!name.length()) | ||||
| 		name = type->name; | ||||
| 	if (exp == 0xffffffff) | ||||
| 	{ | ||||
| 		initExp(); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		level = VLC->heroh->level(exp); | ||||
| 	} | ||||
|  | ||||
| 	if (sex == 0xFF)//sex is default | ||||
| 		sex = type->sex; | ||||
| @@ -781,6 +773,20 @@ void CGHeroInstance::initHero() | ||||
| 	{ | ||||
| 		commander = new CCommanderInstance (VLC->townh->factions[type->heroClass->faction].commander); | ||||
| 		commander->setArmyObj (castToArmyObj()); //TODO: separate function for setting commanders | ||||
| 		commander->giveStackExp (exp); | ||||
| 	} | ||||
|  | ||||
| 	if (exp == 0xffffffff) | ||||
| 	{ | ||||
| 		initExp(); | ||||
| 	} | ||||
| 	else if (ID != Obj::PRISON) | ||||
| 	{ | ||||
| 		level = VLC->heroh->level(exp); | ||||
| 	} | ||||
| 	else //warp hero at the beginning of next turn | ||||
| 	{ | ||||
| 		level = 1; | ||||
| 	} | ||||
|  | ||||
| 	hoverName = VLC->generaltexth->allTexts[15]; | ||||
| @@ -897,9 +903,16 @@ void CGHeroInstance::onHeroVisit(const CGHeroInstance * h) const | ||||
| 	{ | ||||
| 		int txt_id; | ||||
|  | ||||
| 		if(cb->getHeroCount(h->tempOwner,false) < 8) //free hero slot | ||||
| 		if(cb->getHeroCount(h->tempOwner,false) < GameConstants::MAX_HEROES_PER_PLAYER) //free hero slot | ||||
| 		{ | ||||
| 			cb->changeObjPos(id,pos+int3(1,0,0),0); | ||||
| 			//update hero parameters | ||||
| 			SetMovePoints smp; | ||||
| 			smp.hid = id; | ||||
| 			smp.val = maxMovePoints (true); //TODO: hota prison on water? | ||||
| 			cb->setMovePoints (&smp); | ||||
| 			cb->setManaPoints (id, manaLimit()); | ||||
|  | ||||
| 			cb->setObjProperty(id, ObjProperty::ID, Obj::HERO); //set ID to 34 | ||||
| 			cb->giveHero(id,h->tempOwner); //recreates def and adds hero to player | ||||
|  | ||||
| @@ -928,7 +941,7 @@ void CGHeroInstance::initObj() //TODO: use bonus system | ||||
| 	attachTo(hs); //do we ever need to detach it? | ||||
|  | ||||
| 	if(!type) | ||||
| 		return; //TODO: support prison | ||||
| 		initHero(); //TODO: set up everything for prison before specialties are configured | ||||
|  | ||||
| 	BOOST_FOREACH(const auto &spec, type->spec) //TODO: unfity with bonus system | ||||
| 	{ | ||||
|   | ||||
| @@ -94,7 +94,8 @@ namespace GameConstants | ||||
| // Enum declarations | ||||
| namespace PrimarySkill | ||||
| { | ||||
| 	enum PrimarySkill { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE}; | ||||
| 	enum PrimarySkill { ATTACK, DEFENSE, SPELL_POWER, KNOWLEDGE, | ||||
| 				EXPERIENCE = 4}; //for some reason changePrimSkill uses it | ||||
| } | ||||
|  | ||||
| namespace EVictoryConditionType | ||||
|   | ||||
| @@ -275,20 +275,37 @@ void CGameHandler::levelUpHero(int ID) | ||||
| 		hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //upgrade existing | ||||
| 	} | ||||
|  | ||||
| 	if(hlu.skills.size() > 1) //apply and ask for secondary skill | ||||
| 	if (hero->tempOwner == GameConstants::NEUTRAL_PLAYER) //choose skill automatically | ||||
| 	{ | ||||
| 		boost::function<void(ui32)> callback = boost::function<void(ui32)>(boost::bind(callWith<ui16>,hlu.skills,boost::function<void(ui16)>(boost::bind(&CGameHandler::levelUpHero,this,ID,_1)),_1)); | ||||
| 		applyAndAsk(&hlu,hero->tempOwner,callback); //call levelUpHero when client responds | ||||
| 		sendAndApply (&hlu); | ||||
| 		if (hlu.skills.size()) | ||||
| 		{ | ||||
| 			levelUpHero (ID, vstd::pickRandomElementOf (hlu.skills, rand)); | ||||
| 		} | ||||
| 		else //apply and send info | ||||
| 		{ | ||||
| 			levelUpHero(ID); | ||||
| 		} | ||||
| 	} | ||||
| 	else if(hlu.skills.size() == 1) //apply, give only possible skill  and send info | ||||
| 	else | ||||
| 	{ | ||||
| 		sendAndApply(&hlu); | ||||
| 		levelUpHero(ID, hlu.skills.back()); | ||||
| 	} | ||||
| 	else //apply and send info | ||||
| 	{ | ||||
| 		sendAndApply(&hlu); | ||||
| 		levelUpHero(ID); | ||||
| 		if(hlu.skills.size() > 1) //apply and ask for secondary skill | ||||
| 		{ | ||||
| 			boost::function<void(ui32)> callback = boost::function<void(ui32)>(boost::bind  | ||||
| 					(callWith<ui16>, hlu.skills, boost::function<void(ui16)>(boost::bind | ||||
| 					(&CGameHandler::levelUpHero, this, ID,_1) ), _1)); | ||||
| 			applyAndAsk(&hlu,hero->tempOwner,callback); //call levelUpHero when client responds | ||||
| 		} | ||||
| 		else if(hlu.skills.size() == 1) //apply, give only possible skill  and send info | ||||
| 		{ | ||||
| 			sendAndApply(&hlu); | ||||
| 			levelUpHero(ID, hlu.skills.back()); | ||||
| 		} | ||||
| 		else //apply and send info | ||||
| 		{ | ||||
| 			sendAndApply(&hlu); | ||||
| 			levelUpHero(ID); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -407,20 +424,35 @@ void CGameHandler::levelUpCommander(const CCommanderInstance * c) | ||||
| 	} | ||||
| 	int skillAmount = clu.skills.size(); | ||||
|  | ||||
| 	if (skillAmount > 1) //apply and ask for secondary skill | ||||
| 	{ | ||||
| 		auto callback = boost::function<void(ui32)>(boost::bind(callWith<ui32>, clu.skills, boost::function<void(ui32)>(boost::bind(&CGameHandler::levelUpCommander, this, c, _1)), _1)); | ||||
| 		applyAndAsk (&clu, c->armyObj->tempOwner, callback); //call levelUpCommander when client responds | ||||
| 	} | ||||
| 	else if (skillAmount == 1) //apply, give only possible skill and send info | ||||
| 	if (hero->tempOwner == GameConstants::NEUTRAL_PLAYER) //choose skill automatically | ||||
| 	{ | ||||
| 		sendAndApply(&clu); | ||||
| 		levelUpCommander(c, clu.skills.back()); | ||||
| 		if (clu.skills.size()) | ||||
| 		{ | ||||
| 			levelUpCommander(c, vstd::pickRandomElementOf (clu.skills, rand)); | ||||
| 		} | ||||
| 		else //apply and send info | ||||
| 		{ | ||||
| 			levelUpCommander(c); | ||||
| 		} | ||||
| 	} | ||||
| 	else //apply and send info | ||||
| 	else | ||||
| 	{ | ||||
| 		sendAndApply(&clu); | ||||
| 		levelUpCommander(c); | ||||
| 		if (skillAmount > 1) //apply and ask for secondary skill | ||||
| 		{ | ||||
| 			auto callback = boost::function<void(ui32)>(boost::bind(callWith<ui32>, clu.skills, boost::function<void(ui32)>(boost::bind(&CGameHandler::levelUpCommander, this, c, _1)), _1)); | ||||
| 			applyAndAsk (&clu, c->armyObj->tempOwner, callback); //call levelUpCommander when client responds | ||||
| 		} | ||||
| 		else if (skillAmount == 1) //apply, give only possible skill and send info | ||||
| 		{ | ||||
| 			sendAndApply(&clu); | ||||
| 			levelUpCommander(c, clu.skills.back()); | ||||
| 		} | ||||
| 		else //apply and send info | ||||
| 		{ | ||||
| 			sendAndApply(&clu); | ||||
| 			levelUpCommander(c); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -1133,6 +1165,17 @@ void CGameHandler::newTurn() | ||||
| 	std::map<ui8, si32> hadGold;//starting gold - for buildings like dwarven treasury | ||||
| 	srand(time(NULL)); | ||||
|  | ||||
| 	if (firstTurn) | ||||
| 	{ | ||||
| 		BOOST_FOREACH (auto obj, gs->map->objects) | ||||
| 		{ | ||||
| 			if (obj->ID == Obj::PRISON) //give imprisoned hero 0 exp to level him up. easiest to do at this point | ||||
| 			{ | ||||
| 				changePrimSkill (obj->id, PrimarySkill::EXPERIENCE, 0); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if (newWeek && !firstTurn) | ||||
| 	{ | ||||
| 		n.specialWeek = NewTurn::NORMAL; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user