Browse Source

* fixed crash when there was flaggable building next to map edge
* increased char per line limit for subtitles under components
* saves are sorted primary by map format, secondary by name
* fixed displaying date of saved game (uses local time, removed square character)
* removed redundant quotation marks from artifact events text
* corrected some exp/level values
* primary skills cannot negative values
* fixed crash on entering hall when town was near map edge
* workaround to prevent crashes when gaining same sec skill on leveling serie
* fixed displaying luck effect animation
* minor improvements

Michał W. Urbańczyk 16 years ago
parent
commit
64d9665c39

+ 3 - 2
client/CAdvmapInterface.cpp

@@ -329,7 +329,8 @@ void CMinimap::showTile(const int3 &pos)
 		if(!dynamic_cast< const CGHeroInstance * >(oo[v])) //heroes have been printed
 		{
 			int3 maplgp ( (pos.x*mw)/mapSizes.x, (pos.y*mh)/mapSizes.y, pos.z );
-			if(((int)wo) * mapSizes.x != mw) //miniap size in X is not multiple of map size in X
+			if(((int)wo) * mapSizes.x != mw   &&   pos.x+1 < mapSizes.x)//minimap size in X is not multiple of map size in X
+				 
 			{
 				std::vector < const CGObjectInstance * > op1x = LOCPLINT->cb->getFlaggableObjects(int3(pos.x+1, pos.y, pos.z));
 				if(op1x.size()!=0)
@@ -341,7 +342,7 @@ void CMinimap::showTile(const int3 &pos)
 					woShifted = wo;
 				}
 			}
