Ver código fonte

bugfixing:
#124 - level-up code will now use ping-pong mode
#145 - switched skills positions, 1st skill will be selected
#545 - replaced images in reward dialog of seer hut

Ivan Savenko 15 anos atrás
pai
commit
c1f0b956f4
4 arquivos alterados com 128 adições e 108 exclusões
  1. 1 5
      client/GUIClasses.cpp
  2. 25 18
      hch/CObjectHandler.cpp
  3. 100 85
      server/CGameHandler.cpp
  4. 2 0
      server/CGameHandler.h

+ 1 - 5
client/GUIClasses.cpp

@@ -2489,11 +2489,7 @@ CLevelWindow::CLevelWindow(const CGHeroInstance *hero, int pskill, std::vector<u
 		}
 	}
 
-	if(comps.size() > 1)
-	{
-		ok->block(true);
-	}
-	else if(comps.size() == 1)
+	if(comps.size())
 	{
 		comps[0]->select(true);
 	}

+ 25 - 18
hch/CObjectHandler.cpp

@@ -4086,7 +4086,6 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
 					MetaString loot;
 					for (std::vector<ui16>::const_iterator it = m5arts.begin(); it != m5arts.end(); ++it)
 					{
-						bd.components.push_back (Component (Component::ARTIFACT, *it, 0, 0));
 						loot << "%s";
 						loot.addReplacement (MetaString::ART_NAMES, *it);
 					}
@@ -4099,7 +4098,6 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
 					MetaString loot;
 					for (TSlots::const_iterator it = m6creatures.begin(); it != m6creatures.end(); ++it)
 					{
-						bd.components.push_back(Component(it->second));
 						loot << "%s";
 						loot.addReplacement(it->second);
 					}
@@ -4114,7 +4112,6 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
 					{
 						if (m7resources[i])
 						{
-							bd.components.push_back (Component (Component::RESOURCE, i, m7resources[i], 0));
 							loot << "%d %s";
 							loot.addReplacement (m7resources[i]);
 							loot.addReplacement (MetaString::RES_NAMES, i);
@@ -4143,11 +4140,35 @@ void CGSeerHut::onHeroVisit( const CGHeroInstance * h ) const
 					}
 				}
 				case MISSION_PLAYER:
-					bd.components.push_back (Component (Component::FLAG, m13489val, 0, 0));
 					if (!isCustom)
 						bd.text.addReplacement	(VLC->generaltexth->colors[m13489val]);
 					break;
 			}
+			
+			switch (rewardType)
+			{
+				case 1: bd.components.push_back (Component (Component::EXPERIENCE, 0, rVal*(100+h->getSecSkillLevel(21)*5)/100.0f, 0));
+					break;
+				case 2: bd.components.push_back (Component (Component::PRIM_SKILL, 5, rVal, 0));
+					break;
+				case 3: bd.components.push_back (Component (Component::MORALE, 0, rVal, 0));
+					break;
+				case 4: bd.components.push_back (Component (Component::LUCK, 0, rVal, 0));
+					break;
+				case 5: bd.components.push_back (Component (Component::RESOURCE, rID, rVal, 0));
+					break;
+				case 6: bd.components.push_back (Component (Component::PRIM_SKILL, rID, rVal, 0));
+					break;
+				case 7: bd.components.push_back (Component (Component::SEC_SKILL, rID, rVal, 0));
+					break;
+				case 8: bd.components.push_back (Component (Component::ARTIFACT, rID, 0, 0));
+					break;
+				case 9: bd.components.push_back (Component (Component::SPELL, rID, 0, 0));
+					break;
+				case 10: bd.components.push_back (Component (Component::CREATURE, rID, rVal, 0));
+					break;
+			}
+			
 			cb->showBlockingDialog (&bd, boost::bind (&CGSeerHut::finishQuest, this, h, _1));
 			return;
 		}
