Browse Source

* added shots limit
* improved hero hiring
* tree of knowledge will give right number of exp points
* fixed bug with double showing "getting hit" animation
* more logs in initialization of creature handler
* added 'vcmiglorfindel' cheat (works as woggandalfwhite)
* minor improvements

Michał W. Urbańczyk 17 years ago
parent
commit
248b5e8677
12 changed files with 153 additions and 63 deletions
  1. 1 0
      CBattleInterface.cpp
  2. 2 1
      CCallback.cpp
  3. 70 1
      CGameState.cpp
  4. 6 1
      CGameState.h
  5. 1 1
      CHeroWindow.cpp
  6. 1 1
      CLua.cpp
  7. 1 1
      CMT.cpp
  8. 12 7
      CPlayerInterface.cpp
  9. 14 17
      hch/CCreatureHandler.cpp
  10. 0 7
      hch/CCreatureHandler.h
  11. 3 2
      lib/NetPacks.h
  12. 42 24
      server/CGameHandler.cpp

+ 1 - 0
CBattleInterface.cpp

@@ -1819,6 +1819,7 @@ void CBattleHex::clickRight(boost::logic::tribool down)
 				pom->defenseBonus = h->primSkills[1];
 				pom->luck = h->getCurrentLuck();
 				pom->morale = h->getCurrentMorale();
+				pom->shotsLeft = myst.shots;
 			}
 			pom->currentHealth = myst.firstHPleft;
 			(new CCreInfoWindow(myst.creature->idNumber,0,myst.amount,pom,boost::function<void()>(),boost::function<void()>(),NULL))

+ 2 - 1
CCallback.cpp

@@ -523,7 +523,7 @@ bool CCallback::battleIsStackMine(int ID)
 	}
 	return false;
 }
-bool CCallback::battleCanShoot(int ID, int dest) //TODO: check arrows amount
+bool CCallback::battleCanShoot(int ID, int dest)
 {
 	boost::shared_lock<boost::shared_mutex> lock(*gs->mx);
 	CStack *our=battleGetStackByID(ID), *dst=battleGetStackByPos(dest);
@@ -532,6 +532,7 @@ bool CCallback::battleCanShoot(int ID, int dest) //TODO: check arrows amount
 		&& our->owner != dst->owner
 		&& dst->alive()
 		&& !gs->curB->isStackBlocked(ID)
+		&& our->shots
 		)
 		return true;
 	return false;

+ 70 - 1
CGameState.cpp

@@ -247,6 +247,62 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
 	abilities = C->abilities;
 	state.insert(ALIVE);
 }
+
+CGHeroInstance* CGameState::HeroesPool::pickHeroFor(bool native, int player, const CTown *town, int notThatOne)
+{
+	if(player<0 || player>=PLAYER_LIMIT)
+	{
+		tlog1 << "Cannot pick hero for " << town->name << ". Wrong owner!\n";
+		return NULL;
+	}
+	std::vector<CGHeroInstance *> pool;
+	int sum=0, r;
+	if(native)
+	{
+		for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
+		{
+			if(pavailable[i->first] & 1<<player
+			  && i->second->type->heroType/2 == town->typeID
+			  && i->second->subID != notThatOne
+			  )
+			{
+				pool.push_back(i->second);
+			}
+		}
+		if(!pool.size())
+			return pickHeroFor(false,player,town,notThatOne);
+		else
+			return pool[rand()%pool.size()];
+	}
+	else
+	{
+		for(std::map<ui32,CGHeroInstance *>::iterator i=heroesPool.begin(); i!=heroesPool.end(); i++)
+		{
+			if(pavailable[i->first] & 1<<player
+				&& i->second->subID != notThatOne
+			  )
+			{
+				pool.push_back(i->second);
+				sum += i->second->type->heroClass->selectionProbability[town->typeID];
+			}
+		}
+		if(!pool.size())
+		{
+			tlog1 << "There are no heroes available for player " << player<<"!\n";
+			return NULL;
+		}
+		r = rand()%sum;
+		for(int i=0; i<pool.size(); i++)
+		{
+			r -= pool[i]->type->heroClass->selectionProbability[town->typeID];
+			if(r<0)
+				return pool[i];
+		}
+		return pool[pool.size()-1];
+	}
+}
+
+
 void CGameState::applyNL(IPack * pack)
 {
 	switch(pack->getType())
@@ -401,6 +457,16 @@ void CGameState::applyNL(IPack * pack)
 			players[rh->player].availableHeroes.clear();
 			players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid1]);
 			players[rh->player].availableHeroes.push_back(hpool.heroesPool[rh->hid2]);
