浏览代码

- partial implementation of scholar skill (spell exchange works, but no message)
- some fixes

Ivan Savenko 15 年之前
父节点
当前提交
fa735b6a67

+ 1 - 1
client/CCastleInterface.cpp

@@ -616,7 +616,7 @@ void CCastleInterface::buildingClicked(int building)
 			break;
 		case 14:  //marketplace
 			{
-				CMarketplaceWindow *cmw = new CMarketplaceWindow(0);
+				CMarketplaceWindow *cmw = new CMarketplaceWindow();
 				GH.pushInt(cmw);
 				break;
 			}

+ 2 - 2
client/CHeroWindow.cpp

@@ -300,7 +300,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero)
 		morale->text += CGI->generaltexth->arraytxt[108];
 	else
 		for(int it=0; it < mrl.size(); it++)
-			morale->text += mrl[it].second;
+			morale->text += "\n" + mrl[it].second;
 
 
 	//setting luck
@@ -316,7 +316,7 @@ void CHeroWindow::setHero(const CGHeroInstance *hero)
 		luck->text += CGI->generaltexth->arraytxt[77];
 	else
 		for(int it=0; it < mrl.size(); it++)
-			luck->text += mrl[it].second;
+			luck->text += "\n" + mrl[it].second;
 
 	//restoring pos
 	pos.x += 65;

+ 19 - 5
client/CKingdomInterface.cpp

@@ -105,7 +105,7 @@ CKingdomInterface::CKingdomInterface()
 		733,size*116+2,"OVBUTN4.DEF");
 	ObjBottom->bitmapOffset = 2;
 
-	for (size_t i=0; i<SKILL_PER_HERO; i++)
+	for (size_t i=0; i<8; i++)
 	{
 		incomes.push_back(new HoverableArea());//bottom panel with mines
 		incomes[i]->pos = genRect(57,68,pos.x+20+i*80,pos.y+31+size*116);
@@ -223,6 +223,20 @@ void CKingdomInterface::close()
 	GH.popIntTotally(this);
 }
 
+void CKingdomInterface::updateAllGarrisons()
+{
+	for (int i = 0; i<towns.size(); i++)
+	{tlog1<<"Have "<<towns.size()<<" town elements, recreating "<<i<<"\n";
+		if (towns[i] && towns[i]->garr)
+			towns[i]->garr->recreateSlots();
+	}
+	for (int i = 0; i<heroes.size(); i++)
+	{tlog1<<"Have "<<heroes.size()<<" hero elements, recreating "<<i<<"\n";
+		if (heroes[i] && heroes[i]->garr)
+			heroes[i]->garr->recreateSlots();
+	}
+}
+
 void CKingdomInterface::showAll( SDL_Surface * to/*=NULL*/)
 {
 	LOCPLINT->adventureInt->resdatabar.draw(to);
@@ -696,8 +710,8 @@ CKingdomInterface::CHeroItem::CHeroItem(int num, CKingdomInterface * Owner)
 	{
 		artButtons->addButton(boost::assign::map_list_of(0,CGI->generaltexth->overview[13+it]),
 			CGI->generaltexth->overview[8+it], "OVBUTN3.DEF",364+it*112, 46, it);
-		std::string str = CGI->generaltexth->overview[8+it];//TODO:find function for this if any
-		str = str.substr(str.find_first_of("{"), str.find_first_of("}")-str.find_first_of("{"));
+		std::string str = CGI->generaltexth->overview[8+it];
+		str = str.substr(str.find_first_of("{")+1, str.find_first_of("}")-str.find_first_of("{"));
 		artButtons->buttons[it]->addTextOverlay(str, FONT_SMALL, tytulowy);
 	}
 	artButtons->onChange = boost::bind(&CKingdomInterface::CHeroItem::onArtChange, this, _1);
@@ -856,7 +870,7 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
 		morale->text += CGI->generaltexth->arraytxt[108];
 	else
 		for(int it=0; it < mrl.size(); it++)
-			morale->text += mrl[it].second;
+			morale->text += "\n" + mrl[it].second;
 
 	//setting luck
 	mrl = hero->getCurrentLuckModifiers();
@@ -871,7 +885,7 @@ void CKingdomInterface::CHeroItem::setHero(const CGHeroInstance * newHero)
 		luck->text += CGI->generaltexth->arraytxt[77];
 	else
 		for(int it=0; it < mrl.size(); it++)
-			luck->text += mrl[it].second;
+			luck->text += "\n" + mrl[it].second;
 }
 
 void CKingdomInterface::CHeroItem::scrollArts(int move)