-			if(((int)ho) * mapSizes.y != mh) //miniap size in Y is not multiple of map size in Y
+			if(((int)ho) * mapSizes.y != mh   &&   pos.y+1 < mapSizes.y) //minimap size in Y is not multiple of map size in Y
 			{
 				std::vector < const CGObjectInstance * > op1y = LOCPLINT->cb->getFlaggableObjects(int3(pos.x, pos.y+1, pos.z));
 				if(op1y.size()!=0)

+ 4 - 3
client/CMessage.cpp

@@ -355,8 +355,9 @@ void CMessage::drawIWindow(CInfoWindow * ret, std::string text, int player, int
 	SDL_Surface * _or = NULL;
 	int fontHeight;
 
-	// Try to compute a resonable number of characters per line
-	if (!charperline) {
+	// Try to compute a reasonable number of characters per line
+	if (!charperline) 
+	{
 		if (text.size() < 30)
 			charperline = 30;
 		else if (text.size() < 200)
@@ -537,7 +538,7 @@ ComponentResolved::ComponentResolved( SComponent *Comp )
 {
 	comp = Comp;
 	img = comp->getImg();
-	std::vector<std::string> * brtext = CMessage::breakText(comp->subtitle,11,true,true); //text 
+	std::vector<std::string> * brtext = CMessage::breakText(comp->subtitle,13,true,true); //text 
 	txt = CMessage::drawText(brtext,txtFontHeight,GEOR13);
 	delete brtext;
 

+ 8 - 5
client/CPreGame.cpp

@@ -911,7 +911,8 @@ void MapSel::printMaps(int elemIdx)
 
 	for (int line=0; line<slid->capacity; elemIdx++)
 	{
-		if (elemIdx >= selMaps.size()) {
+		if (elemIdx >= selMaps.size()) 
+		{
 			// No elements left to display, so it's an empty line.
 			SDL_BlitSurface(bg, &genRect(25, 351, 22, 115+line*25), scenin, NULL);
 			blitAt(scenin, 25, 121+line*25);
@@ -1248,7 +1249,8 @@ void MapSel::init()
 				}
 				pliczkiTemp.push_back("Games/"+(dir->path().leaf()));
 				std::time_t time = fs::last_write_time(dir->path());
-				datestemp.push_back(std::asctime(std::gmtime(&time)));
+				datestemp.push_back(std::asctime(std::localtime(&time)));
+				boost::algorithm::trim_right(datestemp.back()); //removes following \n
 			}
 		}
 	}
@@ -1261,6 +1263,7 @@ void MapSel::init()
 	maps = std::remove_if(ourGames.begin(),ourGames.end(),isNull);
 	ourGames.erase(maps,ourGames.end());
 	std::sort(ourGames.begin(),ourGames.end(),mapSorter(_name));
+	std::sort(ourGames.begin(),ourGames.end(),mapSorter(_format));
 }
 
 // Move the list up or down by a specified amount (positive or negative).
@@ -1316,7 +1319,7 @@ void MapSel::select(int which, bool updateMapsList, bool forceSettingsUpdate)
 			if (!(selMaps[selected]->players[i].canComputerPlay 
 				|| selMaps[selected]->players[i].canComputerPlay)	
 			  )
-				continue; // this caused some serious problems becouse of lack of simple bijection between two sets of player's numbers (one is returned by CPreGame, second is used in h3m)
+				continue; // this caused some serious problems because of lack of simple bijection between two sets of player's numbers (one is returned by CPreGame, second is used in h3m)
 			PlayerSettings pset;
 			pset.color=(Ecolor)i;
 			pset.serial = serialC;
@@ -1638,6 +1641,8 @@ void CPreGame::showScenSel()
 	//add buttons info
 	if(first)
 	{
+		ourScenSel->mapsel.select(0,false);
+
 		if(fromMenu==newGame)
 		{
 			btns.push_back(&ourScenSel->bEasy);
@@ -1657,8 +1662,6 @@ void CPreGame::showScenSel()
 		ourScenSel->selectedDiff=1;
 		ourScenSel->bNormal.select(true);
 		handleOther = &CPreGame::scenHandleEv;
-		ourScenSel->mapsel.select(0,false);
-
 
 		for (size_t i=0; i < btns.size(); ++i)
 		{

+ 8 - 6
hch/CGeneralTextHandler.cpp

@@ -329,8 +329,8 @@ void CGeneralTextHandler::load()
 	for(int jj=0; jj<764; ++jj)
 	{
 		loadToIt(buflet, buf, i, 2);
-		if(buflet[0] == '"'  &&  buflet[buflet.size()-1] == '"')
-			buflet = buflet.substr(1,buflet.size()-2);
+		trimQuotation(buflet);
+		boost::algorithm::replace_all(temp,"\"\"","\"");
 		allTexts.push_back(buflet);
 	}
 
@@ -340,8 +340,7 @@ void CGeneralTextHandler::load()
 	while(itr<strs.length()-1)
 	{
 		loadToIt(tmp, strs, itr, 3);
-		if(tmp[0] == '"' && tmp[tmp.size()-1] == '"')
-			tmp = tmp.substr(1,tmp.size()-2);
+		trimQuotation(tmp);
 		arraytxt.push_back(tmp);
 	}
 
@@ -377,10 +376,13 @@ void CGeneralTextHandler::load()
 		heroscrn.push_back(tmp);
 	}
 
+	itr = 0;
 	strin = bitmaph->getTextFile("ARTEVENT.TXT");
-	for(itr = 0; itr<strin.size();itr++)
+	for(; itr<strin.size();)
 	{
-		loadToIt(tmp, strin, itr, 3);
+		loadToIt(tmp, strin, itr, 2);
+	//	boost::algorithm::trim(tmp);
+		trimQuotation(tmp);
 		artifEvents.push_back(tmp);
 	}
 

+ 11 - 11
hch/CHeroHandler.cpp

@@ -272,17 +272,17 @@ void CHeroHandler::loadHeroes()
 	expPerLevel.push_back(1000);
 	expPerLevel.push_back(2000);
 	expPerLevel.push_back(3200);
-	expPerLevel.push_back(4500);
-	expPerLevel.push_back(6000);
-	expPerLevel.push_back(7700);
-	expPerLevel.push_back(9000);
-	expPerLevel.push_back(11000);
-	expPerLevel.push_back(13200);
-	expPerLevel.push_back(15500);
-	expPerLevel.push_back(18500);
-	expPerLevel.push_back(22100);
-	expPerLevel.push_back(26420);
-	expPerLevel.push_back(31604);
+	expPerLevel.push_back(4600);
+	expPerLevel.push_back(6200);
+	expPerLevel.push_back(8000);
+	expPerLevel.push_back(10000);
+	expPerLevel.push_back(12200);
+	expPerLevel.push_back(14700);
+	expPerLevel.push_back(17500);
+	expPerLevel.push_back(20600);
+	expPerLevel.push_back(24320);
+	expPerLevel.push_back(28784);
+	expPerLevel.push_back(34140);
 
 	//ballistics info
 	buf = bitmaph->getTextFile("BALLIST.TXT");

+ 2 - 2
hch/CHeroHandler.h

@@ -41,7 +41,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & name & ID & lowStack & highStack & refTypeStack	& heroType & ID & startingSpell;
+		h & name & ID & lowStack & highStack & refTypeStack	& heroType & startingSpell;
 		//hero class pointer is restored by herohandler
 	}
 };
@@ -126,7 +126,7 @@ public:
 
 	template <typename Handler> void serialize(Handler &h, const int version)
 	{
-		h & heroClasses & heroes & expPerLevel & ballistics & obstacles;
+		h & heroClasses & heroes & expPerLevel & ballistics & obstacles & nativeTerrains;
 		if(!h.saving)
 		{
 			//restore class pointers

+ 6 - 7
hch/CObjectHandler.cpp

@@ -371,6 +371,7 @@ int CGHeroInstance::getPrimSkillLevel(int id) const
 	for(std::list<HeroBonus>::const_iterator i=bonuses.begin(); i != bonuses.end(); i++)
 		if(i->type == HeroBonus::PRIMARY_SKILL && i->subtype==id)
 			ret += i->val;
+	amax(ret, id/2);//minimum value for attack and defense is 0 and for spell power and knowledge - 1
 	return ret;
 }
 ui8 CGHeroInstance::getSecSkillLevel(const int & ID) const
@@ -3035,13 +3036,6 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
 	}
 	else //first visit - give bonus!
 	{
-		if(ID == 105  &&  artOrRes == 1) 
-		{
-			txtid++;
-			iw.text.addReplacement(MetaString::ART_NAMES, bonusType);
-		}
-
-
 		switch(artOrRes)
 		{
 		case 0:
@@ -3058,6 +3052,11 @@ void CGOnceVisitable::onHeroVisit( const CGHeroInstance * h ) const
 		}
 
 		iw.text.addTxt(MetaString::ADVOB_TXT, txtid);
+		if(ID == 105  &&  artOrRes == 1) 
+		{
+			iw.text.localStrings.back().second++;
+			iw.text.addReplacement(MetaString::ART_NAMES, bonusType);
+		}
 	}
 
 	cb->showInfoDialog(&iw);

+ 4 - 1
lib/CGameState.cpp

@@ -1623,7 +1623,10 @@ int CGameState::canBuildStructure( const CGTownInstance *t, int ID )
 	}
 	else if(ID == 6) //shipyard
 	{
-		if(map->getTile(t->pos + int3(-1,3,0)).tertype != TerrainTile::water  &&  map->getTile(t->pos + int3(-3,3,0)).tertype != TerrainTile::water)
+		int3 t1(t->pos + int3(-1,3,0)),
+			t2(t->pos + int3(-3,3,0));
+		if(map->isInTheMap(t1) && map->getTile(t1).tertype != TerrainTile::water  
+			&&  (map->isInTheMap(t2) && map->getTile(t2).tertype != TerrainTile::water))
 			ret = 1; //lack of water
 	}
 

+ 1 - 1
lib/Connection.h

@@ -19,7 +19,7 @@
 #include <boost/mpl/identity.hpp>
 
 #include <boost/type_traits/is_array.hpp>
-const ui32 version = 705;
+const ui32 version = 706;
 class CConnection;
 namespace mpl = boost::mpl;
 

+ 6 - 0
lib/NetPacksLib.cpp

@@ -79,6 +79,12 @@ DLL_EXPORT void SetSecSkill::applyGs( CGameState *gs )
 					hero->secSkills[i].second = val;
 				else
 					hero->secSkills[i].second += val;
+
+				if(hero->secSkills[i].second > 3) //workaround to avoid crashes when same sec skill is given more than once
+				{
+					tlog1 << "Warning: Skill " << which << " increased over limit! Decreasing to Expert.\n";
+					hero->secSkills[i].second = 3;
+				}
 			}
 		}
 	}