+			if(rh->flags & 1)
+			{
+				hpool.heroesPool[rh->hid1]->army.slots.clear();
+				hpool.heroesPool[rh->hid1]->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[hpool.heroesPool[rh->hid1]->type->refTypeStack[0]],1);
+			}
+			if(rh->flags & 2)
+			{
+				hpool.heroesPool[rh->hid2]->army.slots.clear();
+				hpool.heroesPool[rh->hid2]->army.slots[0] = std::pair<ui32,si32>(VLC->creh->nameToID[hpool.heroesPool[rh->hid2]->type->refTypeStack[0]],1);
+			}
 			break;
 		}
 	case 500:
@@ -622,8 +688,11 @@ void CGameState::applyNL(IPack * pack)
 	case 3006:
 		{
 			BattleAttack *br = static_cast<BattleAttack*>(pack);
+			CStack *attacker = curB->getStack(br->stackAttacking);
 			if(br->counter())
-				curB->getStack(br->stackAttacking)->counterAttacks--;
+				attacker->counterAttacks--;
+			if(br->shot())
+				attacker->shots--;
 			applyNL(&br->bsa);
 			break;
 		}

+ 6 - 1
CGameState.h

@@ -13,6 +13,7 @@
 #include "tchar_amigaos4.h"
 #endif
 
+class CTown;
 class CScriptCallback;
 class CCallback;
 class CLuaCallback;
@@ -91,6 +92,7 @@ public:
 	ui8 attackerOwned; //if true, this stack is owned by attakcer (this one from left hand side of battle)
 	ui16 position; //position on battlefield
 	ui8 counterAttacks; //how many counter attacks can be performed more in this turn (by default set at the beginning of the round to 1)
+	si16 shots; //how many shots left
 
 	std::set<EAbilities> abilities;
 	std::set<ECombatInfo> state;
@@ -108,6 +110,7 @@ public:
 		h & id;
 		creature = &VLC->creh->creatures[id];
 		abilities = creature->abilities;
+		shots = creature->shots;
 	}
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
@@ -144,10 +147,12 @@ private:
 	std::map<int, CGDefInfo*> villages, forts, capitols; //def-info for town graphics
 	std::vector<ui32> resVals;
 
-	struct HeroesPool
+	struct DLL_EXPORT HeroesPool
 	{
 		std::map<ui32,CGHeroInstance *> heroesPool; //[subID] - heroes available to buy; NULL if not available
 		std::map<ui32,ui8> pavailable; // [subid] -> which players can recruit hero
+
+		CGHeroInstance * pickHeroFor(bool native, int player, const CTown *town, int notThatOne=-1);
 	} hpool; //we have here all heroes available on this map that are not hired
 
 	boost::shared_mutex *mx;

+ 1 - 1
CHeroWindow.cpp

@@ -231,7 +231,7 @@ void CHeroWindow::setHero(const CGHeroInstance *Hero)
 		secSkillAreas[g]->hoverText = std::string(bufor);
 	}
 
-	sprintf(bufor, CGI->generaltexth->allTexts[2].substr(1, CGI->generaltexth->allTexts[2].size()-2).c_str(), hero->level, CGI->heroh->reqExp(hero->level+1), hero->exp);
+	sprintf(bufor, CGI->generaltexth->allTexts[2].c_str(), hero->level, CGI->heroh->reqExp(hero->level+1), hero->exp);
 	expArea->text = std::string(bufor);
 
 	sprintf(bufor, CGI->generaltexth->allTexts[205].substr(1, CGI->generaltexth->allTexts[205].size()-2).c_str(), hero->name.c_str(), hero->mana, hero->getPrimSkillLevel(3)*10);