+ 1 - 0
client/CKingdomInterface.h

@@ -132,6 +132,7 @@ public:
 
 	CKingdomInterface(); //c-tor
 	~CKingdomInterface(); //d-tor
+	void updateAllGarrisons();//garrison updater
 	void moveObjectList(int newPos);
 	void recreateHeroList(int pos);//recreating heroes list (on slider move)
 	void recreateTownList(int pos);//same for town list

+ 7 - 0
client/CPlayerInterface.cpp

@@ -3,6 +3,7 @@
 #include "CBattleInterface.h"
 #include "../CCallback.h"
 #include "CCastleInterface.h"
+#include "CKingdomInterface.h"
 #include "CCursorHandler.h"
 #include "CGameInfo.h"
 #include "CHeroWindow.h"
@@ -484,6 +485,12 @@ void CPlayerInterface::garrisonChanged(const CGObjectInstance * obj)
 			wwg->garr->recreateSlots();
 			wasGarrison = true;
 		}
+		else
+		{//a cheat for Kingdom Overview window (it has CWindowWithGarrison-childrens which are not present in ListInt)
+			CKingdomInterface *cki = dynamic_cast<CKingdomInterface*>(*i);//need to create "Garrison Holder" class thingy
+			if (cki)
+				cki->updateAllGarrisons();
+		}
 	}
 
 	GH.totalRedraw();

+ 2 - 2
client/GUIClasses.cpp

@@ -4532,7 +4532,7 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
 			morale[b]->text += CGI->generaltexth->arraytxt[108];
 		else
 			for(int it=0; it < mrl.size(); it++)
-				morale[b]->text += mrl[it].second;
+				morale[b]->text += "\n" + mrl[it].second;
 
 		//setting luck
 		luck[b] = new LRClickableAreaWTextComp();
@@ -4550,7 +4550,7 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
 			luck[b]->text += CGI->generaltexth->arraytxt[77];
 		else
 			for(int it=0; it < mrl.size(); it++)
-				luck[b]->text += mrl[it].second;
+				luck[b]->text += "\n" + mrl[it].second;
 	}
 
 	//buttons

+ 9 - 4
config/buildings2.txt

@@ -48,11 +48,10 @@ CASTLE 1
 10
 11
 12
-13
+13
 17
 21
-22
-23
+22
 -1
 27
 28
@@ -211,6 +210,10 @@ CASTLE 7
 26
 END
 CASTLE 8
+-1
+27
+28
+16
 34
 41
 6
@@ -226,6 +229,7 @@ CASTLE 8
 3
 4
 5
+15
 14
 17
 35
@@ -238,6 +242,7 @@ CASTLE 8
 11
 12
 13
+29
 END
 EOD
 
@@ -260,4 +265,4 @@ EOD
 
 EOD
 
-Buildings not mentioned in the file will be blitted as first. File can contain data for any count of castles.
+Buildings not mentioned in the file will be blitted as first. File can contain data for any count of castles.

+ 16 - 21
hch/CObjectHandler.cpp

@@ -894,12 +894,12 @@ std::vector<std::pair<int,std::string> > CGHeroInstance::getCurrentMoraleModifie
 		ret.push_back(std::make_pair(getSecSkillLevel(6),VLC->generaltexth->arraytxt[104+getSecSkillLevel(6)]));
 
 	//town structures
-	if(town && visitedTown)
+	if(visitedTown)
 	{
 		if(visitedTown->subID == 0  &&  vstd::contains(visitedTown->builtBuildings,22)) //castle, brotherhood of sword built
 			ret.push_back(std::pair<int,std::string>(2,VLC->generaltexth->buildings[0][22].first + " +2"));
 		else if(vstd::contains(visitedTown->builtBuildings,5)) //tavern is built
-			ret.push_back(std::pair<int,std::string>(2,VLC->generaltexth->buildings[0][5].first + " +1"));
+			ret.push_back(std::pair<int,std::string>(1,VLC->generaltexth->buildings[0][5].first + " +1"));
 	}
 
 	//number of alignments and presence of undead
