瀏覽代碼

* added new spells
- dispel
- armageddon
* spellbook cannot be opened by L-click on hero in battle when it shouldn't be possible
* minor changes

mateuszb 16 年之前
父節點
當前提交
899be22db0
共有 9 個文件被更改,包括 105 次插入48 次删除
  1. 47 22
      CBattleInterface.cpp
  2. 1 1
      CCastleInterface.cpp
  3. 6 6
      CCastleInterface.h
  4. 6 1
      CPlayerInterface.cpp
  5. 3 9
      SDL_Extensions.h
  6. 1 1
      config/spell_info.txt
  7. 7 7
      global.h
  8. 10 1
      lib/NetPacksLib.cpp
  9. 24 0
      server/CGameHandler.cpp

+ 47 - 22
CBattleInterface.cpp

@@ -267,6 +267,7 @@ CBattleInterface::CBattleInterface(CCreatureSet * army1, CCreatureSet * army2, C
 	spellToEffect[18] = 10; //implosion
 	spellToEffect[27] = 27; //shield
 	spellToEffect[28] = 2; //air shield
+	spellToEffect[35] = 41; //dispel
 	spellToEffect[41] = 36; //bless
 	spellToEffect[42] = 40; //curse
 	spellToEffect[43] = 4; //bloodlust
@@ -1941,32 +1942,56 @@ void CBattleInterface::castThisSpell(int spellID)
 
 void CBattleInterface::displayEffect(ui32 effect, int destTile)
 {
-	if(graphics->battleACToDef[effect].size() != 0)
+	if(effect == 12) //armageddon
 	{
-		SBattleEffect be;
-		be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
-		be.frame = 0;
-		be.maxFrame = be.anim->ourImages.size();
-		be.x = 22 * ( ((destTile/BFIELD_WIDTH) + 1)%2 ) + 44 * (destTile % BFIELD_WIDTH) + 45;
-		be.y = 105 + 42 * (destTile/BFIELD_WIDTH);
-
-		if(effect != 1 && effect != 0)
-		{
-			be.x -= be.anim->ourImages[0].bitmap->w/2;
-			be.y -= be.anim->ourImages[0].bitmap->h/2;
-		}
-		else if(effect == 1)
+		if(graphics->battleACToDef[effect].size() != 0)
 		{
-			be.x -= be.anim->ourImages[0].bitmap->w;
-			be.y -= be.anim->ourImages[0].bitmap->h;
+			CDefHandler * anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
+			for(int i=0; i * anim->width < pos.w ; ++i)
+			{
+				for(int j=0; j * anim->height < pos.h ; ++j)
+				{
+					SBattleEffect be;
+					be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
+					be.frame = 0;
+					be.maxFrame = be.anim->ourImages.size();
+					be.x = i * anim->width;
+					be.y = j * anim->height;
+
+					battleEffects.push_back(be);
+				}
+			}
 		}
-		else if (effect == 0)
+	}
+	else
+	{
+		if(graphics->battleACToDef[effect].size() != 0)
 		{
-			be.x -= be.anim->ourImages[0].bitmap->w/2;
-			be.y -= be.anim->ourImages[0].bitmap->h;
-		}
+			SBattleEffect be;
+			be.anim = CDefHandler::giveDef(graphics->battleACToDef[effect][0]);
+			be.frame = 0;
+			be.maxFrame = be.anim->ourImages.size();
+			be.x = 22 * ( ((destTile/BFIELD_WIDTH) + 1)%2 ) + 44 * (destTile % BFIELD_WIDTH) + 45;
+			be.y = 105 + 42 * (destTile/BFIELD_WIDTH);
 
-		battleEffects.push_back(be);
+			if(effect != 1 && effect != 0)
+			{
+				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;
+			}
+			else if (effect == 0)
+			{
+				be.x -= be.anim->ourImages[0].bitmap->w/2;
+				be.y -= be.anim->ourImages[0].bitmap->h;
+			}
+
+			battleEffects.push_back(be);
+		}
 	}
 	//battleEffects 
 }