@@ -4221,21 +4242,17 @@ void CGSeerHut::finishQuest (const CGHeroInstance * h, ui32 accept) const
 }
 void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
 {
-	InfoWindow iw;
-	iw.player = h->getOwner();
 	switch (rewardType)
 	{
 		case 1: //experience
 		{
 			int expVal = rVal*(100+h->getSecSkillLevel(21)*5)/100.0f;
 			cb->changePrimSkill(h->id, 4, expVal, false);
-			iw.components.push_back (Component (Component::EXPERIENCE, 0, expVal, 0));
 			break;
 		}
 		case 2: //mana points
 		{
 			cb->setManaPoints(h->id, h->mana+rVal);
-			iw.components.push_back (Component (Component::PRIM_SKILL, 5, rVal, 0));
 			break;
 		}
 		case 3: case 4: //morale /luck
@@ -4245,34 +4262,26 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
 			GiveBonus gb;
 			gb.id = h->id;
 			gb.bonus = hb;
-			//gb.descr = "";
 			cb->giveHeroBonus(&gb);
-			iw.components.push_back (Component (
-				(rewardType == 3 ? Component::MORALE : Component::LUCK), 0, rVal, 0));
 		}
 			break;
 		case 5: //resources
 			cb->giveResource(h->getOwner(), rID, rVal);
-			iw.components.push_back (Component (Component::RESOURCE, rID, rVal, 0));
 			break;
 		case 6: //main ability bonus (attak, defence etd.)
 			cb->changePrimSkill(h->id, rID, rVal, false);
-			iw.components.push_back (Component (Component::PRIM_SKILL, rID, rVal, 0));
 			break;
 		case 7: // secondary ability gain
 			cb->changeSecSkill(h->id, rID, rVal, false);
-			iw.components.push_back (Component (Component::SEC_SKILL, rID, rVal, 0));
 			break;
 		case 8: // artifact
 			cb->giveHeroArtifact(rID, h->id, -2);
-			iw.components.push_back (Component (Component::ARTIFACT, rID, 0, 0));
 			break;
 		case 9:// spell
 		{
 			std::set<ui32> spell;
 			spell.insert (rID);
 			cb->changeSpells(h->id, true, spell);
-			iw.components.push_back (Component (Component::SPELL, rID, 0, 0));
 		}
 			break;
 		case 10:// creature
@@ -4280,13 +4289,11 @@ void CGSeerHut::completeQuest (const CGHeroInstance * h) const //reward
 			CCreatureSet creatures;
 			creatures.setCreature (0, rID, rVal);
 			cb->giveCreatures (id, h,  creatures);
-			iw.components.push_back (Component (Component::CREATURE, rID, rVal, 0));
 		}
 			break;
 		default:
 			break;
 	}
-	cb->showInfoDialog(&iw);
 }
 
 void CGQuestGuard::initObj()

+ 100 - 85
server/CGameHandler.cpp

@@ -194,20 +194,93 @@ void callWith(std::vector<T> args, boost::function<void(T)> fun, ui32 which)
 	fun(args[which]);
 }
 
-void CGameHandler::changeSecSkill( int ID, int which, int val, bool abs/*=false*/ )
+void CGameHandler::levelUpHero(int ID, int skill)
 {
-	SetSecSkill sss;
-	sss.id = ID;
-	sss.which = which;
-	sss.val = val;
-	sss.abs = abs;
-	sendAndApply(&sss);
+	changeSecSkill(ID, skill, 1, 0);
+	levelUpHero(ID);
+}
 
-	if(which == 7) //Wisdom
+void CGameHandler::levelUpHero(int ID)
+{
+	CGHeroInstance *hero = static_cast<CGHeroInstance *>(gs->map->objects[ID]);
+	if (hero->exp < VLC->heroh->reqExp(hero->level+1)) // no more level-ups
+		return;
+		
+	//give prim skill
+	tlog5 << hero->name <<" got level "<<hero->level<<std::endl;
+	int r = rand()%100, pom=0, x=0;
+	int std::pair<int,int>::*g  =  (hero->level>9) ? (&std::pair<int,int>::second) : (&std::pair<int,int>::first);
+	for(;x<PRIMARY_SKILLS;x++)
+	{
+		pom += hero->type->heroClass->primChance[x].*g;
+		if(r<pom)
+			break;
+	}
+	tlog5 << "Bohater dostaje umiejetnosc pierwszorzedna " << x << " (wynik losowania "<<r<<")"<<std::endl; 
+	SetPrimSkill sps;
+	sps.id = ID;
+	sps.which = x;
+	sps.abs = false;
+	sps.val = 1;
+	sendAndApply(&sps);
+
+	HeroLevelUp hlu;
+	hlu.heroid = ID;
+	hlu.primskill = x;
+	hlu.level = hero->level+1;
+
+	//picking sec. skills for choice
+	std::set<int> basicAndAdv, expert, none;
+	for(int i=0;i<SKILL_QUANTITY;i++)
+		if (isAllowed(2,i))
+			none.insert(i);
+
+	for(unsigned i=0;i<hero->secSkills.size();i++)
 	{
-		const CGHeroInstance *h = getHero(ID);
-		if(h && h->visitedTown)
-			giveSpells(h->visitedTown, h);
+		if(hero->secSkills[i].second < 3)
+			basicAndAdv.insert(hero->secSkills[i].first);
+		else
+			expert.insert(hero->secSkills[i].first);
+		none.erase(hero->secSkills[i].first);
+	}
+
+	//first offered skill
+	if(basicAndAdv.size())
+	{
+		int s = hero->type->heroClass->chooseSecSkill(basicAndAdv);//upgrade existing
+		hlu.skills.push_back(s);
+		basicAndAdv.erase(s);
+	}
+	else if(hero->secSkills.size() < hero->type->heroClass->skillLimit)
+	{
+		hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //give new skill
+		none.erase(hlu.skills.back());
+	}
+
+	//second offered skill
+	if(hero->secSkills.size() < hero->type->heroClass->skillLimit) //hero have free skill slot
+	{
+		hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
+	}
+	else if(basicAndAdv.size())
+	{
+		hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //upgrade existing
+	}
+
+	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);
 	}
 }
 