@@ -981,6 +981,13 @@ std::vector<std::pair<int,std::string> > CGHeroInstance::getCurrentLuckModifiers
 	if(getSecSkillLevel(9)) 
 		ret.push_back(std::make_pair(getSecSkillLevel(9),VLC->generaltexth->arraytxt[73+getSecSkillLevel(9)]));
 
+	if(visitedTown)
+	{
+		if(visitedTown->subID == 1  &&  vstd::contains(visitedTown->builtBuildings,21)) //castle, brotherhood of sword built
+			ret.push_back(std::pair<int,std::string>(2,VLC->generaltexth->buildings[1][21].first + " +2"));
+	}
+
+
 	return ret;
 }
 
@@ -1651,16 +1658,6 @@ int CGTownInstance::defenceBonus(int type) const
 						if (subID == 2 && vstd::contains(builtBuildings,26))//Tower, Grail
 							ret += 15;
 							return ret;
-/*morale*/		case 4:
-						if (              vstd::contains(builtBuildings, 5))//Any, Tavern
-							ret += 1;
-						if (subID == 0 && vstd::contains(builtBuildings,22))//Castle, Brotherhood of the sword
-							ret += 1;
-							return ret;
-/*luck*/		case 5:
-						if (subID == 1 && vstd::contains(builtBuildings,21))//Rampart, Fountain of Fortune
-							ret += 2;
-							return ret;
 		}
 		return 0;//Why we are here? wrong type?
 }
@@ -5411,9 +5408,11 @@ void CShop::setPropertyDer (ui8 what, ui32 val)
 	}
 }
 void CGArtMerchant::reset(ui32 val)
-{
+{//TODO: it should have 2 global pools instead of unique for each merchant:
+// 1) for town merchants - resets every month,
+// 2) for adv. map - resets only on game start
 	std::vector<CArtifact*>::iterator index;
-	for (ui8 i = 0; i < 4; ++i) //each tier
+	for (ui8 i = 0; i < 3; ++i) //each tier
 	{	
 		int count = 0;
 		std::vector<CArtifact*> arts; //to avoid addition of different tiers
@@ -5421,19 +5420,15 @@ void CGArtMerchant::reset(ui32 val)
 		{
 			case 0:
 				cb->getAllowed (arts, CArtifact::ART_TREASURE);
-				count = 2;
+				count = 3; // first row - three treasures,
 				break;
 			case 1:
 				cb->getAllowed (arts, CArtifact::ART_MINOR);
-				count = 2;
+				count = 3; // second row three minors
 				break;
 			case 2:
 				cb->getAllowed (arts, CArtifact::ART_MAJOR);
-				count = 1;
-				break;
-			case 3:
-				cb->getAllowed (arts, CArtifact::ART_RELIC);
-				count = 1;
+				count = 1; // and a third row - one major
 				break;
 		}
 		for (ui8 n = 0; n < count; n++)

+ 49 - 12
server/CGameHandler.cpp

@@ -797,7 +797,6 @@ void CGameHandler::newTurn()
 
 		std::pair<ui8,si32> playerGold(i->first,i->second.resources[6]);
 		hadGold.insert(playerGold); 
-		tlog1<<i->first<<" & "<<i->second.resources[6]<<"\n";
 
 		if(gs->getDate(1)==7) //first day of week - new heroes in tavern
 		{
@@ -1269,6 +1268,7 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
 	if (town)
 	{
 		if (hero2)
+		{
 			for (int i=0; i<4; i++)
 			{
 				int val = town->defenceBonus(i);
@@ -1280,18 +1280,21 @@ void CGameHandler::setupBattle( BattleInfo * curB, int3 tile, const CCreatureSet
 					sendAndApply(&gs);
 				}
 			}
+		}
+		else//if we don't have hero - apply separately, if hero present - will be taken from hero bonuses
+		{
+			if(town->subID == 0  &&  vstd::contains(town->builtBuildings,22)) //castle, brotherhood of sword built
+				for(int g=0; g<stacks.size(); ++g)
+					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, 2, StackFeature::OTHER_SOURCE));
 
-		int bonuseValue = town->defenceBonus(4);//morale
-		if (bonuseValue)
-			for(int g=0; g<stacks.size(); ++g)
-				if (!stacks[g]->attackerOwned)//garrisoned stack
-					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, bonuseValue, StackFeature::OTHER_SOURCE));
+			else if(vstd::contains(town->builtBuildings,5)) //tavern is built
+				for(int g=0; g<stacks.size(); ++g)
+					stacks[g]->features.push_back(makeFeature(StackFeature::MORALE_BONUS, StackFeature::WHOLE_BATTLE, 0, 1, StackFeature::OTHER_SOURCE));
 
-		bonuseValue = town->defenceBonus(5);//luck
-		if (bonuseValue)
-			for(int g=0; g<stacks.size(); ++g)
-				if (!stacks[g]->attackerOwned)//garrisoned stack
-					stacks[g]->features.push_back(makeFeature(StackFeature::LUCK_BONUS, StackFeature::WHOLE_BATTLE, 0, bonuseValue, StackFeature::OTHER_SOURCE));
+			if(town->subID == 1  &&  vstd::contains(town->builtBuildings,21)) //rampart, fountain of fortune is present
+				for(int g=0; g<stacks.size(); ++g)
+					stacks[g]->features.push_back(makeFeature(StackFeature::LUCK_BONUS, StackFeature::WHOLE_BATTLE, 0, 2, StackFeature::OTHER_SOURCE));
+		}
 	}
 
 	//giving terrain premies for heroes & stacks