+ 1 - 1
CLua.cpp

@@ -310,7 +310,7 @@ void CVisitableOPH::onNAHeroVisit(int objid, int heroID, bool alreadyVisited)
 		case 102:
 			{
 				const CGHeroInstance *h = cb->getHero(heroID);
-				val = VLC->heroh->reqExp(h->level) + VLC->heroh->reqExp(h->level+val);
+				val = VLC->heroh->reqExp(h->level+val) - VLC->heroh->reqExp(h->level);
 				if(!typeOfTree[objid])
 				{
 					visitors[objid].insert(heroID);

+ 1 - 1
CMT.cpp

@@ -277,7 +277,7 @@ void processCommand(const std::string &message, CClient *&client)
 		boost::filesystem::create_directory("Extracted_txts");
 		tlog0<<"Command accepted. Opening .lod file...\t";
 		CLodHandler * txth = new CLodHandler;
-		txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"data");
+		txth->init(std::string(DATA_DIR "Data" PATHSEPARATOR "H3bitmap.lod"),"");
 		tlog0<<"done.\nScanning .lod file\n";
 		int curp=0;
 		std::string pattern = ".TXT", pom;

+ 12 - 7
CPlayerInterface.cpp

@@ -2086,9 +2086,9 @@ void CPlayerInterface::battleStackAttacked(BattleStackAttacked * bsa)
 		battleInt->displayEffect(bsa->effect, cb->battleGetStackByID(bsa->stackAttacked)->position, cb->battleGetStackByID(bsa->stackAttacked)->attackerOwned);
 	}
 	if(bsa->killed())
-		battleInt->stackKilled(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, -1, false);
+		battleInt->stackKilled(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7 );
 	else