+ 7 - 4
server/CGameHandler.cpp

@@ -478,7 +478,7 @@ void CGameHandler::prepareAttack(BattleAttack &bat, CStack *att, CStack *def)
 	if(att->Luck() > 0  &&  rand()%24 < att->Luck())
 	{
 		bsa->damageAmount *= 2;
-		bsa->flags |= 4;
+		bat.flags |= 4;
 	}
 	prepareAttacked(*bsa,def);
 }
@@ -2593,13 +2593,16 @@ void CGameHandler::handleTimeEvents()
 				{
 					if(ev->resources[i]) //if resource is changed, we add it to the dialog
 					{
-						// If removing too much ressources, adjust the
+						// If removing too much resources, adjust the
 						// amount so the total doesn't become negative.
 						if (sr.res[i] + ev->resources[i] < 0)
 							ev->resources[i] = -sr.res[i];
 
-						iw.components.push_back(Component(Component::RESOURCE,i,ev->resources[i],0));
-						sr.res[i] += ev->resources[i];
+						if(ev->resources[i]) //if non-zero res change
+						{
+							iw.components.push_back(Component(Component::RESOURCE,i,ev->resources[i],0));
+							sr.res[i] += ev->resources[i];
+						}
 					}
 				}
 				if (iw.components.size())