@@ -1911,13 +1914,47 @@ void CGameHandler::changeObjPos( int objid, int3 newPos, ui8 flags )
 	sendAndApply(&cop);
 }
 
+void CGameHandler::useScholarSkill(si32 fromHero, si32 toHero)
+{//TODO: dialog window;
+	const CGHeroInstance * h1 = getHero(fromHero);
+	const CGHeroInstance * h2 = getHero(toHero);
+
+	int ScholarLevel = std::max( h1->getSecSkillLevel(18), h2->getSecSkillLevel(18));//heroes can trade with this levels
+	if ( ScholarLevel == 0 )
+		return;
+
+	ScholarLevel++;
+	int h1Lvl = std::min(ScholarLevel, h1->getSecSkillLevel(7)+2),
+	    h2Lvl = std::min(ScholarLevel, h2->getSecSkillLevel(7)+2);//heroes can receive this levels
+	ChangeSpells cs;
+	cs.learn = true;
+	cs.hid = toHero;//giving spells to first hero
+
+	for(std::set<ui32>::iterator it=h1->spells.begin(); it!=h1->spells.end();it++)
+		if ( h2Lvl >= VLC->spellh->spells[*it].level && !vstd::contains(h2->spells, *it))//hero can learn it and don't have it yet
+			cs.spells.insert(*it);//spell to learn
+
+	if (cs.spells.size())//if found new spell - apply
+		sendAndApply(&cs);
+
+	cs.hid = fromHero;
+	cs.spells.clear();
+
+	for(std::set<ui32>::iterator it=h2->spells.begin(); it!=h2->spells.end();it++)
+		if ( h1Lvl >= VLC->spellh->spells[*it].level && !vstd::contains(h1->spells, *it))
+			cs.spells.insert(*it);
+	if (cs.spells.size())
+		sendAndApply(&cs);
+}
+
 void CGameHandler::heroExchange(si32 hero1, si32 hero2)
 {
 	ui8 player1 = getHero(hero1)->tempOwner;
 	ui8 player2 = getHero(hero2)->tempOwner;
 
-	if(player1 == player2)
+	if(player1 == player2)//TODO: allies
 	{
+		useScholarSkill(hero1,hero2);
 		OpenWindow hex;
 		hex.window = OpenWindow::EXCHANGE_WINDOW;
 		hex.id1 = hero1;

+ 1 - 0
server/CGameHandler.h

@@ -146,6 +146,7 @@ public:
 	void setManaPoints(int hid, int val);
 	void giveHero(int id, int player);
 	void changeObjPos(int objid, int3 newPos, ui8 flags);
+	void useScholarSkill(si32 hero1, si32 hero2);
 	void heroExchange(si32 hero1, si32 hero2);
 	//////////////////////////////////////////////////////////////////////////