-		battleInt->stackIsAttacked(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, -1, false);
+		battleInt->stackIsAttacked(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7);
 }
 void CPlayerInterface::battleAttack(BattleAttack *ba)
 {
@@ -3129,7 +3129,7 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
 	anim = new CCreaturePic(c);
 	if(!type) anim->anim->setType(1);
 
-	char pom[25];int hlp=0;
+	char pom[75];int hlp=0;
 
 	if(creatureCount)
 	{
@@ -3169,7 +3169,10 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount, StackState
 	if(c->shots)
 	{
 		printAt(CGI->generaltexth->allTexts[198],155,86,GEOR13,zwykly,bitmap);
-		SDL_itoa(c->shots,pom,10);
+		if(State)
+			sprintf(pom,"%d(%d)",c->shots,State->shotsLeft);
+		else
+			SDL_itoa(c->shots,pom,10);
 		printToWR(pom,276,99,GEOR13,zwykly,bitmap);
 	}
 
@@ -3930,8 +3933,10 @@ void CTavernWindow::show(SDL_Surface * to)
 	
 	HeroPortrait *sel = selected ? &h2 : &h1;
 	char descr[300];
-	int artifs = sel->h->artifWorn.size()+sel->h->artifacts.size() - 1; //artifacts amount; - 1 is for catapult
-	if(vstd::contains(sel->h->artifWorn,0)) artifs--; //spellbook doesn't count neither
+	int artifs = sel->h->artifWorn.size()+sel->h->artifacts.size();
+	for(int i=13; i<=17; i++) //war machines and spellbook doesn't count
+		if(vstd::contains(sel->h->artifWorn,i)) 
+			artifs--;
 	sprintf_s(descr,300,CGI->generaltexth->allTexts[215].c_str(),
 		sel->h->name.c_str(),sel->h->level,sel->h->type->heroClass->name.c_str(),artifs);
 	printAtMiddleWB(descr,pos.x+146,pos.y+389,GEOR13,40,zwykly,screen);
@@ -3984,4 +3989,4 @@ CTavernWindow::HeroPortrait::HeroPortrait(int &sel, int id, int x, int y, const
 void CTavernWindow::HeroPortrait::show(SDL_Surface * to)
 {
 	blitAt(graphics->portraitLarge[h->subID],pos);
-}
+}

+ 14 - 17
hch/CCreatureHandler.cpp

@@ -64,6 +64,7 @@ si32 CCreature::maxAmount(const std::vector<si32> &res) const //how many creatur
 void CCreatureHandler::loadCreatures()
 {
 	notUsedMonsters += 122,124,126,128,145,146,147,148,149,160,161,162,163,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191;
+	tlog5 << "\t\tReading ZCRTRAIT.TXT" << std::endl;
 	std::string buf = bitmaph->getTextFile("ZCRTRAIT.TXT");
 	int andame = buf.size();
 	int i=0; //buf iterator
@@ -319,21 +320,11 @@ void CCreatureHandler::loadCreatures()
 		if(ncre.nameSing!=std::string("") && ncre.namePl!=std::string(""))
 		{
 			ncre.idNumber = creatures.size();
-			ncre.isDefinite = true;
 			creatures.push_back(ncre);
 		}
 	}
-	for(int bb=1; bb<8; ++bb)
-	{
-		CCreature ncre;
-		ncre.isDefinite = false;
-		ncre.indefLevel = bb;
-		ncre.indefUpgraded = false;
-		creatures.push_back(ncre);
-		ncre.indefUpgraded = true;
-		creatures.push_back(ncre);
-	}
 
+	tlog5 << "\t\tReading config/crerefnam.txt" << std::endl;
 	//loading reference names
 	std::ifstream ifs("config/crerefnam.txt");
 	int tempi;
@@ -350,6 +341,8 @@ void CCreatureHandler::loadCreatures()
 	ifs.clear();
 	for(int i=1;i<=10;i++)
 		levelCreatures.insert(std::pair<int,std::vector<CCreature*> >(i,std::vector<CCreature*>()));
+
+	tlog5 << "\t\tReading config/monsters.txt" << std::endl;
 	ifs.open("config/monsters.txt");
 	{
 		while(!ifs.eof())
@@ -366,6 +359,7 @@ void CCreatureHandler::loadCreatures()
 	ifs.close();
 	ifs.clear();
 
+	tlog5 << "\t\tReading config/cr_factions.txt" << std::endl;
 	ifs.open("config/cr_factions.txt");
 	while(!ifs.eof())
 	{
@@ -376,6 +370,7 @@ void CCreatureHandler::loadCreatures()
 	ifs.close();
 	ifs.clear();
 
+	tlog5 << "\t\tReading config/cr_upgrade_list.txt" << std::endl;
 	ifs.open("config/cr_upgrade_list.txt");
 	while(!ifs.eof())
 	{
@@ -387,6 +382,7 @@ void CCreatureHandler::loadCreatures()
 	ifs.clear();
 
 	//loading unit animation def names
+	tlog5 << "\t\tReading config/CREDEFS.TXT" << std::endl;
 	std::ifstream inp("config/CREDEFS.TXT", std::ios::in | std::ios::binary); //this file is not in lod
 	inp.seekg(0,std::ios::end); // na koniec
 	int andame2 = inp.tellg();  // read length
@@ -395,11 +391,7 @@ void CCreatureHandler::loadCreatures()
 	inp.read((char*)bufor, andame2); // read map file to buffer
 	inp.close();
 	buf = std::string(bufor);
-#ifndef __GNUC__
-	delete [andame2] bufor;
-#else
 	delete [] bufor;
-#endif
 
 	i = 0; //buf iterator
 	hmcr = 0;
@@ -409,8 +401,10 @@ void CCreatureHandler::loadCreatures()
 			break;
 	}
 	i+=2;
-	for(int s=0; s<creatures.size()-16; ++s)
+	tlog5 << "We have "<<creatures.size() << " creatures\n";
+	for(int s=0; s<creatures.size(); ++s)
 	{
+		//tlog5 <<"\t\t\t" << s <<". Reading defname. \n";
 		int befi=i;
 		std::string rub;
 		for(i; i<andame2; ++i)
@@ -430,10 +424,12 @@ void CCreatureHandler::loadCreatures()
 		std::string defName = buf.substr(befi, i-befi);
 		creatures[s].animDefName = defName;
 	}
+	tlog5 << "\t\tReading CRANIM.TXT.txt" << std::endl;
 	loadAnimationInfo();
 
 	//loading id to projectile mapping
 
+	tlog5 << "\t\tReading config/cr_shots.txt" << std::endl;
 	std::ifstream inp2("config" PATHSEPARATOR "cr_shots.txt", std::ios::in | std::ios::binary); //this file is not in lod
 	char dump [200];
 	inp2.getline(dump, 200);
@@ -474,8 +470,9 @@ void CCreatureHandler::loadAnimationInfo()
 			break;
 	}
 	i+=2;
-	for(int dd=0; dd<creatures.size()-16; ++dd)
+	for(int dd=0; dd<creatures.size(); ++dd)
 	{
+		//tlog5 << "\t\t\tReading animation info for creature " << dd << std::endl;
 		loadUnitAnimInfo(creatures[dd], buf, i);
 	}
 	return;

+ 0 - 7
hch/CCreatureHandler.h

@@ -32,13 +32,6 @@ public:
 	int troopCountLocationOffset, attackClimaxFrame;
 	///end of anim info
 
-	//for some types of towns
-	bool isDefinite; //if the creature type is wotn dependent, it should be true
-	int indefLevel; //only if indefinite
-	bool indefUpgraded; //onlu if inddefinite
-
-	//TODO - zdolnoœci (abilities) - na typie wyliczeniowym czy czymœ - albo lepiej secie czegoœ
-
 	bool isDoubleWide() const; //returns true if unit is double wide on battlefield
 	bool isFlying() const; //returns true if it is a flying unit
 	bool isShooting() const; //returns true if unit can shoot

+ 3 - 2
lib/NetPacks.h

@@ -143,12 +143,13 @@ struct FoWChange : public CPack<FoWChange> //112
 
 struct SetAvailableHeroes : public CPack<SetAvailableHeroes> //113
 {
-	SetAvailableHeroes(){type = 113;};
+	SetAvailableHeroes(){type = 113;flags=0;};
 	ui8 player;
 	ui32 hid1, hid2;
+	ui8 flags; //1 - reset army of hero1; 2 - reset army of hero 2
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & player & hid1 & hid2;
+		h & player & hid1 & hid2 & flags;
 	}
 };
 

+ 42 - 24
server/CGameHandler.cpp

@@ -987,6 +987,11 @@ upgend:
 										fc.tiles.insert(int3(i,j,k));
 						sendAndApply(&fc);
 					}
+					else if(message == "vcmiglorfindel")
+					{
+						CGHeroInstance *hero = gs->getHero(gs->players[*players.begin()].currentSelection);
+						changePrimSkill(hero->id,4,VLC->heroh->reqExp(hero->level+1) - VLC->heroh->reqExp(hero->level));
+					}
 					else
 						cheated = false;
 					if(cheated)
@@ -1019,12 +1024,26 @@ upgend:
 					  )
 						break;
 					CGHeroInstance *nh = gs->players[t->tempOwner].availableHeroes[hid];