@@ -2385,7 +2410,7 @@ void CBattleHero::setPhase(int newPhase)
 
 void CBattleHero::clickLeft(boost::logic::tribool down)
 {
-	if(!down && myHero) if(myHero->getArt(17)) //if both conditions are satisfied; for certain reason myHero->getArt(17) has been checked once even though myHero was NULL
+	if(!down && myHero && LOCPLINT->cb->battleCanCastSpell()) //check conditions
 	{
 		for(int it=0; it<BFIELD_SIZE; ++it) //do nothing when any hex is hovered - hero's animation overlaps battlefield
 		{

+ 1 - 1
CCastleInterface.cpp

@@ -416,7 +416,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town)
 
 	townlist->fun = boost::bind(&CCastleInterface::townChange,this);
 	townlist->genList();
-	townlist->selected = getIndexOf(townlist->items,Town);
+	townlist->selected = vstd::findPos(townlist->items,Town);
 	if((townlist->selected+1) > townlist->SIZE)
 		townlist->from = townlist->selected -  townlist->SIZE + 2;
 

+ 6 - 6
CCastleInterface.h

@@ -50,7 +50,7 @@ public:
 	CCastleInterface *owner;
 	const CGHeroInstance *hero;
 	int upg; //0 - up garrison, 1 - down garrison
-	bool highlight;
+	bool highlight; //indicates id the slot is highlighted
 
 	void hover (bool on);
 	void clickRight (boost::logic::tribool down);
@@ -65,8 +65,8 @@ public:
 class CCastleInterface : public CWindowWithGarrison
 {
 public:
-	SDL_Rect pos;
-	bool showing;
+	SDL_Rect pos; //why not inherit this member from CIntObject ?
+	bool showing; //indicates if interface is active
 	CBuildingRect * hBuild; //highlighted building
 	SDL_Surface * townInt;
 	SDL_Surface * cityBg;
@@ -167,7 +167,7 @@ class CFortScreen : public IShowActivable, public CIntObject
 	{
 	public:
 		int bid;
-		RecArea(int BID):bid(BID){};
+		RecArea(int BID):bid(BID){}; //c-tor
 		void clickLeft (tribool down);
 		void clickRight (tribool down);
 		void activate();
@@ -181,10 +181,10 @@ public:
 	std::vector<RecArea*> recAreas;
 	std::vector<CCreaturePic*> crePics;
 
-	CFortScreen(CCastleInterface * owner);
+	CFortScreen(CCastleInterface * owner); //c-tor
 
 	void draw( CCastleInterface * owner, bool first);
-	~CFortScreen();
+	~CFortScreen(); //d-tor
 	void close();
 	void show(SDL_Surface * to);
 	void activate();

+ 6 - 1
CPlayerInterface.cpp

@@ -2304,7 +2304,7 @@ void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
 	std::vector<CBattleInterface::SStackAttackedInfo> arg;
 	for(std::set<BattleStackAttacked>::iterator i = bsa.begin(); i != bsa.end(); i++)
 	{
-		if(i->isEffect())
+		if(i->isEffect() && i->effect != 12) //and not armageddon
 		{
 			battleInt->displayEffect(i->effect, cb->battleGetStackByID(i->stackAttacked)->position);
 		}
@@ -2312,6 +2312,11 @@ void CPlayerInterface::battleStacksAttacked(std::set<BattleStackAttacked> & bsa)
 		arg.push_back(to_put);
 	}
 
+	if(bsa.begin()->isEffect() && bsa.begin()->effect == 12) //for armageddon - I hope this condition is enough
+	{
+		battleInt->displayEffect(bsa.begin()->effect, -1);
+	}
+
 	battleInt->stacksAreAttacked(arg);
 }
 void CPlayerInterface::battleAttack(BattleAttack *ba)

+ 3 - 9
SDL_Extensions.h

@@ -22,13 +22,7 @@ void blitAtWR(SDL_Surface * src, SDL_Rect pos, SDL_Surface * dst=screen);
 void blitAt(SDL_Surface * src, SDL_Rect pos, SDL_Surface * dst=screen);
 void updateRect (SDL_Rect * rect, SDL_Surface * scr = screen);
 bool isItIn(const SDL_Rect * rect, int x, int y);
-template <typename T> int getIndexOf(const std::vector<T> & v, const T & val)
-{
-	for(int i=0;i<v.size();i++)
-		if(v[i]==val)
-			return i;
-	return -1;
-}
+
 inline SDL_Rect genRect(const int & hh, const int & ww, const int & xx, const int & yy)
 {
 	SDL_Rect ret;
@@ -59,9 +53,9 @@ namespace CSDL_Ext
 	SDL_Surface * hFlip(SDL_Surface * toRot); //horizontal flip
 	SDL_Surface * rotate02(SDL_Surface * toRot); //rotate 90 degrees left
 	SDL_Surface * rotate03(SDL_Surface * toRot); //rotate 180 degrees
-	SDL_Cursor * SurfaceToCursor(SDL_Surface *image, int hx, int hy);
+	SDL_Cursor * SurfaceToCursor(SDL_Surface *image, int hx, int hy); //creates cursor from bitmap
 	Uint32 SDL_GetPixel(SDL_Surface *surface, const int & x, const int & y, bool colorByte = false);
-	SDL_Color SDL_GetPixelColor(SDL_Surface *surface, int x, int y);
+	SDL_Color SDL_GetPixelColor(SDL_Surface *surface, int x, int y); //returns color of pixel at given position
 	SDL_Surface * alphaTransform(SDL_Surface * src); //adds transparency and shadows (partial handling only; see examples of using for details)
 	void blitWithRotate1(SDL_Surface *src,SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests
 	void blitWithRotate2(SDL_Surface *src,SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect);//srcRect is not used, works with 8bpp sources and 24bpp dests

+ 1 - 1
config/spell_info.txt

@@ -35,7 +35,7 @@
 32 1 0 0 0 X
 33 1 0 0 0 X
 34 1 0 0 0 X
-35 1 0 0 0 X
+35 0 0 0 0 X
 36 1 0 0 0 0
 37 1 0 0 0 0
 38 1 0 0 0 0

+ 7 - 7
global.h

@@ -114,12 +114,12 @@ template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
 namespace vstd
 {
 	template <typename Container, typename Item>
-	bool contains(const Container & c, const Item &i)
+	bool contains(const Container & c, const Item &i) //returns true if container c contains item i
 	{
 		return std::find(c.begin(),c.end(),i) != c.end();
 	}
 	template <typename V, typename Item, typename Item2>
-	bool contains(const std::map<Item,V> & c, const Item2 &i)
+	bool contains(const std::map<Item,V> & c, const Item2 &i) //returns true if map c contains item i
 	{
 		return c.find(i)!=c.end();
 	}
@@ -140,7 +140,7 @@ namespace vstd
 		return std::find(c.begin(),c.end(),i);
 	}
 	template <typename T1, typename T2>
-	int findPos(const std::vector<T1> & c, const T2 &s)
+	int findPos(const std::vector<T1> & c, const T2 &s) //returns position of first element in vector c equal to s, if there is no such element, -1 is returned
 	{
 		for(size_t i=0; i < c.size(); ++i)
 			if(c[i] == s)
@@ -161,7 +161,7 @@ namespace vstd
 		return std::find(c.begin(),c.end(),i);
 	}
 	template <typename Container, typename Item>
-	bool operator-=(Container &c, const Item &i)
+	bool operator-=(Container &c, const Item &i) //removes element i from container c, returns false if c does not contain i
 	{
 		typename Container::iterator itr = find(c,i);
 		if(itr == c.end())
@@ -212,7 +212,7 @@ namespace vstd
 using vstd::operator-=;
 
 template <typename t1, typename t2>
-t1 & amax(t1 &a, const t2 &b)
+t1 & amax(t1 &a, const t2 &b) //assigns greater of (a, b) to a and returns maximum of (a, b)
 {
 	if(a >= b)
 		return a;
@@ -223,7 +223,7 @@ t1 & amax(t1 &a, const t2 &b)
 	}
 }
 template <typename t1, typename t2>
-t1 & amin(t1 &a, const t2 &b)
+t1 & amin(t1 &a, const t2 &b) //assigns smaller of (a, b) to a and returns minimum of (a, b)
 {
 	if(a <= b)
 		return a;
@@ -236,7 +236,7 @@ t1 & amin(t1 &a, const t2 &b)
 #include "CConsoleHandler.h"
 extern DLL_EXPORT std::ostream *logfile;
 extern DLL_EXPORT CConsoleHandler *console;
-template <int lvl> class CLogger
+template <int lvl> class CLogger //logger, prints log info to console and saves in file
 {
 public:
 	CLogger<lvl>& operator<<(std::ostream& (*fun)(std::ostream&))

+ 10 - 1
lib/NetPacksLib.cpp

@@ -549,7 +549,16 @@ DLL_EXPORT void SetStackEffect::applyGs( CGameState *gs )
 	{
 		CStack *s = gs->curB->getStack(id);
 		if(s)
-			s->effects.push_back(effect);
+		{
+			if(effect.id == 35) //dispel - removing all effects
+			{
+				s->effects.clear();
+			}
+			else //adding effect
+			{
+				s->effects.push_back(effect);
+			}
+		}
 		else
 			tlog1 << "Cannot find stack " << id << std::endl;
 	}

+ 24 - 0
server/CGameHandler.cpp

@@ -2425,8 +2425,32 @@ bool CGameHandler::makeCustomAction( BattleAction &ba )
 					sendAndApply(&si);
 					break;
 				}
+			case 26: //armageddon
+				{
+					std::set<CStack*> attackedCres;
+					
+					for(int it=0; it<gs->curB->stacks.size(); ++it)
+					{
+						attackedCres.insert(gs->curB->stacks[it]);
+					}
+					if(attackedCres.size() == 0) break;
+					StacksInjured si;
+					for(std::set<CStack*>::iterator it = attackedCres.begin(); it != attackedCres.end(); ++it)
+					{
+						BattleStackAttacked bsa;
+						bsa.flags |= 2;
+						bsa.effect = 12;
+						bsa.damageAmount = h->getPrimSkillLevel(2) * 10  +  s->powers[h->getSpellSchoolLevel(s)]; 
+						bsa.stackAttacked = (*it)->ID;
+						prepareAttacked(bsa,*it);
+						si.stacks.insert(bsa);
+					}
+					sendAndApply(&si);
+					break;
+				}
 			case 27: //shield 
 			case 28: //air shield
+			case 35: //dispel
 			case 41: //bless
 			case 42: //curse
 			case 43: //bloodlust