Преглед изворни кода

* lightning bolt and ice bolt spells
* displayEffect shows animations on more correct places
* removed three magic numbers (now they're BFIELD_WIDTH, BFIELD_HEIGHT and BFIELD_SIZE macros)
* minor changes

mateuszb пре 17 година
родитељ
комит
6b9146f998
9 измењених фајлова са 131 додато и 76 уклоњено
  1. 63 43
      CBattleInterface.cpp
  2. 3 3
      CBattleInterface.h
  3. 17 17
      CGameState.cpp
  4. 3 3
      CGameState.h
  5. 1 1
      CPlayerInterface.cpp
  6. 1 1
      config/AC_desc.txt
  7. 7 2
      global.h
  8. 6 2
      mapHandler.cpp
  9. 30 4
      server/CGameHandler.cpp

+ 63 - 43
CBattleInterface.cpp

@@ -34,9 +34,9 @@ extern SDL_Color zwykly;
 class CMP_stack2
 {
 public:
-	bool operator ()(const CStack& a, const CStack& b)
+	inline bool operator ()(const CStack& a, const CStack& b)
 	{
-		return (a.creature->speed)>(b.creature->speed);
+		return (a.speed())>(b.speed());
 	}
 } cmpst2 ;
 
@@ -127,12 +127,12 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
 	CSDL_Ext::alphaTransform(cellBorder);
 	cellShade = BitmapHandler::loadBitmap("CCELLSHD.BMP");
 	CSDL_Ext::alphaTransform(cellShade);
-	for(int h=0; h<187; ++h)
+	for(int h=0; h<BFIELD_SIZE; ++h)
 	{
 		bfield[h].myNumber = h;
 
-		int x = 14 + ((h/17)%2==0 ? 22 : 0) + 44*(h%17);
-		int y = 86 + 42 * (h/17);
+		int x = 14 + ((h/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(h%BFIELD_WIDTH);
+		int y = 86 + 42 * (h/BFIELD_WIDTH);
 		bfield[h].pos = genRect(cellShade->h, cellShade->w, x, y);
 		bfield[h].accesible = true;
 		bfield[h].myInterface = this;
@@ -177,9 +177,9 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
 		cellBorders->format->palette->colors[g] = cellBorder->format->palette->colors[g];
 	}
 	//palette copied
-	for(int i=0; i<11; ++i) //rows
+	for(int i=0; i<BFIELD_HEIGHT; ++i) //rows
 	{
-		for(int j=0; j<15; ++j) //columns
+		for(int j=0; j<BFIELD_WIDTH-2; ++j) //columns
 		{
 			int x = 58 + (i%2==0 ? 22 : 0) + 44*j;
 			int y = 86 + 42 * i;
@@ -262,7 +262,7 @@ void CBattleInterface::activate()
 	bDefence->activate();
 	bConsoleUp->activate();
 	bConsoleDown->activate();
-	for(int b=0; b<187; ++b)
+	for(int b=0; b<BFIELD_SIZE; ++b)
 	{
 		bfield[b].activate();
 	}
@@ -285,7 +285,7 @@ void CBattleInterface::deactivate()
 	bDefence->deactivate();
 	bConsoleUp->deactivate();
 	bConsoleDown->deactivate();
-	for(int b=0; b<187; ++b)
+	for(int b=0; b<BFIELD_SIZE; ++b)
 	{
 		bfield[b].deactivate();
 	}
@@ -319,12 +319,12 @@ void CBattleInterface::show(SDL_Surface * to)
 	//printing hovered cell
 	if(printMouseShadow)
 	{
-		for(int b=0; b<187; ++b)
+		for(int b=0; b<BFIELD_SIZE; ++b)
 		{
 			if(bfield[b].strictHovered && bfield[b].hovered)
 			{
-				int x = 14 + ((b/17)%2==0 ? 22 : 0) + 44*(b%17);
-				int y = 86 + 42 * (b/17);
+				int x = 14 + ((b/BFIELD_WIDTH)%2==0 ? 22 : 0) + 44*(b%BFIELD_WIDTH);
+				int y = 86 + 42 * (b/BFIELD_WIDTH);
 				CSDL_Ext::blit8bppAlphaTo24bpp(cellShade, NULL, to, &genRect(cellShade->h, cellShade->w, x, y));
 			}
 		}
@@ -353,14 +353,14 @@ void CBattleInterface::show(SDL_Surface * to)
 		defendingHero->show(to);
 
 	////showing units //a lot of work...
-	std::vector<int> stackAliveByHex[187];
+	std::vector<int> stackAliveByHex[BFIELD_SIZE];
 	//double loop because dead stacks should be printed first
 	for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
 	{
 		if(j->second.alive())
 			stackAliveByHex[j->second.position].push_back(j->second.ID);
 	}
-	std::vector<int> stackDeadByHex[187];
+	std::vector<int> stackDeadByHex[BFIELD_SIZE];
 	for(std::map<int, CStack>::iterator j=stacks.begin(); j!=stacks.end(); ++j)
 	{
 		if(!j->second.alive())
@@ -369,7 +369,7 @@ void CBattleInterface::show(SDL_Surface * to)
 
 	attackingShowHelper(); // handle attack animation
 
-	for(int b=0; b<187; ++b) //showing dead stacks
+	for(int b=0; b<BFIELD_SIZE; ++b) //showing dead stacks
 	{
 		for(int v=0; v<stackDeadByHex[b].size(); ++v)
 		{
@@ -386,7 +386,7 @@ void CBattleInterface::show(SDL_Surface * to)
 			}
 		}
 	}
-	for(int b=0; b<187; ++b) //showing alive stacks
+	for(int b=0; b<BFIELD_SIZE; ++b) //showing alive stacks
 	{
 		for(int v=0; v<stackAliveByHex[b].size(); ++v)
 		{
@@ -493,7 +493,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 	if(activeStack>=0 && !spellDestSelectMode)
 	{
 		int myNumber = -1; //number of hovered tile
-		for(int g=0; g<187; ++g)
+		for(int g=0; g<BFIELD_SIZE; ++g)
 		{
 			if(bfield[g].hovered && bfield[g].strictHovered)
 			{
@@ -519,7 +519,7 @@ void CBattleInterface::mouseMoved(const SDL_MouseMotionEvent &sEvent)
 					else if(isTileAttackable(myNumber)) //available enemy (melee attackable)
 					{
 						int fromHex = -1;
-						for(int b=0; b<187; ++b)
+						for(int b=0; b<BFIELD_SIZE; ++b)
 							if(bfield[b].hovered && !bfield[b].strictHovered)
 							{
 								fromHex = b;
@@ -1059,7 +1059,7 @@ void CBattleInterface::giveCommand(ui8 action, ui16 tile, ui32 stack, si32 addit
 	activeStack = -1;
 }
 
-bool CBattleInterface::isTileAttackable(int number)
+bool CBattleInterface::isTileAttackable(const int & number) const
 {
 	for(int b=0; b<shadedHexes.size(); ++b)
 	{
@@ -1090,26 +1090,20 @@ void CBattleInterface::hexLclicked(int whichOne)
 			if(!dest || !dest->alive()) //no creature at that tile
 			{
 				if(std::find(shadedHexes.begin(),shadedHexes.end(),whichOne)!=shadedHexes.end())// and it's in our range
+				{
+					CGI->curh->changeGraphic(1, 6); //cursor should be changed
 					giveCommand(2,whichOne,activeStack);
+				}
 			}
 			else if(dest->owner != attackingHeroInstance->tempOwner
 				&& LOCPLINT->cb->battleCanShoot(activeStack, whichOne)
 				&& BattleInfo::mutualPosition(LOCPLINT->cb->battleGetPos(activeStack),whichOne) < 0 ) //shooting
 			{
+				CGI->curh->changeGraphic(1, 6); //cursor should be changed
 				giveCommand(7,whichOne,activeStack);
 			}
 			else if(dest->owner != attackingHeroInstance->tempOwner) //attacking
 			{
-				//std::vector<int> n = BattleInfo::neighbouringTiles(whichOne);
-				//for(int i=0;i<n.size();i++)
-				//{
-				//	//TODO: now we are using first available tile, but in the future we should add possibility of choosing from which tile we want to attack
-				//	if(vstd::contains(shadedHexes,n[i]))
-				//	{
-				//		giveCommand(6,n[i],activeStack,whichOne);
-				//		return;
-				//	}
-				//}
 				switch(CGI->curh->number)
 				{
 				case 12:
@@ -1131,6 +1125,7 @@ void CBattleInterface::hexLclicked(int whichOne)
 					giveCommand(6,whichOne + 1,activeStack,whichOne);
 					break;
 				}
+				CGI->curh->changeGraphic(1, 6); //cursor should be changed
 			}
 		}
 	}
@@ -1223,13 +1218,23 @@ void CBattleInterface::battleFinished(const BattleResult& br)
 
 void CBattleInterface::spellCasted(SpellCasted * sc)
 {
+	std::vector< std::string > anims; //for magic arrow and ice bolt
 	switch(sc->id)
 	{
 	case 15: //magic arrow
 		{
-			//initial variables
-			std::vector< std::string > anims;
+			//initialization of anims
 			anims.push_back("C20SPX0.DEF"); anims.push_back("C20SPX1.DEF"); anims.push_back("C20SPX2.DEF"); anims.push_back("C20SPX3.DEF"); anims.push_back("C20SPX4.DEF");
+		}
+	case 16: //ice bolt
+		{
+			if(anims.size() == 0) //initialiaztion of anims
+			{
+				anims.push_back("C08SPW0.DEF"); anims.push_back("C08SPW1.DEF"); anims.push_back("C08SPW2.DEF"); anims.push_back("C08SPW3.DEF"); anims.push_back("C08SPW4.DEF");
+			}
+		} //end of ice bolt only part
+		{ //common ice bolt and magic arrow part
+			//initial variables
 			std::string animToDisplay;
 			std::pair<int, int> srccoord = sc->side ? std::make_pair(770, 60) : std::make_pair(30, 60);
 			std::pair<int, int> destcoord = CBattleHex::getXYUnitAnim(sc->tile, !sc->side, LOCPLINT->cb->battleGetStackByPos(sc->tile)->creature); //position attacked by arrow
@@ -1270,11 +1275,18 @@ void CBattleInterface::spellCasted(SpellCasted * sc)
 			}
 
 			int b=0;
+			break; //for 15 and 16 cases
+		}
+	case 17: //lightning bolt
+		{
+			displayEffect(1, sc->tile);
 			break;
 		}
 	case 53://haste
-		displayEffect(31,sc->tile,LOCPLINT->cb->battleGetStackByPos(sc->tile)->owner);
-		break;
+		{
+			displayEffect(31, sc->tile);
+			break;
+		}
 	}
 }
 
@@ -1291,7 +1303,7 @@ void CBattleInterface::castThisSpell(int spellID)
 	CGI->curh->changeGraphic(3, 0); 
 }
 
-void CBattleInterface::displayEffect(ui32 effect, int destTile, bool affected)
+void CBattleInterface::displayEffect(ui32 effect, int destTile)
 {
 	if(graphics->battleACToDef[effect].size() != 0)
 	{
@@ -1299,11 +1311,19 @@ void CBattleInterface::displayEffect(ui32 effect, int destTile, bool affected)
 		be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
 		be.frame = 0;
 		be.maxFrame = be.anim->ourImages.size();
-		std::pair<int, int> coords = CBattleHex::getXYUnitAnim(destTile, affected, NULL);
-		coords.first += 250; coords.second += 240;
-		coords.first -= be.anim->ourImages[0].bitmap->w/2;
-		coords.second -= be.anim->ourImages[0].bitmap->h/2;
-		be.x = coords.first; be.y = coords.second;
+		be.x = 22 * ( ((destTile/BFIELD_WIDTH) + 1)%2 ) + 44 * (destTile % BFIELD_WIDTH) + 50;
+		be.y = 100 + 42 * (destTile/BFIELD_WIDTH);
+
+		if(effect != 1)
+		{
+			be.x -= be.anim->ourImages[0].bitmap->w/2;
+			be.y -= be.anim->ourImages[0].bitmap->h/2;
+		}
+		else if(effect == 1)
+		{
+			be.x -= be.anim->ourImages[0].bitmap->w;
+			be.y -= be.anim->ourImages[0].bitmap->h;
+		}
 
 		battleEffects.push_back(be);
 	}
@@ -1656,7 +1676,7 @@ void CBattleHero::clickLeft(boost::logic::tribool down)
 {
 	if(!down && myHero)
 	{
-		for(int it=0; it<187; ++it) //do nothing when any hex is hovered - hero's animation overlaps battlefield
+		for(int it=0; it<BFIELD_SIZE; ++it) //do nothing when any hex is hovered - hero's animation overlaps battlefield
 		{
 			if(myOwner->bfield[it].hovered && myOwner->bfield[it].strictHovered)
 				return;
@@ -1707,15 +1727,15 @@ CBattleHero::~CBattleHero()
 std::pair<int, int> CBattleHex::getXYUnitAnim(const int & hexNum, const bool & attacker, const CCreature * creature)
 {
 	std::pair<int, int> ret = std::make_pair(-500, -500); //returned value
-	ret.second = -139 + 42 * (hexNum/17); //counting y
+	ret.second = -139 + 42 * (hexNum/BFIELD_WIDTH); //counting y
 	//counting x
 	if(attacker)
 	{
-		ret.first = -160 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17);
+		ret.first = -160 + 22 * ( ((hexNum/BFIELD_WIDTH) + 1)%2 ) + 44 * (hexNum % BFIELD_WIDTH);
 	}
 	else
 	{
-		ret.first = -219 + 22 * ( ((hexNum/17) + 1)%2 ) + 44 * (hexNum % 17);
+		ret.first = -219 + 22 * ( ((hexNum/BFIELD_WIDTH) + 1)%2 ) + 44 * (hexNum % BFIELD_WIDTH);
 	}
 	//shifting position for double - hex creatures
 	if(creature && creature->isDoubleWide())

+ 3 - 3
CBattleInterface.h

@@ -166,7 +166,7 @@ private:
 	std::list<SProjectileInfo> projectiles;
 	void projectileShowHelper(SDL_Surface * to=NULL); //prints projectiles present on the battlefield
 	void giveCommand(ui8 action, ui16 tile, ui32 stack, si32 additional=-1);
-	bool isTileAttackable(int number); //returns true if tile 'number' is neighbouring any tile from active stack's range or is one of these tiles
+	bool isTileAttackable(const int & number) const; //returns true if tile 'number' is neighbouring any tile from active stack's range or is one of these tiles
 
 	struct SBattleEffect
 	{
@@ -189,7 +189,7 @@ public:
 	void setAnimSpeed(int set); //set for animSpeed
 	int getAnimSpeed() const; //get for animSpeed
 
-	CBattleHex bfield[187]; //11 lines, 17 hexes on each
+	CBattleHex bfield[BFIELD_SIZE]; //11 lines, 17 hexes on each
 	std::vector< CBattleObstacle * > obstacles; //vector of obstacles on the battlefield
 	SDL_Surface * cellBorder, * cellShade;
 	CondSh<BattleAction *> *givenCommand; //data != NULL if we have i.e. moved current unit
@@ -231,7 +231,7 @@ public:
 	void battleFinished(const BattleResult& br); //called when battle is finished - battleresult window should be printed
 	void spellCasted(SpellCasted * sc); //called when a hero casts a spell
 	void castThisSpell(int spellID); //called when player has chosen a spell from spellbook
-	void displayEffect(ui32 effect, int destTile, bool affected); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
+	void displayEffect(ui32 effect, int destTile); //displays effect of a spell on the battlefield; affected: true - attacker. false - defender
 
 	friend class CBattleHex;
 	friend class CBattleReslutWindow;

+ 17 - 17
CGameState.cpp

@@ -95,7 +95,7 @@ CStack * BattleInfo::getStackT(int tileID)
 }
 void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit)
 {
-	memset(accessibility,1,187); //initialize array with trues
+	memset(accessibility,1,BFIELD_SIZE); //initialize array with trues
 	for(int g=0; g<stacks.size(); ++g)
 	{
 		if(!stacks[g]->alive() || stacks[g]->ID==stackToOmmit) //we don't want to lock position of this stack
@@ -114,11 +114,11 @@ void BattleInfo::getAccessibilityMap(bool *accessibility, int stackToOmmit)
 }
 void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerSide, int stackToOmmit) //send pointer to at least 187 allocated bytes
 {	
-	bool mac[187];
+	bool mac[BFIELD_SIZE];
 	getAccessibilityMap(mac,stackToOmmit);
-	memcpy(accessibility,mac,187);
+	memcpy(accessibility,mac,BFIELD_SIZE);
 
-	for(int b=0; b<187; ++b)
+	for(int b=0; b<BFIELD_SIZE; ++b)
 	{
 		if( mac[b] && !(atackerSide ? mac[b-1] : mac[b+1]))
 		{
@@ -127,16 +127,16 @@ void BattleInfo::getAccessibilityMapForTwoHex(bool *accessibility, bool atackerS
 	}
 
 	//removing accessibility for side hexes
-	for(int v=0; v<187; ++v)
+	for(int v=0; v<BFIELD_SIZE; ++v)
 		if(atackerSide ? (v%17)==1 : (v%17)==15)
 			accessibility[v] = false;
 }
 void BattleInfo::makeBFS(int start, bool*accessibility, int *predecessor, int *dists) //both pointers must point to the at least 187-elements int arrays
 {
 	//inits
-	for(int b=0; b<187; ++b)
+	for(int b=0; b<BFIELD_SIZE; ++b)
 		predecessor[b] = -1;
-	for(int g=0; g<187; ++g)
+	for(int g=0; g<BFIELD_SIZE; ++g)
 		dists[g] = 100000000;	
 	
 	std::queue<int> hexq; //bfs queue
@@ -163,18 +163,18 @@ void BattleInfo::makeBFS(int start, bool*accessibility, int *predecessor, int *d
 std::vector<int> BattleInfo::getAccessibility(int stackID)
 {
 	std::vector<int> ret;
-	bool ac[187];
+	bool ac[BFIELD_SIZE];
 	CStack *s = getStack(stackID);
 	if(s->creature->isDoubleWide())
 		getAccessibilityMapForTwoHex(ac,s->attackerOwned,stackID);
 	else
 		getAccessibilityMap(ac,stackID);
 
-	int pr[187], dist[187];
+	int pr[BFIELD_SIZE], dist[BFIELD_SIZE];
 	makeBFS(s->position,ac,pr,dist);
 	
-	for(int i=0;i<187;i++)
-		if(dist[i] <= s->creature->speed)
+	for(int i=0;i<BFIELD_SIZE;i++)
+		if(dist[i] <= s->speed())
 			ret.push_back(i);
 
 	return ret;
@@ -212,7 +212,7 @@ signed char BattleInfo::mutualPosition(int hex1, int hex2)
 }
 std::vector<int> BattleInfo::neighbouringTiles(int hex)
 {
-#define CHECK_AND_PUSH(tile) {int hlp = (tile); if(hlp>=0 && hlp<187 && (hlp%17!=16) && hlp%17) ret.push_back(hlp);}
+#define CHECK_AND_PUSH(tile) {int hlp = (tile); if(hlp>=0 && hlp<BFIELD_SIZE && (hlp%17!=16) && hlp%17) ret.push_back(hlp);}
 	std::vector<int> ret;
 	CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 18 : 17 ));
 	CHECK_AND_PUSH(hex - ( (hex/17)%2 ? 17 : 16 ));
@@ -225,8 +225,8 @@ std::vector<int> BattleInfo::neighbouringTiles(int hex)
 }
 std::vector<int> BattleInfo::getPath(int start, int dest, bool*accessibility)
 {							
-	int predecessor[187]; //for getting the Path
-	int dist[187]; //calculated distances
+	int predecessor[BFIELD_SIZE]; //for getting the Path
+	int dist[BFIELD_SIZE]; //calculated distances
 
 	makeBFS(start,accessibility,predecessor,dist);
 
@@ -248,10 +248,10 @@ CStack::CStack(CCreature * C, int A, int O, int I, bool AO, int S)
 	state.insert(ALIVE);
 }
 
-ui32 CStack::speed()
+ui32 CStack::speed() const
 {
 	int premy=0;
-	StackEffect *effect = 0;
+	const StackEffect *effect = 0;
 	//haste effect check
 	effect = getEffect(53);
 	if(effect)
@@ -271,7 +271,7 @@ ui32 CStack::speed()
 	return creature->speed + premy;
 }
 
-CStack::StackEffect * CStack::getEffect(ui16 id)
+const CStack::StackEffect * CStack::getEffect(ui16 id) const
 {
 	for (int i=0; i< effects.size(); i++)
 		if(effects[i].id == id)

+ 3 - 3
CGameState.h

@@ -110,8 +110,8 @@ public:
 
 	CStack(CCreature * C, int A, int O, int I, bool AO, int S);
 	CStack() : creature(NULL),amount(-1),owner(255), position(-1), ID(-1), attackerOwned(true), firstHPleft(-1), slot(255), baseAmount(-1), counterAttacks(1){};
-	StackEffect * getEffect(ui16 id); //effect id (SP)
-	ui32 speed();
+	const StackEffect * getEffect(ui16 id) const; //effect id (SP)
+	ui32 speed() const;
 	template <typename Handler> void save(Handler &h, const int version)
 	{
 		h & creature->idNumber;
@@ -132,7 +132,7 @@ public:
 		else
 			load(h,version);
 	}
-	bool alive()
+	bool alive() const
 	{
 		return vstd::contains(state,ALIVE);
 	}

+ 1 - 1
CPlayerInterface.cpp

@@ -2103,7 +2103,7 @@ void CPlayerInterface::battleStackAttacked(BattleStackAttacked * bsa)
 	boost::unique_lock<boost::recursive_mutex> un(*pim);
 	if(bsa->isEffect())
 	{
-		battleInt->displayEffect(bsa->effect, cb->battleGetStackByID(bsa->stackAttacked)->position, cb->battleGetStackByID(bsa->stackAttacked)->attackerOwned);
+		battleInt->displayEffect(bsa->effect, cb->battleGetStackByID(bsa->stackAttacked)->position);
 	}
 	if(bsa->killed())
 		battleInt->stackKilled(bsa->stackAttacked, bsa->damageAmount, bsa->killedAmount, LOCPLINT->curAction->stackNumber, LOCPLINT->curAction->actionType==7 );

+ 1 - 1
config/AC_desc.txt

@@ -1,6 +1,6 @@
 //WoG_Ac_format_to_def_names_mapping
 0 1 C10SPW.DEF
-1 1 C03SPA.DEF
+1 1 C03SPA0.DEF
 2 1 C01SPA0.DEF
 3 1 C02SPA0.DEF
 4 1 SP12_.DEF

+ 7 - 2
global.h

@@ -72,8 +72,13 @@ const int CREATURES_PER_TOWN = 7; //without upgrades
 const int MAX_BUILDING_PER_TURN = 1;
 const int SPELL_LEVELS = 5;
 
-#define MARK_BLOCKED_POSITIONS false
-#define MARK_VISITABLE_POSITIONS false
+#define BFIELD_WIDTH (17)
+#define BFIELD_HEIGHT (11)
+#define BFIELD_SIZE ((BFIELD_WIDTH) * (BFIELD_HEIGHT))
+
+//uncomment to make it work
+//#define MARK_BLOCKED_POSITIONS
+//#define MARK_VISITABLE_POSITIONS
 
 #define DEFBYPASS
 

+ 6 - 2
mapHandler.cpp

@@ -741,7 +741,8 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
 			}
 			else 
 			{
-				if(MARK_BLOCKED_POSITIONS &&  ttiles[x+bx][y+by][level].tileInfo->blocked) //temporary hiding blocked positions
+#ifdef MARK_BLOCKED_POSITIONS
+				if(ttiles[x+bx][y+by][level].tileInfo->blocked) //temporary hiding blocked positions
 				{
 					SDL_Rect sr;
 					sr.y=by*32;
@@ -759,7 +760,9 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
 
 					SDL_FreeSurface(ns);
 				}
-				if(MARK_VISITABLE_POSITIONS &&  ttiles[x+bx][y+by][level].tileInfo->visitable) //temporary hiding visitable positions
+#endif
+#ifdef MARK_VISITABLE_POSITIONS
+				if(ttiles[x+bx][y+by][level].tileInfo->visitable) //temporary hiding visitable positions
 				{
 					SDL_Rect sr;
 					sr.y=by*32;
@@ -777,6 +780,7 @@ SDL_Surface * CMapHandler::terrainRect(int x, int y, int dx, int dy, int level,
 
 					SDL_FreeSurface(ns);
 				}
+#endif
 			}
 		}
 	}

+ 30 - 4
server/CGameHandler.cpp

@@ -46,9 +46,9 @@ std::map<ui32, CFunctionList<void(ui32)> > callbacks; //question id => callback
 class CMP_stack
 {
 public:
-	bool operator ()(const CStack* a, const CStack* b)
+	inline bool operator ()(const CStack* a, const CStack* b)
 	{
-		return (a->creature->speed)>(b->creature->speed);
+		return (a->speed())>(b->speed());
 	}
 } cmpst ;
 
@@ -1243,6 +1243,32 @@ upgend:
 									sendAndApply(&bsa);
 									break;
 								}
+							case 16://ice bolt
+								{
+									CStack * attacked = gs->curB->getStackT(ba.destinationTile);
+									if(!attacked) break;
+									BattleStackAttacked bsa;
+									bsa.flags |= 2;
+									bsa.effect = 46;
+									bsa.damageAmount = h->getPrimSkillLevel(2) * 20  +  s->powers[getSchoolLevel(h,s)]; 
+									bsa.stackAttacked = attacked->ID;
+									prepareAttacked(bsa,attacked);
+									sendAndApply(&bsa);
+									break;
+								}
+							case 17://lightning bolt
+								{
+									CStack * attacked = gs->curB->getStackT(ba.destinationTile);
+									if(!attacked) break;
+									BattleStackAttacked bsa;
+									bsa.flags |= 2;
+									bsa.effect = 38;
+									bsa.damageAmount = h->getPrimSkillLevel(2) * 25  +  s->powers[getSchoolLevel(h,s)]; 
+									bsa.stackAttacked = attacked->ID;
+									prepareAttacked(bsa,attacked);
+									sendAndApply(&bsa);
+									break;
+								}
 							case 53: //haste
 								{
 									SetStackEffect sse;
@@ -1309,7 +1335,7 @@ void CGameHandler::moveStack(int stack, int dest)
 		*stackAtEnd = gs->curB->getStackT(dest);
 
 	//initing necessary tables
-	bool accessibility[187];
+	bool accessibility[BFIELD_SIZE];
 	if(curStack->creature->isDoubleWide())
 		gs->curB->getAccessibilityMapForTwoHex(accessibility,curStack->attackerOwned,curStack->ID);
 	else 
@@ -1322,7 +1348,7 @@ void CGameHandler::moveStack(int stack, int dest)
 	//	return false;
 
 	std::vector<int> path = gs->curB->getPath(curStack->position,dest,accessibility);
-	int tilesToMove = std::max((int)path.size()-curStack->creature->speed, 0);
+	int tilesToMove = std::max((int)(path.size() - curStack->speed()), 0);
 	for(int v=path.size()-1; v>=tilesToMove; --v)
 	{
 		//inform clients about move