+
 					HeroRecruited hr;
 					hr.tid = tid;
 					hr.hid = nh->subID;
 					hr.player = t->tempOwner;
 					hr.tile = t->pos - int3(1,0,0);
 					sendAndApply(&hr);
+
+					SetAvailableHeroes sah;
+					(hid ? sah.hid2 : sah.hid1) = gs->hpool.pickHeroFor(false,t->tempOwner,t->town)->subID;
+					(hid ? sah.hid1 : sah.hid2) = gs->players[t->tempOwner].availableHeroes[!hid]->subID;
+					sah.player = t->tempOwner;
+					sah.flags = hid+1;
+					sendAndApply(&sah);
+
+					SetResource sr;
+					sr.player = t->tempOwner;
+					sr.resid = 6;
+					sr.val = gs->players[t->tempOwner].resources[6] - 2500;
+					sendAndApply(&sr);
 					break;
 				}
 			case 2001:
@@ -1075,8 +1094,9 @@ upgend:
 							CStack *curStack = gs->curB->getStack(ba.stackNumber),
 								*stackAtEnd = gs->curB->getStackT(ba.additionalInfo);
 
-							if((curStack->position != ba.destinationTile) || //we wasn't able to reach destination tile
-								(BattleInfo::mutualPosition(ba.destinationTile,ba.additionalInfo)<0) ) //destination tile is not neighbouring with enemy stack
+							if( curStack->position != ba.destinationTile //we wasn't able to reach destination tile
+							  || BattleInfo::mutualPosition(ba.destinationTile,ba.additionalInfo) < 0 //destination tile is not neighbouring with enemy stack
+							  ) 
 								return;
 
 							BattleAttack bat;