@@ -221,82 +294,24 @@ void CGameHandler::changePrimSkill(int ID, int which, si64 val, bool abs)
 	sendAndApply(&sps);
 	if(which==4) //only for exp - hero may level up
 	{
-		CGHeroInstance *hero = static_cast<CGHeroInstance *>(gs->map->objects[ID]);
-		while (hero->exp >= VLC->heroh->reqExp(hero->level+1)) //new level
-		{
-			//give prim skill
-			tlog5 << hero->name <<" got level "<<hero->level<<std::endl;
-			int r = rand()%100, pom=0, x=0;
-			int std::pair<int,int>::*g  =  (hero->level>9) ? (&std::pair<int,int>::second) : (&std::pair<int,int>::first);
-			for(;x<PRIMARY_SKILLS;x++)
-			{
-				pom += hero->type->heroClass->primChance[x].*g;
-				if(r<pom)
-					break;
-			}
-			tlog5 << "Bohater dostaje umiejetnosc pierwszorzedna " << x << " (wynik losowania "<<r<<")"<<std::endl; 
-			SetPrimSkill sps;
-			sps.id = ID;
-			sps.which = x;
-			sps.abs = false;
-			sps.val = 1;
-			sendAndApply(&sps);
-
-			HeroLevelUp hlu;
-			hlu.heroid = ID;
-			hlu.primskill = x;
-			hlu.level = hero->level+1;
-
-			//picking sec. skills for choice
-			std::set<int> basicAndAdv, expert, none;
-			for(int i=0;i<SKILL_QUANTITY;i++) none.insert(i);
-			for(unsigned i=0;i<hero->secSkills.size();i++)
-			{
-				if(hero->secSkills[i].second < 3)
-					basicAndAdv.insert(hero->secSkills[i].first);
-				else
-					expert.insert(hero->secSkills[i].first);
-				none.erase(hero->secSkills[i].first);
-			}
-
-			//first offered skill
-			if(hero->secSkills.size() < hero->type->heroClass->skillLimit) //free skill slot
-			{
-				hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
-				none.erase(hlu.skills.back());
-			}
-			else if(basicAndAdv.size())
-			{
-				int s = hero->type->heroClass->chooseSecSkill(basicAndAdv);
-				hlu.skills.push_back(s);
-				basicAndAdv.erase(s);
-			}
+		levelUpHero(ID);
+	}
+}
 
-			//second offered skill
-			if(basicAndAdv.size())
-			{
-				hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(basicAndAdv)); //new skill
-			}
-			else if(hero->secSkills.size() < hero->type->heroClass->skillLimit)
-			{
-				hlu.skills.push_back(hero->type->heroClass->chooseSecSkill(none)); //new skill
-			}
+void CGameHandler::changeSecSkill( int ID, int which, int val, bool abs/*=false*/ )
+{
+	SetSecSkill sss;
+	sss.id = ID;
+	sss.which = which;
+	sss.val = val;
+	sss.abs = abs;
+	sendAndApply(&sss);
 
-			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::changeSecSkill,this,ID,_1,1,0)),_1));
-				applyAndAsk(&hlu,hero->tempOwner,callback); //call changeSecSkill with appropriate args when client responds
-			}
-			else if(hlu.skills.size() == 1) //apply, give only possible skill  and send info
-			{
-				sendAndApply(&hlu);
-				changeSecSkill(ID,hlu.skills.back(),1,false);
-			}
-			else //apply and send info
-			{
-				sendAndApply(&hlu);
-			}
-		}
+	if(which == 7) //Wisdom
+	{
+		const CGHeroInstance *h = getHero(ID);
+		if(h && h->visitedTown)
+			giveSpells(h->visitedTown, h);
 	}
 }
 

+ 2 - 0
server/CGameHandler.h

@@ -123,6 +123,8 @@ public:
 	void setOwner(int objid, ui8 owner);
 	void setHoverName(int objid, MetaString * name);
 	void setObjProperty(int objid, int prop, si64 val);
+	void levelUpHero(int ID, int skill);//handle client respond and send one more request if needed 
+	void levelUpHero(int ID);//initial call - check if hero have remaining levelups & handle them
 	void changePrimSkill(int ID, int which, si64 val, bool abs=false);
 	void changeSecSkill(int ID, int which, int val, bool abs=false); 
 	void showInfoDialog(InfoWindow *iw);