@@ -1105,25 +1125,33 @@ upgend:
 						}
 					case 7: //shoot
 						{
-							//TODO: check arrows count
-							//TODO: check if stack isn't blocked by enemy
-
-							sendAndApply(&StartAction(ba)); //start shooting
 							CStack *curStack = gs->curB->getStack(ba.stackNumber),
 								*destStack= gs->curB->getStackT(ba.destinationTile);
+							if(!curStack //our stack exists
+							  || !destStack //there is a stack at destination tile
+							  || !curStack->shots //stack has shots
+							  || gs->curB->isStackBlocked(curStack->ID) //we are not blocked
+							  || !vstd::contains(curStack->abilities,SHOOTER) //our stack is shooting unit
+							  )
+								break;
+
+							sendAndApply(&StartAction(ba)); //start shooting
 
 							BattleAttack bat;
 							prepareAttack(bat,curStack,destStack);
 							bat.flags |= 1;
+							sendAndApply(&bat);
 
-							if(vstd::contains(curStack->abilities,TWICE_ATTACK)
-								&& curStack->alive())
+							if(vstd::contains(curStack->abilities,TWICE_ATTACK) //if unit shots twice let's make another shot
+							  && curStack->alive()
+							  && destStack->alive()
+							  && curStack->shots
+							  )
 							{
 								prepareAttack(bat,curStack,destStack);
 								sendAndApply(&bat);
 							}
 
-							sendAndApply(&bat);
 							sendDataToClients(ui16(3008)); //end shooting
 							break;
 						}
@@ -1335,25 +1363,15 @@ void CGameHandler::newTurn()
 
 	for ( std::map<ui8, PlayerState>::iterator i=gs->players.begin() ; i!=gs->players.end();i++)
 	{
+		if(i->first == 255) continue;
 		if(gs->getDate(1)==7) //first day of week - new heroes in tavern
 		{
 			SetAvailableHeroes sah;
 			sah.player = i->first;
-			int r;
-			if(!gs->hpool.heroesPool.size()) return;
-			for(int a=0;a<2;a++)
-			{
-				r = rand() % gs->hpool.heroesPool.size();
-				std::map<ui32,CGHeroInstance *>::iterator ch = gs->hpool.heroesPool.begin();
-				while(r--) ch++;
-				if(a) sah.hid2 = ch->first;
-				else sah.hid1 = ch->first;
-			}
+			//TODO: - will fail when there are not enough available heroes
+			sah.hid1 = gs->hpool.pickHeroFor(true,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle])->subID;
+			sah.hid2 = gs->hpool.pickHeroFor(false,i->first,&VLC->townh->towns[gs->scenarioOps->getIthPlayersSettings(i->first).castle],sah.hid1)->subID;
 			sendAndApply(&sah);
-			//TODO: guarantee that heroes are different
-			//TODO: first hero should be from initial player town
-			//TODO: use selectionProbability from CHeroClass
-			//int town = gs->scenarioOps->getIthPlayersSettings(i->first).castle;
 		}
 		if(i->first>=PLAYER_LIMIT) continue;
 		SetResources r;
@@ -1369,7 +1387,7 @@ void CGameHandler::newTurn()
 			hth.mana = std::max(h->mana,std::min(h->mana+1+h->getSecSkillLevel(8), h->manaLimit())); //hero regains 1 mana point + mysticism lvel
 			n.heroes.insert(hth);
 			
-			switch(h->getSecSkillLevel(13)) //handle estates - give gols
+			switch(h->getSecSkillLevel(13)) //handle estates - give gold
 			{
 			case 1: //basic
 				r.res[6] += 125;