Jelajahi Sumber

Animation system update:
-- files moved to /client, GUI classes added
-- handling of creatures, used in creature cards, fixed #469 \ #490
-- handling of town buildings
#631 crash at hill fort fixed

Ivan Savenko 15 tahun lalu
induk
melakukan
265d7a22d6

+ 1 - 1
client/AdventureMapButton.cpp

@@ -1,5 +1,5 @@
 #include "AdventureMapButton.h"
-#include "../hch/CAnimation.h"
+#include "CAnimation.h"
 #include "CAdvmapInterface.h"
 #include "SDL_Extensions.h"
 #include "CGameInfo.h"

+ 301 - 26
hch/CAnimation.cpp → client/CAnimation.cpp

@@ -1,13 +1,15 @@
 #include <iostream>
 #include <sstream>
 #include <boost/foreach.hpp>
+#include <boost/bind.hpp>
 
 #include "SDL.h"
 #include "SDL_image.h"
 
-#include "../client/CBitmapHandler.h"
+#include "CBitmapHandler.h"
 #include "CAnimation.h"
-#include "CLodHandler.h"
+#include "SDL_Extensions.h"
+#include "../hch/CLodHandler.h"
 
 /*
  * CAnimation.cpp, part of VCMI engine
@@ -19,7 +21,6 @@
  *
  */
 
-
 extern DLL_EXPORT CLodHandler *spriteh;
 
 /*************************************************************************
@@ -267,8 +268,9 @@ SDL_Surface * CDefFile::loadFrame (const unsigned char * FDef, const BMPPalette
 		break;
 	}
 
-	SDL_Color ttcol = ret->format->palette->colors[0];
-	Uint32 keycol = SDL_MapRGBA(ret->format, ttcol.r, ttcol.b, ttcol.g, ttcol.unused);
+	SDL_Color *col = ret->format->palette->colors;
+	
+	Uint32 keycol = SDL_MapRGBA(ret->format, col[0].r, col[0].b, col[0].g, col[0].unused);
 	SDL_SetColorKey(ret, SDL_SRCCOLORKEY, keycol);
 	return ret;
 };
@@ -282,6 +284,15 @@ BMPPalette * CDefFile::getPalette()
 
 CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL)
 {
+	static SDL_Color H3Palette[8] = {{  0,   0,   0, 255},
+	                                 {  0,   0,   0, 192},
+	                                 {  0,   0,   0, 128},
+	                                 {  0,   0,   0,  64},
+	                                 {  0,   0,   0,  32},
+	                                 {255, 255,   0, 255},
+	                                 {255, 255,   0, 255},
+	                                 {255, 255,   0, 255}};//H3 palette for shadow\selection highlight
+	
 	data = spriteh->giveFile(Name, FILE_ANIMATION, &datasize);
 	if (!data)
 	{
@@ -292,37 +303,41 @@ CDefFile::CDefFile(std::string Name):data(NULL),colors(NULL)
 	colors = new BMPPalette[256];
 	int it = 0;
 
-	//int type   = readNormalNr(data, it); it+=4;
+	type = readNormalNr(data, it); it+=4;
 	//int width  = readNormalNr(data, it); it+=4;//not used
 	//int height = readNormalNr(data, it); it+=4;
-	it+=12;
+	it+=8;
 	unsigned int totalBlocks = readNormalNr(data, it);
 	it+=4;
 
-	for (unsigned int i=0; i<256; i++)
+	for (unsigned int i= 0; i<256; i++)
 	{
 		colors[i].R = data[it++];
 		colors[i].G = data[it++];
 		colors[i].B = data[it++];
 		colors[i].F = 0;
 	}
+	memcpy(colors, H3Palette, (type == 66)? 32:20);//initialize shadow\selection colors
 
-	offset.resize(totalBlocks);
 	offList.insert(datasize);
 
 	for (unsigned int i=0; i<totalBlocks; i++)
 	{
+		unsigned int blockID = readNormalNr(data, it);
 		it+=4;
 		unsigned int totalEntries = readNormalNr(data, it);
 		it+=12;
+		//8 unknown bytes - skipping
 
 		//13 bytes for name of every frame in this block - not used, skipping
 		it+= 13 * totalEntries;
 
+		offset.resize(std::max(blockID+1, offset.size()));
+
 		for (unsigned int j=0; j<totalEntries; j++)
 		{
 			size_t currOffset = readNormalNr(data, it);
-			offset[i].push_back(currOffset);
+			offset[blockID].push_back(currOffset);
 			offList.insert(currOffset);
 			it += 4;
 		}
@@ -353,6 +368,8 @@ unsigned char * CDefFile::getFrame(size_t frame, size_t group) const
 
 CDefFile::~CDefFile()
 {
+	offset.clear();
+	offList.clear();
 	delete[] data;
 	delete[] colors;
 }
@@ -379,7 +396,10 @@ CAnimation::AnimEntry::AnimEntry():
 bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
 {
 	if (groupSize(group) <= frame)
+	{
+		printError(frame, group, "LoadFrame");
 		return false;
+	}
 	AnimEntry &e = entries[group][frame];
 
 	if (e.surf || e.data)
@@ -410,7 +430,7 @@ bool CAnimation::loadFrame(CDefFile * file, size_t frame, size_t group)
 			else
 			{
 				e.surf = IMG_Load_RW( SDL_RWFromMem((void*)pic, size), 1);
-				delete pic;
+				delete [] pic;
 			}
 		}
 	}
@@ -438,7 +458,7 @@ bool CAnimation::unloadFrame(size_t frame, size_t group)
 			return true;
 
 		SDL_FreeSurface(e.surf);
-		delete e.data;
+		delete [] e.data;
 
 		e.surf = NULL;
 		e.data = NULL;
@@ -501,7 +521,13 @@ void CAnimation::init(CDefFile * file)
 		if (!toAdd.empty())
 		{
 			entries.push_back(toAdd);
-			break;
+		}
+		else
+		{
+			entries.resize(entries.size()+1);
+			if (group > 21)
+				break;//FIXME: crude workaround: if some groups are not present
+				      //(common for creatures) parser will exit before reaching them
 		}
 	}
 }
@@ -532,7 +558,6 @@ CAnimation::CAnimation(std::string Name, bool Compressed):
 	int dotPos = name.find_last_of('.');
 	if ( dotPos != -1 )
 		name.erase(dotPos);
-
 	CDefFile * file = getFile();
 	init(file);
 	delete file;
@@ -548,12 +573,11 @@ CAnimation::CAnimation():
 
 CAnimation::~CAnimation()
 {
-	delete defPalette;
-
+	delete [] defPalette;
 	for (size_t i = 0; i < entries.size(); i++)
 		for (size_t j = 0; j < entries.at(i).size(); j++)
 		{
-			delete entries[i][j].data;
+			delete [] entries[i][j].data;
 			if (entries[i][j].surf)
 				SDL_FreeSurface(entries[i][j].surf);
 		}
@@ -575,21 +599,25 @@ void CAnimation::add(SDL_Surface * surf, bool shared, size_t group)
 	entries[group].back().surf = surf;
 }
 
-void CAnimation::purgeCompressed()
+void CAnimation::removeDecompressed(size_t frame, size_t group)
 {
-	for (size_t group; group < entries.size(); group++)
-		for (size_t frame; frame < entries[group].size(); frame++)
-			if (entries[group][frame].surf)
-				SDL_FreeSurface(entries[group][frame].surf);
+	AnimEntry &e = entries[group][frame];
+	if (e.surf && e.data)
+	{
+		SDL_FreeSurface(e.surf);
+		e.surf = NULL;
+	}
 }
 
 SDL_Surface * CAnimation::image(size_t frame)
 {
 	size_t group=0;
-	for (; group<entries.size() && frame > entries[group].size(); group++)
+	while (group<entries.size() && frame > entries[group].size())
 		frame -= entries[group].size();
 
-	return image(frame, group);
+	if (group <entries.size() && frame < entries[group].size())
+		return image(frame, group);
+	return NULL;
 }
 
 SDL_Surface * CAnimation::image(size_t frame, size_t group)
@@ -634,13 +662,14 @@ void CAnimation::loadGroup(size_t group)
 {
 	CDefFile * file = getFile();
 
-	for (size_t frame = 0; frame<entries[group].size(); frame++)
+	for (size_t frame = 0; frame<groupSize(group); frame++)
 		loadFrame(file, frame, group);
+	delete file;
 }
 
 void CAnimation::unloadGroup(size_t group)
 {
-	for (size_t frame = 0; frame<entries[group].size(); frame++)
+	for (size_t frame = 0; frame<groupSize(group); frame++)
 		unloadFrame(frame, group);
 }
 
@@ -693,3 +722,249 @@ size_t CAnimation::size() const
 	}
 	return ret;
 }
+/*
+CAnimImage::CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group):
+	anim(name),
+	frame(Frame),
+	group(Group)
+{
+	anim.load(frame, group);
+	pos.w = anim.image(frame, group)->w;
+	pos.h = anim.image(frame, group)->h;
+}
+
+CAnimImage::~CAnimImage()
+{
+
+}
+
+void CAnimImage::show(SDL_Surface *to)
+{
+	blitAtLoc(anim.image(frame, group), 0,0, to);
+}
+
+void CAnimImage::setFrame(size_t Frame, size_t Group)
+{
+	if (frame == Frame && group==Group)
+		return;
+	if (anim.groupSize(Group) > Frame)
+	{
+		anim.unload(frame, group);
+		anim.load(Frame, Group);
+		frame = Frame;
+		group = Group;
+	}
+}
+*/
+CShowableAnim::CShowableAnim(int x, int y, std::string name, unsigned char Flags, unsigned int Delay, size_t Group):
+	anim(name, Flags),
+	group(Group),
+	frame(0),
+	first(0),
+	flags(Flags),
+	frameDelay(Delay),
+	value(0),
+	xOffset(0),
+	yOffset(0)
+{
+	pos.x+=x;
+	pos.y+=y;
+
+	anim.loadGroup(group);
+	last = anim.groupSize(group);
+	pos.w = anim.image(0, group)->w;
+	pos.h = anim.image(0, group)->h;
+}
+
+CShowableAnim::~CShowableAnim()
+{
+
+}
+
+bool CShowableAnim::set(size_t Group, size_t from, size_t to)
+{
+	size_t max = anim.groupSize(Group);
+
+	if (max>to)
+		max = to;
+
+	if (max < from || max == 0)
+		return false;
+
+	anim.load(Group);
+	anim.unload(group);
+	group = Group;
+	frame = first = from;
+	last = max;
+	value = 0;
+	return true;
+}
+
+bool CShowableAnim::set(size_t Group)
+{
+	if (anim.groupSize(Group)== 0)
+		return false;
+	if (group != Group)
+	{
+		anim.loadGroup(Group);
+		anim.unloadGroup(group);
+		first = 0;
+		group = Group;
+		last = anim.groupSize(Group);
+	}
+	frame = value = 0;
+	return true;
+}
+
+void CShowableAnim::reset()
+{
+	value = 0;
+	frame = first;
+	if (callback)
+		callback();
+}
+
+void CShowableAnim::movePic( int byX, int byY)
+{
+	xOffset += byX;
+	yOffset += byY;
+}
+
+void CShowableAnim::show(SDL_Surface *to)
+{
+	if ( flags & FLAG_BASE && frame != first)
+		blitImage(anim.image(first, group), to);
+	blitImage(anim.image(frame, group), to);
+	
+	if ( ++value == frameDelay )
+	{
+		value = 0;
+		if (flags & FLAG_COMPRESSED)
+			anim.removeDecompressed(frame, group);
+		if ( ++frame == last)
+			reset();
+	}
+
+}
+
+void CShowableAnim::showAll(SDL_Surface *to)
+{
+	show(to);
+}
+
+void CShowableAnim::blitImage(SDL_Surface *what, SDL_Surface *to)
+{
+	assert(what);
+	//TODO: SDL RLE?
+	SDL_Rect dstRect=genRect(pos.h, pos.w, pos.x, pos.y);
+	SDL_Rect srcRect;
+	
+	srcRect.x = xOffset;
+	srcRect.y = yOffset;
+	srcRect.w = pos.w;
+	srcRect.h = pos.h;
+	
+	/*if ( flags & FLAG_ROTATED )
+	{} //TODO: rotate surface
+	else */
+	if (flags & FLAG_ALPHA && what->format->BytesPerPixel == 1) //alpha on 8-bit surf - use custom blitter
+		CSDL_Ext::blit8bppAlphaTo24bpp(what, &srcRect, to, &dstRect);
+	else
+		CSDL_Ext::blitSurface(what, &srcRect, to, &dstRect);
+}
+
+void CShowableAnim::rotate(bool on)
+{
+	if (on)
+		flags |= FLAG_ROTATED;
+	else
+		flags &= ~FLAG_ROTATED;
+}
+
+CCreatureAnim::CCreatureAnim(int x, int y, std::string name, unsigned char flags, EAnimType type):
+	CShowableAnim(x,y,name,flags,3,type)
+{
+	if (flags & FLAG_PREVIEW)
+		callback = boost::bind(&CCreatureAnim::loopPreview,this);
+};
+
+void CCreatureAnim::loopPreview()
+{
+	std::vector<EAnimType> available;
+	if (anim.groupSize(ANIM_HOLDING))
+		available.push_back(ANIM_HOLDING);
+
+	if (anim.groupSize(ANIM_HITTED))
+		available.push_back(ANIM_HITTED);
+
+	if (anim.groupSize(ANIM_DEFENCE))
+		available.push_back(ANIM_DEFENCE);
+
+	if (anim.groupSize(ANIM_ATTACK_FRONT))
+		available.push_back(ANIM_ATTACK_FRONT);
+
+	if (anim.groupSize(ANIM_CAST_FRONT))
+		available.push_back(ANIM_CAST_FRONT);
+
+	size_t rnd = rand()%(available.size()*2);
+
+	if (rnd >= available.size())
+	{
+		if ( anim.groupSize(ANIM_MOVING) == 0 )//no moving animation present
+			addLast( ANIM_HOLDING );
+		else
+			addLast( ANIM_MOVING ) ;
+	}
+	else
+		addLast(available[rnd]);
+}
+
+void CCreatureAnim::addLast(EAnimType newType)
+{
+	if (type != ANIM_MOVING && newType == ANIM_MOVING)//starting moving - play init sequence
+	{
+		queue.push( ANIM_MOVE_START );
+	}
+	else if (type == ANIM_MOVING && newType != ANIM_MOVING )//previous anim was moving - finish it
+	{
+		queue.push( ANIM_MOVE_END);
+	}
+	if (newType == ANIM_TURN_L || newType == ANIM_TURN_R)
+		queue.push(newType);
+
+	queue.push(newType);
+}
+
+void CCreatureAnim::reset()
+{
+	//if we are in the middle of rotation - set flag
+	if (type == ANIM_TURN_L && !queue.empty() && queue.front() == ANIM_TURN_L)
+		flags |= FLAG_ROTATED;
+	if (type == ANIM_TURN_R && !queue.empty() && queue.front() == ANIM_TURN_R)
+		flags &= ~FLAG_ROTATED;
+
+	while (!queue.empty())//FIXME: remove dublication
+	{
+		EAnimType at = queue.front();
+		queue.pop();
+		if (set(at))
+			return;
+	}
+	if  (callback)
+		callback();
+	while (!queue.empty())
+	{
+		EAnimType at = queue.front();
+		queue.pop();
+		if (set(at))
+			return;
+	}
+	tlog0<<"Warning: next sequence is not found for animation!\n";
+}
+
+void CCreatureAnim::clearAndSet(EAnimType type)
+{
+	while (!queue.empty())
+		queue.pop();
+	set(type);
+}

+ 135 - 1
hch/CAnimation.h → client/CAnimation.h

@@ -1,10 +1,15 @@
 #ifndef __CANIMATION_H__
 #define __CANIMATION_H__
 
+#include <boost/function.hpp>
+
 #include <vector>
 #include <string>
+#include <queue>
 #include <set>
+
 #include "../global.h"
+#include "GUIBase.h"
 
 /*
  * CAnimation.h, part of VCMI engine
@@ -37,6 +42,7 @@ private:
 		ui32 TopMargin;
 	};
 
+	unsigned int type;
 	unsigned char * data;
 	int datasize;
 	BMPPalette * colors;
@@ -138,7 +144,7 @@ public:
 	void add(SDL_Surface * surf, bool shared=false, size_t group=0);
 
 	//removes all surfaces which have compressed data
-	void purgeCompressed();
+	void removeDecompressed(size_t frame, size_t group);
 
 	//get pointer to surface, this function ignores groups (like ourImages in DefHandler)
 	SDL_Surface * image (size_t frame);
@@ -173,7 +179,135 @@ public:
 
 	//total count of frames in whole anim
 	size_t size() const;
+};
+/*
+//Class for displaying one image from animation
+class CAnimImage: public CIntObject
+{
+private:
+	CAnimation anim;
+	size_t frame;//displayed frame/group
+	size_t group;
+
+public:
+	CAnimImage(int x, int y, std::string name, size_t Frame, size_t Group=0);//c-tor
+	~CAnimImage();//d-tor
+
+	//change displayed frame on this one
+	void setFrame(size_t Frame, size_t Group=0);
+	void show(SDL_Surface *to);
+	//TODO: showAll();
+};
+*/
+//Base class for displaying animation, used as superclass for different animations
+class CShowableAnim: public CIntObject
+{
+public:
+	enum EFlags
+	{
+		FLAG_BASE=1,       //base frame will be blitted before current one
+		FLAG_COMPRESSED=2, //animations will be loaded in compressed state
+		FLAG_ROTATED=4,    //will be displayed rotated
+		FLAG_ALPHA=8,      //if image is 8bbp it will be printed with transparency (0=opaque, 255=transparent)
+		FLAG_USERLE=16,    //not used for now, enable RLE compression from SDL
+		FLAG_PREVIEW=32    //for creatures only: several animation (move, attack, defence...) will be randomly selected
+	};
+
+protected:
+	CAnimation anim;
+	size_t group, frame;//current frame
+
+	size_t first, last; //animation range
+
+	unsigned char flags;//flags from EFlags enum
+
+	unsigned int frameDelay;//delay in frames of each image
+
+	unsigned int value;//how many times current frame was showed
+
+	//blit image with optional rotation, fitting into rect, etc
+	void blitImage(SDL_Surface *what, SDL_Surface *to);
+
+	//For clipping in rect, offsets of picture coordinates
+	int xOffset, yOffset;
+
+public:
+	//called when next animation sequence is required
+	boost::function<void()> callback;
+
+	CShowableAnim(int x, int y, std::string name, unsigned char flags, unsigned int Delay=4, size_t Group=0);
+	~CShowableAnim();
+
+	//set animation to group or part of group
+	bool set(size_t Group);
+	bool set(size_t Group, size_t from, size_t to=-1);
+
+	//set rotation flag
+	void rotate(bool on);
+
+	//move displayed part of picture (if picture is clipped to rect)
+	void movePic( int byX, int byY);
+
+	//set frame to first, call callback
+	virtual void reset();
+
+	//show current frame and increase counter
+	void show(SDL_Surface *to);
+	void showAll(SDL_Surface *to);
+};
+
+class CCreatureAnim: public CShowableAnim
+{
+public:
+
+	enum EAnimType // list of creature animations, numbers were taken from def files
+	{
+		ANIM_MOVING=0, //will automatically add MOVE_START and MOVE_END to queue
+		ANIM_MOUSEON=1,
+		ANIM_HOLDING=2,
+		ANIM_HITTED=3,
+		ANIM_DEFENCE=4,
+		ANIM_DEATH=5,
+		//ANIM_DEATH2=6, //unused?
+		ANIM_TURN_L=7, //will automatically play second part of anim and rotate creature
+		ANIM_TURN_R=8, //same
+		//ANIM_TURN_L2=9, //identical to previous?
+		//ANIM_TURN_R2=10,
+		ANIM_ATTACK_UP=11,
+		ANIM_ATTACK_FRONT=12,
+		ANIM_ATTACK_DOWN=13,
+		ANIM_SHOOT_UP=14,
+		ANIM_SHOOT_FRONT=15,
+		ANIM_SHOOT_DOWN=16,
+		ANIM_CAST_UP=17,
+		ANIM_CAST_FRONT=18,
+		ANIM_CAST_DOWN=19,
+		ANIM_2HEX_ATTACK_UP=17,
+		ANIM_2HEX_ATTACK_FRONT=18,
+		ANIM_2HEX_ATTACK_DOWN=19,
+		ANIM_MOVE_START=20, //no need to use this two directly - ANIM_MOVING will be enought
+		ANIM_MOVE_END=21
+	};
+
+private:
+	// queue of animations waiting to be displayed
+	std::queue<EAnimType> queue;
+
+	//this funcction is used as callback if preview flag was set during construction
+	void loopPreview();
+
+public:
+	//change anim to next if queue is not empty, call callback othervice
+	void reset();
+
+	//add sequence to the end of queue
+	void addLast(EAnimType newType);
+
+	//clear queue and set animation to this sequence
+	void clearAndSet(EAnimType type);
 
+	CCreatureAnim(int x, int y, std::string name, unsigned char flags=FLAG_COMPRESSED | FLAG_ALPHA | FLAG_PREVIEW,
+	              EAnimType type=ANIM_HOLDING);
 
 };
 

+ 4 - 4
client/CBattleInterface.cpp

@@ -4,7 +4,7 @@
 #include "SDL_Extensions.h"
 #include "CAdvmapInterface.h"
 #include "AdventureMapButton.h"
-#include "../hch/CAnimation.h"
+#include "CAnimation.h"
 #include "../hch/CObjectHandler.h"
 #include "../hch/CHeroHandler.h"
 #include "../hch/CDefHandler.h"
@@ -563,8 +563,8 @@ void CDefenceAnim::endAnim()
 	if(IDby!=-1)
 		owner->printConsoleAttacked(stackID, dmg, amountKilled, IDby);
 
-	const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false);
-	const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false);
+	//const CStack * attacker = owner->curInt->cb->battleGetStackByID(IDby, false);
+	//const CStack * attacked = owner->curInt->cb->battleGetStackByID(stackID, false);
 
 	CBattleAnimation::endAnim();
 
@@ -600,7 +600,7 @@ bool CBattleStackMoved::init()
 		endAnim();
 		return false;
 	}
-	bool twoTiles = movedStack->doubleWide();
+	//bool twoTiles = movedStack->doubleWide();
 	
 	Point begPosition = CBattleHex::getXYUnitAnim(curStackPos, movedStack->attackerOwned, movedStack, owner);
 	Point endPosition = CBattleHex::getXYUnitAnim(destHex, movedStack->attackerOwned, movedStack, owner);

+ 108 - 197
client/CCastleInterface.cpp

@@ -2,6 +2,7 @@
 #include "CCastleInterface.h"
 #include "AdventureMapButton.h"
 #include "CAdvmapInterface.h"
+#include "CAnimation.h"
 #include "../CCallback.h"
 #include "CGameInfo.h"
 #include "CHeroWindow.h"
@@ -20,7 +21,7 @@
 #include "../lib/map.h"
 #include <boost/algorithm/string.hpp>
 #include <boost/algorithm/string/replace.hpp>
-#include <boost/assign/std/vector.hpp> 
+#include <boost/assign/std/vector.hpp>
 #include <boost/lexical_cast.hpp>
 #include <cmath>
 #include <sstream>
@@ -52,45 +53,32 @@ int hordeToDwellingID(int bid)//helper, converts horde buiding ID into correspon
 }
 
 CBuildingRect::CBuildingRect(Structure *Str)
-	:moi(false), offset(0), str(Str)
+	:CShowableAnim(0, 0, Str->defName, CShowableAnim::FLAG_BASE),
+	moi(false), str(Str)
 {
-	def = CDefHandler::giveDef(Str->defName);
-	max = def->ourImages.size();
 
-	if(str->ID == 33    &&    str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette
-	{
-		for(std::vector<Cimage>::iterator i=def->ourImages.begin();i!=def->ourImages.end();i++)
-		{
-			SDL_SetColorKey(i->bitmap,SDL_SRCCOLORKEY,*((char*)i->bitmap->pixels));
-		}
-	}
+	pos.x += str->pos.x + LOCPLINT->castleInt->pos.x;
+	pos.y += str->pos.y + LOCPLINT->castleInt->pos.y;
+
+	if(str->ID == 33 && str->townID == 4) //little 'hack' for estate in necropolis - background color is not always the first color in the palette
+		for(size_t i=0; i<anim.groupSize(0);i++)
+			SDL_SetColorKey(anim.image(i,0), SDL_SRCCOLORKEY,
+			      *((char*)(anim.image(i,0)->pixels)));
 
-	pos.x = str->pos.x + LOCPLINT->castleInt->pos.x;
-	pos.y = str->pos.y + LOCPLINT->castleInt->pos.y;
-	pos.w = def->ourImages[0].bitmap->w;
-	pos.h = def->ourImages[0].bitmap->h;
 	if(Str->ID<0  || (Str->ID>=27 && Str->ID<=29))
 	{
 		area = border = NULL;
 		return;
 	}
 
-	border = BitmapHandler::loadBitmap(str->borderName);
-	if (border)
-	{
-		SDL_SetColorKey(border,SDL_SRCCOLORKEY,SDL_MapRGB(border->format,0,255,255));
-	}
-	else
+	border = BitmapHandler::loadBitmap(str->borderName, true);
+	if (!border)
 	{
 		tlog2 << "Warning: no border for "<<Str->ID<<std::endl;
 	}
 
-	area = BitmapHandler::loadBitmap(str->areaName); //FIXME look up
-	if (area)
-	{ 
-		;//SDL_SetColorKey(area,SDL_SRCCOLORKEY,SDL_MapRGB(area->format,0,255,255));
-	}
-	else
+	area = BitmapHandler::loadBitmap(str->areaName);
+	if (!area)
 	{
 		tlog2 << "Warning: no area for "<<Str->ID<<std::endl;
 	}
@@ -98,7 +86,6 @@ CBuildingRect::CBuildingRect(Structure *Str)
 
 CBuildingRect::~CBuildingRect()
 {
-	delete def;
 	if(border)
 		SDL_FreeSurface(border);
 	if(area)
@@ -152,16 +139,14 @@ void CBuildingRect::hover(bool on)
 		}
 	}
 }
+
 void CBuildingRect::clickLeft(tribool down, bool previousState)
 {
-	if( area && (LOCPLINT->castleInt->hBuild==this) && !(indeterminate(down)) &&
-		!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
-	{
-		if(previousState && !down)
+	if( previousState && !down && area && (LOCPLINT->castleInt->hBuild==this) )
+		if (!CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
 			LOCPLINT->castleInt->buildingClicked(str->ID);
-		//ClickableL::clickLeft(down);
-	}
 }
+
 void CBuildingRect::clickRight(tribool down, bool previousState)
 {
 	if((!area) || (!((bool)down)) || (this!=LOCPLINT->castleInt->hBuild))
@@ -169,7 +154,7 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
 	if( !CSDL_Ext::isTransparent(area, GH.current->motion.x-pos.x, GH.current->motion.y-pos.y) ) //inside building image
 	{
 		int bid = hordeToDwellingID(str->ID);
-		
+
 		CBuilding *bld = CGI->buildh->buildings[str->townID].find(bid)->second;
 		assert(bld);
 
@@ -186,11 +171,24 @@ void CBuildingRect::clickRight(tribool down, bool previousState)
 	}
 }
 
+void CBuildingRect::show(SDL_Surface *to)
+{
+	CShowableAnim::show(to);
+
+	if(LOCPLINT->castleInt->hBuild == this && border) //if this this higlighted structure and has border we'll blit it
+		blitAtLoc(border,0,0,to);
+}
+
+void CBuildingRect::showAll(SDL_Surface *to)
+{
+	show(to);
+}
+
 std::string getBuildingSubtitle(int tid, int bid)//hover text for building
 {
 	const CGTownInstance * t = LOCPLINT->castleInt->town;
 	bid = hordeToDwellingID(bid);
-	
+
 	if (bid<30)//non-dwellings - only buiding name
 		return CGI->buildh->buildings[tid].find(bid)->second->Name();
 	else//dwellings - recruit %creature%
@@ -214,27 +212,19 @@ void CBuildingRect::mouseMoved (const SDL_MouseMotionEvent & sEvent)
 		}
 		else //inside the area of this building
 		{
-			if(LOCPLINT->castleInt->hBuild) //a building is hovered
-			{
-				if((*LOCPLINT->castleInt->hBuild)<(*this)) //set if we are on top
-				{
-					LOCPLINT->castleInt->hBuild = this;
-					GH.statusbar->print(getBuildingSubtitle(str->townID, str->ID));
-				}
-			}
-			else //no building hovered
+			if(! LOCPLINT->castleInt->hBuild //no building hovered
+			  || (*LOCPLINT->castleInt->hBuild)<(*this)) //or we are on top
 			{
 				LOCPLINT->castleInt->hBuild = this;
 				GH.statusbar->print(getBuildingSubtitle(str->townID, str->ID));
 			}
 		}
 	}
-	//if(border)
-	//	blitAt(border,pos.x,pos.y);
 }
+
 void CHeroGSlot::hover (bool on)
 {
-	if(!on) 
+	if(!on)
 	{
 		GH.statusbar->clear();
 		return;
@@ -284,10 +274,6 @@ void CHeroGSlot::hover (bool on)
 		GH.statusbar->print(temp);
 }
 
-void CHeroGSlot::clickRight(tribool down, bool previousState)
-{
-}
-
 void CHeroGSlot::clickLeft(tribool down, bool previousState)
 {
 	CHeroGSlot *other = upg  ?  &owner->hslotup :  &owner->hslotdown;
@@ -341,19 +327,10 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
 	//}
 }
 
-void CHeroGSlot::activate()
-{
-	activateLClick();
-	activateRClick();
-	activateHover();
-}
-
 void CHeroGSlot::deactivate()
 {
 	highlight = false;
-	deactivateLClick();
-	deactivateRClick();
-	deactivateHover();
+	CIntObject::deactivate();
 }
 
 void CHeroGSlot::show(SDL_Surface * to)
@@ -544,7 +521,7 @@ void CCastleInterface::buildingClicked(int building)
 					}
 				}
 				else
-				{ 
+				{
 					enterMageGuild();
 				}
 				break;
@@ -572,8 +549,8 @@ void CCastleInterface::buildingClicked(int building)
 				if(!vstd::contains(town->forbiddenBuildings, 26))
 				{
 					LOCPLINT->showYesNoDialog(CGI->generaltexth->allTexts[597], //Do you wish this to be the permanent home of the Grail?
-												std::vector<SComponent*>(), 
-												boost::bind(&CCallback::buildBuilding, LOCPLINT->cb, town, 26), 
+												std::vector<SComponent*>(),
+												boost::bind(&CCallback::buildBuilding, LOCPLINT->cb, town, 26),
 												boost::bind(&CCastleInterface::enterHall, this), true);
 				}
 				else
@@ -643,7 +620,7 @@ void CCastleInterface::buildingClicked(int building)
 						GH.pushInt(new CUniversityWindow(town->garrisonHero, town));
 					else//no hero in town - default popup
 						defaultBuildingClicked(building);
-					
+
 					break;
 				default:
 					defaultBuildingClicked(building);
@@ -665,7 +642,7 @@ void CCastleInterface::buildingClicked(int building)
 								LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[126], std::vector<SComponent*>(), soundBase::sound_todo);
 								break;//only visiting hero can use castle gates
 							}
-							
+
 							std::vector <int> availableTowns;
 							std::vector <const CGTownInstance*> Towns = LOCPLINT->cb->getTownsInfo(false);
 							for(size_t i=0;i<Towns.size();i++)
@@ -690,15 +667,15 @@ void CCastleInterface::buildingClicked(int building)
 							hero = town->garrisonHero;
 						else
 							hero = NULL;//no hero - will trade with town garrison
-						
+
 						GH.pushInt ( new CTransformerWindow(hero, town) );
 						break;
-						
+
 	/*Dungeon*/		case 5: //Portal of Summoning
 						if (town->creatures[CREATURES_PER_TOWN].second.empty())
 						//extra dwelling has no creatures in it
 							LOCPLINT->showInfoDialog(CGI->generaltexth->tcommands[30], std::vector<SComponent*>(), soundBase::sound_todo);
-						else 
+						else
 							this->showRecruitmentWindow(CREATURES_PER_TOWN);
 					break;
 	/*Stronghold*/		case 6: //Ballista Yard
@@ -828,30 +805,13 @@ void CCastleInterface::townChange()
 
 void CCastleInterface::show(SDL_Surface * to)
 {
-	count++;
-	if(count==5)
-	{
-		count=0;
-		animval++;
-	}
-
 	blitAt(cityBg,pos,to);
 
 
 	//blit buildings
 	for(size_t i=0;i<buildings.size();i++)
 	{
-		int frame = ((animval)%(buildings[i]->max - buildings[i]->offset)) + buildings[i]->offset;
-		if(frame)
-		{
-			blitAt(buildings[i]->def->ourImages[0].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
-			blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
-		}
-		else
-			blitAt(buildings[i]->def->ourImages[frame].bitmap,buildings[i]->pos.x,buildings[i]->pos.y,to);
-
-		if(hBuild==buildings[i] && hBuild->border) //if this this higlighted structure and has border we'll blit it
-			blitAt(hBuild->border,hBuild->pos,to);
+		buildings[i]->showAll(to);
 	}
 	statusbar->show(to);//refreshing statusbar
 }
@@ -992,7 +952,7 @@ void CCastleInterface::recreateBuildings()
 			Structure * st = CGI->townh->structures[town->subID][20];
 			buildings.push_back(new CBuildingRect(st));
 			s.insert(std::pair<int,int>(st->group,st->ID));
-			isThereShip = true; 
+			isThereShip = true;
 		}
 	}
 
@@ -1012,13 +972,11 @@ void CCastleInterface::recreateBuildings()
 		}
 		if(town->builtBuildings.find(4)!=town->builtBuildings.end()) //there is mage Guild level 5
 		{
-			vortex->offset = 10;
-			vortex->max = vortex->def->ourImages.size();
+			vortex->set(0,10);
 		}
 		else
 		{
-			vortex->offset = 0;
-			vortex->max = 10;
+			vortex->set(0,0,9);
 		}
 	}
 	//code for the shipyard in the Castle
@@ -1043,13 +1001,11 @@ void CCastleInterface::recreateBuildings()
 			}
 			if(town->builtBuildings.find(8)!=town->builtBuildings.end()) //there is citadel
 			{
-				shipyard->offset = 1;
-				shipyard->max = shipyard->def->ourImages.size();
+				shipyard->set(0,1);
 			}
 			else
 			{
-				shipyard->offset = 0;
-				shipyard->max = 1;
+				shipyard->set(0,0,0);
 			}
 		}
 	}
@@ -1154,7 +1110,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
 		descr +="\n"+CGI->generaltexth->allTexts[590];
 		summ = CGI->creh->creatures[crid]->growth;
 		boost::algorithm::replace_first(descr,"%d", boost::lexical_cast<std::string>(summ));
-		
+
 		if ( level>=0 && level<CREATURES_PER_TOWN)
 		{
 
@@ -1168,7 +1124,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
 
 			summ+=AddToString(CGI->generaltexth->artifNames[133] + " %+d",descr,
 				summ * ci->town->valOfGlobalBonuses
-				(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion 
+				(Selector::type(Bonus::CREATURE_GROWTH_PERCENT) && Selector::sourceType(Bonus::ARTIFACT))/100); //Statue of Legion
 
 			if(ci->town->town->hordeLvl[0]==level)//horde, x to summ
 			if((bld.find(18)!=bld.end()) || (bld.find(19)!=bld.end()))
@@ -1200,7 +1156,7 @@ void CCastleInterface::CCreaInfo::clickRight(tribool down, bool previousState)
 			};
 			if (bl.size())
 				summ+=AddToString (CGI->arth->artifacts[bl.front().id]->Name()+" %+d", descr, bl.totalValue());
-			
+
 			//TODO: player bonuses
 
 			if(bld.find(26)!=bld.end()) //grail - +50% to ALL growth
@@ -1261,7 +1217,7 @@ void CCastleInterface::CTownInfo::hover(bool on)
 	{
 		std::string descr;
 		if ( bid == 6 ) {} //empty "no fort" icon. no hover message
-		else 
+		else
 		if ( bid == 14 ) //marketplace/income icon
 			descr = CGI->generaltexth->allTexts[255];
 		else
@@ -1282,7 +1238,7 @@ void CCastleInterface::CTownInfo::clickLeft(tribool down, bool previousState)
 void CCastleInterface::CTownInfo::clickRight(tribool down, bool previousState)
 {
 	if(down)
-	{	
+	{
 		if (( bid == 6 ) || ( bid == 14) )
 			return;
 		CInfoPopup *mess = new CInfoPopup();
@@ -1414,7 +1370,7 @@ void CHallInterface::CBuildingBox::show(SDL_Surface * to)
 	CCastleInterface *ci = LOCPLINT->castleInt;
 	if (( (BID == 18) && (vstd::contains(ci->town->builtBuildings,(ci->town->town->hordeLvl[0]+37))))
 	||  ( (BID == 24) && (vstd::contains(ci->town->builtBuildings,(ci->town->town->hordeLvl[1]+37)))) )
-		blitAt(ci->bicons->ourImages[BID+1].bitmap,pos.x,pos.y,to);		
+		blitAt(ci->bicons->ourImages[BID+1].bitmap,pos.x,pos.y,to);
 	else
 		blitAt(ci->bicons->ourImages[BID].bitmap,pos.x,pos.y,to);
 	int pom, pom2=-1;
@@ -1672,7 +1628,7 @@ CHallInterface::CBuildWindow::CBuildWindow(int Tid, int Bid, int State, bool Mod
 	CSDL_Ext::printAtMiddleWB(getTextForState(state),199,248,FONT_SMALL,50,zwykly,bitmap);
 	CSDL_Ext::printAtMiddle(CSDL_Ext::processStr(CGI->generaltexth->hcommands[7],pom),197,30,FONT_BIG,tytulowy,bitmap);
 
-	int resamount=0; 
+	int resamount=0;
 	for(int i=0;i<7;i++)
 	{
 		if(CGI->buildh->buildings[tid][bid]->resources[i])
@@ -1738,12 +1694,10 @@ CFortScreen::~CFortScreen()
 void CFortScreen::show( SDL_Surface * to)
 {
 	blitAt(bg,pos,to);
-	static unsigned char anim = 1;
 	for (int i=0; i<crePics.size(); i++)
 	{
-		crePics[i]->blitPic(to,pos.x+positions[i].x+159,pos.y+positions[i].y+4,!(anim%4));
+		crePics[i]->show(to);
 	}
-	anim++;
 	exit->show(to);
 	resdatabar->show(to);
 	GH.statusbar->show(to);
@@ -1775,7 +1729,7 @@ void CFortScreen::close()
 
 CFortScreen::CFortScreen( CCastleInterface * owner )
 {
-	if (owner->town->creatures.size() > CREATURES_PER_TOWN 
+	if (owner->town->creatures.size() > CREATURES_PER_TOWN
 	        && owner->town->creatures[CREATURES_PER_TOWN].second.size() )//dungeon with active portal
 		fortSize = CREATURES_PER_TOWN+1;
 	else
@@ -1809,11 +1763,11 @@ void CFortScreen::draw( CCastleInterface * owner, bool first)
 		bg2 = BitmapHandler::loadBitmap("TPCASTL7.bmp");
 	else
 		bg2 = BitmapHandler::loadBitmap("TPCASTL8.bmp");
-		
+
 	SDL_Surface *icons =  BitmapHandler::loadBitmap("ZPCAINFO.bmp");
 	SDL_SetColorKey(icons,SDL_SRCCOLORKEY,SDL_MapRGB(icons->format,0,255,255));
 	graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
-	bg = SDL_ConvertSurface(bg2,screen->format,0); 
+	bg = SDL_ConvertSurface(bg2,screen->format,0);
 	SDL_FreeSurface(bg2);
 	printAtMiddle(CGI->buildh->buildings[owner->town->subID][owner->town->fortLevel()+6]->Name(),400,13,FONT_MEDIUM,zwykly,bg);
 	for(int i=0;i<fortSize; i++)
@@ -1884,7 +1838,7 @@ void CFortScreen::draw( CCastleInterface * owner, bool first)
 		}
 		if(first)
 		{
-			crePics.push_back(new CCreaturePic(c,false));
+			crePics.push_back(new CCreaturePic( positions[i].x+pos.x+160, positions[i].y+pos.y+5, c,false));
 			if(present)
 			{
 				recAreas.push_back(new RecArea(i));
@@ -1906,24 +1860,32 @@ void CFortScreen::RecArea::clickRight(tribool down, bool previousState)
 }
 CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
 {
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+	
+	bg = new CPicture("TPMAGE.bmp");
+	pos = bg->center();
 	resdatabar = new CMinorResDataBar;
-	pos = owner->pos;
 	resdatabar->pos.x += pos.x;
 	resdatabar->pos.y += pos.y;
-	bg = BitmapHandler::loadBitmap("TPMAGE.bmp");
 	LOCPLINT->castleInt->statusbar->clear();
-	exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this),pos.x+748,pos.y+556,"TPMAGE1.DEF",SDLK_RETURN);
+	
+	exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this), 748, 556,"TPMAGE1.DEF",SDLK_RETURN);
 	exit->assignedKeys.insert(SDLK_ESCAPE);
-	scrolls2 = CDefHandler::giveDefEss("TPMAGES.DEF");
+	CAnimation scrolls("TPMAGES.DEF");
+	scrolls.load();
+	
 	SDL_Surface *view = BitmapHandler::loadBitmap(graphics->guildBgs[owner->town->subID]);
 	SDL_SetColorKey(view,SDL_SRCCOLORKEY,SDL_MapRGB(view->format,0,255,255));
+	blitAt(view,332,76,*bg);
+	SDL_FreeSurface(view);
+	
 	positions.resize(5);
 	positions[0] += genRect(61,83,222,445), genRect(61,83,312,445), genRect(61,83,402,445), genRect(61,83,520,445), genRect(61,83,610,445), genRect(61,83,700,445);
 	positions[1] += genRect(61,83,48,53), genRect(61,83,48,147), genRect(61,83,48,241), genRect(61,83,48,335), genRect(61,83,48,429);
 	positions[2] += genRect(61,83,570,82), genRect(61,83,672,82), genRect(61,83,570,157), genRect(61,83,672,157);
 	positions[3] += genRect(61,83,183,42), genRect(61,83,183,148), genRect(61,83,183,253);
 	positions[4] += genRect(61,83,491,325), genRect(61,83,591,325);
-	blitAt(view,332,76,bg);
+	
 	for(size_t i=0; i<owner->town->town->mageLevel; i++)
 	{
 		size_t sp = owner->town->spellsAtLevel(i+1,false); //spell at level with -1 hmmm?
@@ -1931,30 +1893,27 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
 		{
 			if(i<owner->town->mageGuildLevel() && owner->town->spells[i].size()>j)
 			{
-				spells.push_back(Scroll(&CGI->spellh->spells[owner->town->spells[i][j]]));
-				spells[spells.size()-1].pos = positions[i][j];
-				blitAt(graphics->spellscr->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],bg);
+				spells.push_back( new Scroll(&CGI->spellh->spells[owner->town->spells[i][j]]));
+				spells[spells.size()-1]->pos = positions[i][j];
+				blitAt(graphics->spellscr->ourImages[owner->town->spells[i][j]].bitmap,positions[i][j],*bg);
 			}
 			else
 			{
-				blitAt(scrolls2->ourImages[1].bitmap,positions[i][j],bg);
+				blitAt(scrolls.image(1),positions[i][j],*bg);
 			}
 		}
 	}
-	SDL_FreeSurface(view);
+	
 	for(size_t i=0;i<spells.size();i++)
 	{
-		spells[i].pos.x += pos.x;
-		spells[i].pos.y += pos.y;
+		spells[i]->pos.x += pos.x;
+		spells[i]->pos.y += pos.y;
 	}
-	delete scrolls2;
 }
 
 CMageGuildScreen::~CMageGuildScreen()
 {
-	delete exit;
-	SDL_FreeSurface(bg);
-	delete resdatabar;
+	
 }
 
 void CMageGuildScreen::close()
@@ -1962,30 +1921,10 @@ void CMageGuildScreen::close()
 	GH.popIntTotally(this);
 }
 
-void CMageGuildScreen::show(SDL_Surface * to)
-{
-	blitAt(bg,pos,to);
-	resdatabar->show(to);
-	GH.statusbar->show(to);
-	exit->show(to);
-}
-
-void CMageGuildScreen::activate()
+CMageGuildScreen::Scroll::Scroll(CSpell *Spell)
+	:spell(Spell)
 {
-	exit->activate();
-	for(size_t i=0;i<spells.size();i++)
-	{
-		spells[i].activate();
-	}
-}
-
-void CMageGuildScreen::deactivate()
-{
-	exit->deactivate();
-	for(size_t i=0;i<spells.size();i++)
-	{
-		spells[i].deactivate();
-	}
+	used = LCLICK | RCLICK | HOVER;
 }
 
 void CMageGuildScreen::Scroll::clickLeft(tribool down, bool previousState)
@@ -2017,7 +1956,6 @@ void CMageGuildScreen::Scroll::clickRight(tribool down, bool previousState)
 
 void CMageGuildScreen::Scroll::hover(bool on)
 {
-	//Hoverable::hover(on);
 	if(on)
 		GH.statusbar->print(spell->name);
 	else
@@ -2027,66 +1965,39 @@ void CMageGuildScreen::Scroll::hover(bool on)
 
 CBlacksmithDialog::CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid)
 {
-	SDL_Surface *bg2 = BitmapHandler::loadBitmap("TPSMITH.bmp");
-	SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
-	graphics->blueToPlayersAdv(bg2,LOCPLINT->playerID);
-	bmp = SDL_ConvertSurface(bg2,screen->format,0); 
-	SDL_FreeSurface(bg2);
-	bg2 = BitmapHandler::loadBitmap("TPSMITBK.bmp");
-	blitAt(bg2,64,50,bmp);
-	SDL_FreeSurface(bg2);
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+//	SDL_SetColorKey(bg2,SDL_SRCCOLORKEY,SDL_MapRGB(bg2->format,0,255,255));
+	bmp = new CPicture("TPSMITH");
+	bmp->colorizeAndConvert(LOCPLINT->playerID);
+	
+	pos = bmp->center();
+	
+	SDL_Surface *bg = BitmapHandler::loadBitmap("TPSMITBK.bmp");
+	blitAt(bg,64,50,*bmp);
+	SDL_FreeSurface(bg);
 
-	CCreatureAnimation cra(CGI->creh->creatures[creMachineID]->animDefName);
-	cra.nextFrameMiddle(bmp,170,120,true,0,false);
+	CCreatureAnim cra(170, 120, CGI->creh->creatures[creMachineID]->animDefName);
 	char pom[75];
 	sprintf(pom,CGI->generaltexth->allTexts[274].c_str(),CGI->creh->creatures[creMachineID]->nameSing.c_str()); //build a new ...
-	printAtMiddle(pom,165,28,FONT_MEDIUM,tytulowy,bmp);
-	printAtMiddle(CGI->generaltexth->jktexts[43],165,218,FONT_MEDIUM,zwykly,bmp); //resource cost
+	printAtMiddle(pom,165,28,FONT_MEDIUM,tytulowy,*bmp);
+	printAtMiddle(CGI->generaltexth->jktexts[43],165,218,FONT_MEDIUM,zwykly,*bmp); //resource cost
 	SDL_itoa(CGI->arth->artifacts[aid]->price,pom,10);
-	printAtMiddle(pom,165,290,FONT_MEDIUM,zwykly,bmp);
-
-	pos.w = bmp->w;
-	pos.h = bmp->h;
-	pos.x = screen->w/2 - pos.w/2;
-	pos.y = screen->h/2 - pos.h/2;
+	printAtMiddle(pom,165,290,FONT_MEDIUM,zwykly,*bmp);
 
-	buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 42,pos.y + 312,"IBUY30.DEF",SDLK_RETURN);
-	cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this),pos.x + 224,pos.y + 312,"ICANCEL.DEF",SDLK_ESCAPE);
+	buy = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this), 42, 312,"IBUY30.DEF",SDLK_RETURN);
+	cancel = new AdventureMapButton("","",boost::bind(&CBlacksmithDialog::close,this), 224, 312,"ICANCEL.DEF",SDLK_ESCAPE);
 
 	if(possible)
 		buy->callback += boost::bind(&CCallback::buyArtifact,LOCPLINT->cb,LOCPLINT->cb->getHeroInfo(hid,2),aid);
 	else
-		buy->bitmapOffset = 2;
+		buy->block(2);
 
-	blitAt(graphics->resources32->ourImages[6].bitmap,148,244,bmp);
-}
-
-void CBlacksmithDialog::show( SDL_Surface * to )
-{
-	blitAt(bmp,pos,to);
-	buy->show(to);
-	cancel->show(to);
-}
-
-void CBlacksmithDialog::activate()
-{
-	if(!buy->bitmapOffset)
-		buy->activate();
-	cancel->activate();
-}
-
-void CBlacksmithDialog::deactivate()
-{
-	if(!buy->bitmapOffset)
-		buy->deactivate();
-	cancel->deactivate();
+	blitAt(graphics->resources32->ourImages[6].bitmap,148,244,*bmp);
 }
 
 CBlacksmithDialog::~CBlacksmithDialog()
 {
-	SDL_FreeSurface(bmp);
-	delete cancel;
-	delete buy;
+	
 }
 
 void CBlacksmithDialog::close()

+ 11 - 16
client/CCastleInterface.h

@@ -5,6 +5,7 @@
 
 #include "../global.h"
 #include <SDL.h>
+#include "CAnimation.h"
 #include "GUIBase.h"
 #include "../hch/CMusicBase.h"
 //#include "boost/tuple/tuple.hpp"
@@ -19,6 +20,7 @@ class CStatusBar;
 class CTownList;
 class CRecruitmentWindow;
 class CTransformerWindow;
+class CPicture;
 class CCreaturePic;
 class CMinorResDataBar;
 
@@ -32,13 +34,11 @@ class CMinorResDataBar;
  *
  */
 
-class CBuildingRect : public CIntObject
+class CBuildingRect : public CShowableAnim
 {
 public:
 	bool moi; //motion interested is active
-	int offset, max; //first and last animation frame
 	Structure* str;
-	CDefHandler* def;
 	SDL_Surface* border;
 	SDL_Surface* area;
 	CBuildingRect(Structure *Str); //c-tor
@@ -50,6 +50,8 @@ public:
 	void clickLeft(tribool down, bool previousState);
 	void clickRight(tribool down, bool previousState);
 	void mouseMoved (const SDL_MouseMotionEvent & sEvent);
+	void show(SDL_Surface *to);
+	void showAll(SDL_Surface *to);
 };
 
 class CHeroGSlot : public CIntObject
@@ -63,9 +65,7 @@ public:
 	void setHighlight(bool on);
 
 	void hover (bool on);
-	void clickRight(tribool down, bool previousState);
 	void clickLeft(tribool down, bool previousState);
-	void activate();
 	void deactivate();
 	void show(SDL_Surface * to);
 	CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner); //c-tor
@@ -240,40 +240,35 @@ public:
 	public:
 		CSpell *spell;
 
-		Scroll(CSpell *Spell):spell(Spell){used = LCLICK | RCLICK | HOVER;};
+		Scroll(CSpell *Spell);
 		void clickLeft(tribool down, bool previousState);
 		void clickRight(tribool down, bool previousState);
 		void hover(bool on);
 	};
 	std::vector<std::vector<SDL_Rect> > positions;
 
-	SDL_Surface *bg;
-	CDefEssential *scrolls, *scrolls2;
+	CPicture *bg;
 	AdventureMapButton *exit;
-	std::vector<Scroll> spells;
+	std::vector<Scroll *> spells;
 	CMinorResDataBar * resdatabar;
 
 
 	CMageGuildScreen(CCastleInterface * owner); //c-tor
 	~CMageGuildScreen(); //d-tor
 	void close();
-	void show(SDL_Surface * to);
-	void activate();
-	void deactivate();
+
 };
 
 class CBlacksmithDialog : public CIntObject
 {
 public:
 	AdventureMapButton *buy, *cancel;
-	SDL_Surface *bmp; //background
+	CPicture *bmp; //background
+	CCreatureAnim * anim;
 
 	CBlacksmithDialog(bool possible, int creMachineID, int aid, int hid); //c-tor
 	~CBlacksmithDialog(); //d-tor
 	void close();
-	void show(SDL_Surface * to);
-	void activate();
-	void deactivate();
 };
 
 #endif // __CCASTLEINTERFACE_H__

+ 1 - 1
client/CMessage.cpp

@@ -2,7 +2,7 @@
 #include "CMessage.h"
 #include "SDL_ttf.h"
 #include "../hch/CDefHandler.h"
-#include "../hch/CAnimation.h"
+#include "CAnimation.h"
 #include "CGameInfo.h"
 #include "SDL_Extensions.h"
 #include "../hch/CLodHandler.h"

+ 6 - 6
client/CPreGame.cpp

@@ -9,7 +9,7 @@
 #include "SDL_Extensions.h"
 #include "CGameInfo.h"
 #include "CCursorHandler.h"
-#include "../hch/CAnimation.h"
+#include "CAnimation.h"
 #include "../hch/CDefHandler.h"
 #include "../hch/CDefObjInfoHandler.h"
 #include "../hch/CGeneralTextHandler.h"
@@ -2097,8 +2097,8 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero)
 	if(!btns[0])
 		return;
 
-	if(!onlyHero  &&  pi.defaultCastle() != -1 //fixed tow
-		|| SEL->isGuest() && s.color != playerColor) //or not our player
+	if( (!onlyHero  &&  pi.defaultCastle() != -1) //fixed tow
+		|| (SEL->isGuest() && s.color != playerColor)) //or not our player
 	{
 		btns[0]->disable();
 		btns[1]->disable();
@@ -2109,8 +2109,8 @@ void OptionsTab::PlayerOptionsEntry::selectButtons(bool onlyHero)
 		btns[1]->enable(active);
 	}
 
-	if(pi.defaultHero() != -1  ||  !s.human  ||  s.castle < 0 //fixed hero
-		|| SEL->isGuest() && s.color != playerColor)//or not our player
+	if( (pi.defaultHero() != -1  ||  !s.human  ||  s.castle < 0) //fixed hero
+		|| (SEL->isGuest() && s.color != playerColor))//or not our player
 	{
 		btns[2]->disable();
 		btns[3]->disable();
@@ -3128,7 +3128,7 @@ void CBonusSelection::CRegion::clickRight( tribool down, bool previousState )
 
 void CBonusSelection::CRegion::show( SDL_Surface * to )
 {
-	const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber];
+	//const SCampPositions::SRegionDesc & desc = owner->campDescriptions[owner->ourCampaign->camp->header.mapVersion].regions[myNumber];
 	if (!accessible)
 	{
 		//show as striped

+ 45 - 60
client/GUIClasses.cpp

@@ -15,7 +15,7 @@
 #include "CConfigHandler.h"
 #include "CCreatureAnimation.h"
 #include "Graphics.h"
-#include "../hch/CAnimation.h"
+#include "CAnimation.h"
 #include "../hch/CArtHandler.h"
 #include "../hch/CBuildingHandler.h"
 #include "../hch/CGeneralTextHandler.h"
@@ -1632,37 +1632,37 @@ int CTownList::size()
 	return LOCPLINT->towns.size();
 }
 
-CCreaturePic::CCreaturePic(const CCreature *cre, bool Big)
+CCreaturePic::CCreaturePic(int x, int y, const CCreature *cre, bool Big, bool Animated)
 :c(cre),big(Big)
 {
-	anim = new CCreatureAnimation(cre->animDefName);
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+	pos.x+=x;
+	pos.y+=y;
+	
+	x = 225 - (c->isDoubleWide()?63:78);
+	y = 225 - (big?75:65);
+	
+	anim = new CCreatureAnim(0,0, cre->animDefName);
+	anim->movePic(x,y);
+	anim->pos.w = 100;
+	anim->pos.h = big?130:120;
 }
+
 CCreaturePic::~CCreaturePic()
 {
-	delete anim;
+	
 }
-int CCreaturePic::blitPic(SDL_Surface *to, int x, int y, bool nextFrame)
+
+void CCreaturePic::show(SDL_Surface *to)
 {
-	SDL_Rect dst;
 	if(big)
-	{
-		blitAt(graphics->backgrounds[c->faction],x,y,to);//curx-50,pos.y+130-65);
-		dst = genRect(130,100,x,y);
-	}
+		blitAtLoc(graphics->backgrounds[c->faction],0,0,to);
 	else
-	{
-		blitAt(graphics->backgroundsm[c->faction],x,y,to);//curx-50,pos.y+130-65);
-		dst = genRect(120,100,x,y);
-	}
-	if(c->isDoubleWide())
-		x-=15;
-	return anim->nextFrameMiddle(to,x+78,y+(big ? 55 : 45),true,0,nextFrame,false,false,&dst);
-}
-SDL_Surface * CCreaturePic::getPic(bool nextFrame)
-{
-	//TODO: write
-	return NULL;
+		blitAtLoc(graphics->backgroundsm[c->faction],0,0,to);
+
+	CIntObject::show(to);
 }
+
 void CRecruitmentWindow::close()
 {
 	GH.popIntTotally(this);
@@ -1783,7 +1783,6 @@ void CRecruitmentWindow::deactivate()
 
 void CRecruitmentWindow::show(SDL_Surface * to)
 {
-	static char animCounter=0; //animation counter - for determining appropriate animation frame to be shown
 	blitAt(bitmap,pos.x,pos.y,to);
 	buy->show(to);
 	max->show(to);
@@ -1809,14 +1808,9 @@ void CRecruitmentWindow::show(SDL_Surface * to)
 		curx+=32+16;//size of bitmap + distance between them
 	}
 
-	curx = pos.x + 192 + CREATURE_WIDTH - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
 	for(int i=0; i<creatures.size(); ++i)
-	{
-		creatures[i].pic->blitPic(to, curx-50, pos.y+130-65, !(animCounter%4));
-		curx += TOTAL_CREATURE_WIDTH;
-	}
+		creatures[i].pic->show(to);
 
-	++animCounter;
 	bar->show(to);
 }
 
@@ -1854,17 +1848,18 @@ CRecruitmentWindow::CRecruitmentWindow(const CGDwelling *Dwelling, int Level, co
 	drawBorder(bitmap,289,312,66,34,int3(173,142,66));
 
 	//border for creatures
-	int curx = 192 + 51 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
+	int curx = 192 + 50 - (CREATURE_WIDTH*creatures.size()/2) - (SPACE_BETWEEN*(creatures.size()-1)/2);
 	for(int i=0;i<creatures.size();i++)
 	{
-		creatures[i].pos.x = curx+1;
+		creatures[i].pos.x = curx;
 		creatures[i].pos.y = 65;
 		creatures[i].pos.w = 100;
 		creatures[i].pos.h = 130;
 		if(which==i)
-			drawBorder(bitmap,curx,64,CREATURE_WIDTH,132,int3(255,0,0));
+			drawBorder(bitmap,curx-1,64,CREATURE_WIDTH,132,int3(255,0,0));
 		else
-			drawBorder(bitmap,curx,64,CREATURE_WIDTH,132,int3(239,215,123));
+			drawBorder(bitmap,curx-1,64,CREATURE_WIDTH,132,int3(239,215,123));
+		creatures[i].pic = new CCreaturePic(pos.x+curx, pos.y+65, CGI->creh->creatures[creatures[i].ID]);
 		curx += TOTAL_CREATURE_WIDTH;
 	}
 
@@ -1902,8 +1897,7 @@ void CRecruitmentWindow::initCres()
 
 			cur.amount = dwelling->creatures[i].first;
 			cur.ID = dwelling->creatures[i].second[j];
-			const CCreature *cre = CGI->creh->creatures[cur.ID];
-			cur.pic = new CCreaturePic(cre);
+			CCreature * cre= CGI->creh->creatures[cur.ID];
 
 			for(int k=0; k<cre->cost.size(); k++)
 				if(cre->cost[k])
@@ -1948,8 +1942,8 @@ CSplitWindow::CSplitWindow(int cid, int max, CGarrisonInt *Owner, int Last, int
 	slider = new CSlider(pos.x+21,pos.y+194,257,boost::bind(&CSplitWindow::sliderMoved,this,_1),0,sliderPositions,val,true);
 	a1 = max-val;
 	a2 = val;
-	anim = new CCreaturePic(CGI->creh->creatures[cid]);
-	anim->anim->setType(1);
+	animLeft = new CCreaturePic(pos.x+20,  pos.y+54, CGI->creh->creatures[cid], true, false);
+	animRight = new CCreaturePic(pos.x+177, pos.y+54, CGI->creh->creatures[cid], true, false);
 
 	std::string title = CGI->generaltexth->allTexts[256];
 	boost::algorithm::replace_first(title,"%s",CGI->creh->creatures[cid]->namePl);
@@ -1962,7 +1956,8 @@ CSplitWindow::~CSplitWindow() //d-tor
 	delete ok;
 	delete cancel;
 	delete slider;
-	delete anim;
+	delete animLeft;
+	delete animRight;
 }
 
 void CSplitWindow::activate()
@@ -2010,8 +2005,8 @@ void CSplitWindow::show(SDL_Surface * to)
 	slider->show(to);
 	printAtMiddle(boost::lexical_cast<std::string>(a1) + (!which ? "_" : ""),pos.x+70,pos.y+237,FONT_BIG,zwykly,to);
 	printAtMiddle(boost::lexical_cast<std::string>(a2) + (which ? "_" : ""),pos.x+233,pos.y+237,FONT_BIG,zwykly,to);
-	anim->blitPic(to,pos.x+20,pos.y+54,false);
-	anim->blitPic(to,pos.x+177,pos.y+54,false);
+	animLeft->show(to);
+	animRight->show(to);
 }
 
 void CSplitWindow::keyPressed (const SDL_KeyboardEvent & key)
@@ -2077,9 +2072,7 @@ void CSplitWindow::clickLeft(tribool down, bool previousState)
 void CCreInfoWindow::show(SDL_Surface * to)
 {
 	blitAt(*bitmap,pos.x,pos.y,to);
-	anim->blitPic(to,pos.x+21,pos.y+48,(type) && !(anf%4));
-	if(++anf==4) 
-		anf=0;
+	anim->show(to);
 	if(count.size())
 		printTo(count.c_str(),pos.x+114,pos.y+174,FONT_TIMES,zwykly,to);
 	if(upgrade)
@@ -2157,7 +2150,6 @@ CCreInfoWindow::CCreInfoWindow(const CStackInstance &st, int Type, boost::functi
 			if(printed >= 3) //we can fit only 3 effects
 				break;
 		}
-
 		//print current health
 		printLine(5, CGI->generaltexth->allTexts[200], battleStack->firstHPleft);
 	}
@@ -2188,19 +2180,13 @@ void CCreInfoWindow::init(const CCreature *cre, const CStackInstance *stack, int
 	else
 		finalNode = cre;
 
-	anf = 0;
 	c = cre;
 
 	bitmap = new CPicture("CRSTKPU.bmp");
 	bitmap->colorizeAndConvert(LOCPLINT->playerID);
 	pos = bitmap->center();
 
-	{
-		BLOCK_CAPTURING;
-		anim = new CCreaturePic(c);
-	}
-
-	if(!type) anim->anim->setType(2);
+	anim = new CCreaturePic(21, 48, c);
 
 	count = boost::lexical_cast<std::string>(creatureCount);
 
@@ -2253,7 +2239,6 @@ CCreInfoWindow::CCreInfoWindow(int Cid, int Type, int creatureCount)
 
 CCreInfoWindow::~CCreInfoWindow()
 {
-	delete anim;
  	for(int i=0; i<upgResCost.size();i++)
  		delete upgResCost[i];
 }
@@ -2425,6 +2410,11 @@ void CMinorResDataBar::show(SDL_Surface * to)
 		,pos.x+545+(pos.w-545)/2,pos.y+pos.h/2,FONT_SMALL,zwykly,to);
 }
 
+void CMinorResDataBar::showAll(SDL_Surface * to)
+{
+	show(to);
+}
+
 CMinorResDataBar::CMinorResDataBar()
 {
 	bg = BitmapHandler::loadBitmap("Z2ESBAR.bmp");
@@ -2913,8 +2903,10 @@ void CTradeWindow::getPositionsFor(std::vector<Rect> &poss, bool Left, EType typ
 			genRect(h, w, x + dx, y + 2*dy);
 
 		if(!Left)
+		{
 			BOOST_FOREACH(Rect &r, poss)
 				r.x += leftToRightOffset;
+		}
 	}
 }
 
@@ -3269,7 +3261,7 @@ void CMarketplaceWindow::selectionChanged(bool side)
 
 bool CMarketplaceWindow::printButtonFor(EMarketMode M) const
 {
-	return market->allowsTrade(M) && M != mode && (hero || M != CREATURE_RESOURCE && M != RESOURCE_ARTIFACT && M != ARTIFACT_RESOURCE);
+	return market->allowsTrade(M) && M != mode && (hero || ( M != CREATURE_RESOURCE && M != RESOURCE_ARTIFACT && M != ARTIFACT_RESOURCE ));
 }
 
 void CMarketplaceWindow::garrisonChanged()
@@ -6013,16 +6005,9 @@ CHillFortWindow::~CHillFortWindow()
 void CHillFortWindow::activate()
 {
 	CIntObject::activate();
-	garr->activate();
 	GH.statusbar = bar;
 }
 
-void CHillFortWindow::deactivate()
-{
-	CIntObject::deactivate();
-	garr->deactivate();
-}
-
 void CHillFortWindow::updateGarrisons()
 {
 	

+ 16 - 15
client/GUIClasses.h

@@ -42,7 +42,7 @@ class SComponent;
 class CCreature;
 struct SDL_Surface;
 struct CPath;
-class CCreatureAnimation;
+class CCreatureAnim;
 class CSelectableComponent;
 class CCreatureSet;
 class CGObjectInstance;
@@ -435,16 +435,18 @@ public:
 	int size(); //how many elements do we have
 };
 
-class CCreaturePic //draws picture with creature on background, use nextFrame=true to get animation
+class CCreaturePic : public CIntObject //draws picture with creature on background, use Animated=true to get animation
 {
-public:
+private:
 	const CCreature *c; //which creature's picture
 	bool big; //big => 100x130; !big => 100x120
-	CCreatureAnimation *anim; //displayed animation
-	CCreaturePic(const CCreature *cre, bool Big=true); //c-tor
+	CCreatureAnim *anim; //displayed animation
+	
+public:
+	CCreaturePic(int x, int y, const CCreature *cre, bool Big=true, bool Animated=true); //c-tor
 	~CCreaturePic(); //d-tor
-	int blitPic(SDL_Surface *to, int x, int y, bool nextFrame); //prints creature on screen
-	SDL_Surface * getPic(bool nextFrame); //returns frame of animation
+	void show(SDL_Surface *to); //prints creature on screen
+	
 };
 
 class CRecruitmentWindow : public CIntObject
@@ -496,7 +498,7 @@ class CSplitWindow : public CIntObject
 public:
 	CGarrisonInt *gar;
 	CSlider *slider;
-	CCreaturePic *anim; //creature's animation
+	CCreaturePic *animLeft, *animRight; //creature's animation
 	AdventureMapButton *ok, *cancel;
 	SDL_Surface *bitmap; //background
 	int a1, a2, c; //TODO: comment me
@@ -538,6 +540,7 @@ class CMinorResDataBar : public CIntObject
 public:
 	SDL_Surface *bg; //background bitmap
 	void show(SDL_Surface * to);
+	void showAll(SDL_Surface * to);
 	CMinorResDataBar(); //c-tor
 	~CMinorResDataBar(); //d-tor
 };
@@ -865,7 +868,6 @@ public:
 	//bool active; //TODO: comment me
 	int type;//0 - rclick popup; 1 - normal window
 	CPicture *bitmap; //background
-	char anf; //animation counter
 	std::string count; //creature count in text format
 
 	boost::function<void()> dsm; //dismiss button callback
@@ -1082,7 +1084,7 @@ class CUniversityWindow : public CIntObject
 	public:
 		int ID;//id of selected skill
 		CUniversityWindow * parent;
-		
+
 		void showAll(SDL_Surface * to);
 		void clickLeft(tribool down, bool previousState);
 		void clickRight(tribool down, bool previousState);
@@ -1094,14 +1096,14 @@ class CUniversityWindow : public CIntObject
 public:
 	const CGHeroInstance *hero;
 	const IMarket * market;
-	
+
 	CPicture * green, * yellow, * red;//colored bars near skills
 	CPicture *bg; //background
 	std::vector<CItem*> items;
 
 	AdventureMapButton *cancel;
 	CGStatusBar *bar;
-	
+
 	CUniversityWindow(const CGHeroInstance * _hero, const IMarket * _market); //c-tor
 	~CUniversityWindow(); //d-tor
 };
@@ -1136,13 +1138,12 @@ public:
 	const CGHeroInstance * hero;
 	std::vector<int> currState;//current state of slot - to avoid calls to getState or updating buttons
 	std::vector<std::map<int,int> > costs;// costs [slot ID] [resource ID] = resource count for upgrade
-	std::vector<int> totalSumm; // totalSum[resource ID] = value 
+	std::vector<int> totalSumm; // totalSum[resource ID] = value
 
 	CHillFortWindow(const CGHeroInstance *visitor, const CGObjectInstance *object); //c-tor
 	~CHillFortWindow(); //d-tor
-	
+
 	void activate();
-	void deactivate();
 	void showAll (SDL_Surface *to);
 	std::string getDefForSlot(int slot);//return def name for this slot
 	std::string getTextForSlot(int slot);//return hover text for this slot

+ 2 - 2
client/Makefile.am

@@ -13,8 +13,6 @@ vcmiclient_SOURCES =  \
 	../CThreadHelper.h \
 	../StartInfo.h \
 	../global.h \
-	../hch/CAnimation.h \
-	../hch/CAnimation.cpp \
 	../hch/CBuildingHandler.h \
 	../hch/CDefHandler.cpp \
 	../hch/CDefHandler.h \
@@ -39,6 +37,8 @@ vcmiclient_SOURCES =  \
 	AdventureMapButton.h \
 	CAdvmapInterface.cpp \
 	CAdvmapInterface.h \
+	CAnimation.h \
+	CAnimation.cpp \
 	CBattleInterface.cpp \
 	CBattleInterface.h \
 	CBitmapHandler.cpp \

+ 19 - 19
client/Makefile.in

@@ -59,7 +59,6 @@ PROGRAMS = $(bin_PROGRAMS)
 am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \
 	vcmiclient-CGameInterface.$(OBJEXT) \
 	vcmiclient-CThreadHelper.$(OBJEXT) \
-	vcmiclient-CAnimation.$(OBJEXT) \
 	vcmiclient-CDefHandler.$(OBJEXT) \
 	vcmiclient-CMusicHandler.$(OBJEXT) \
 	vcmiclient-CSndHandler.$(OBJEXT) \
@@ -67,6 +66,7 @@ am_vcmiclient_OBJECTS = vcmiclient-CCallback.$(OBJEXT) \
 	vcmiclient-CMapInfo.$(OBJEXT) \
 	vcmiclient-AdventureMapButton.$(OBJEXT) \
 	vcmiclient-CAdvmapInterface.$(OBJEXT) \
+	vcmiclient-CAnimation.$(OBJEXT) \
 	vcmiclient-CBattleInterface.$(OBJEXT) \
 	vcmiclient-CBitmapHandler.$(OBJEXT) \
 	vcmiclient-CCastleInterface.$(OBJEXT) \
@@ -282,8 +282,6 @@ vcmiclient_SOURCES = \
 	../CThreadHelper.h \
 	../StartInfo.h \
 	../global.h \
-	../hch/CAnimation.h \
-	../hch/CAnimation.cpp \
 	../hch/CBuildingHandler.h \
 	../hch/CDefHandler.cpp \
 	../hch/CDefHandler.h \
@@ -308,6 +306,8 @@ vcmiclient_SOURCES = \
 	AdventureMapButton.h \
 	CAdvmapInterface.cpp \
 	CAdvmapInterface.h \
+	CAnimation.h \
+	CAnimation.cpp \
 	CBattleInterface.cpp \
 	CBattleInterface.h \
 	CBitmapHandler.cpp \
@@ -546,22 +546,6 @@ vcmiclient-CThreadHelper.obj: ../CThreadHelper.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CThreadHelper.obj `if test -f '../CThreadHelper.cpp'; then $(CYGPATH_W) '../CThreadHelper.cpp'; else $(CYGPATH_W) '$(srcdir)/../CThreadHelper.cpp'; fi`
 
-vcmiclient-CAnimation.o: ../hch/CAnimation.cpp
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
-@am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f '../hch/CAnimation.cpp' || echo '$(srcdir)/'`../hch/CAnimation.cpp
-
-vcmiclient-CAnimation.obj: ../hch/CAnimation.cpp
-@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi`
-@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
-@am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='../hch/CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f '../hch/CAnimation.cpp'; then $(CYGPATH_W) '../hch/CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/../hch/CAnimation.cpp'; fi`
-
 vcmiclient-CDefHandler.o: ../hch/CDefHandler.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CDefHandler.o -MD -MP -MF $(DEPDIR)/vcmiclient-CDefHandler.Tpo -c -o vcmiclient-CDefHandler.o `test -f '../hch/CDefHandler.cpp' || echo '$(srcdir)/'`../hch/CDefHandler.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CDefHandler.Tpo $(DEPDIR)/vcmiclient-CDefHandler.Po
@@ -674,6 +658,22 @@ vcmiclient-CAdvmapInterface.obj: CAdvmapInterface.cpp
 @AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAdvmapInterface.obj `if test -f 'CAdvmapInterface.cpp'; then $(CYGPATH_W) 'CAdvmapInterface.cpp'; else $(CYGPATH_W) '$(srcdir)/CAdvmapInterface.cpp'; fi`
 
+vcmiclient-CAnimation.o: CAnimation.cpp
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.o -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.o `test -f 'CAnimation.cpp' || echo '$(srcdir)/'`CAnimation.cpp
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
+@am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='CAnimation.cpp' object='vcmiclient-CAnimation.o' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.o `test -f 'CAnimation.cpp' || echo '$(srcdir)/'`CAnimation.cpp
+
+vcmiclient-CAnimation.obj: CAnimation.cpp
+@am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CAnimation.obj -MD -MP -MF $(DEPDIR)/vcmiclient-CAnimation.Tpo -c -o vcmiclient-CAnimation.obj `if test -f 'CAnimation.cpp'; then $(CYGPATH_W) 'CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/CAnimation.cpp'; fi`
+@am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CAnimation.Tpo $(DEPDIR)/vcmiclient-CAnimation.Po
+@am__fastdepCXX_FALSE@	$(AM_V_CXX) @AM_BACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	source='CAnimation.cpp' object='vcmiclient-CAnimation.obj' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCXX_FALSE@	DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCXX_FALSE@	$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -c -o vcmiclient-CAnimation.obj `if test -f 'CAnimation.cpp'; then $(CYGPATH_W) 'CAnimation.cpp'; else $(CYGPATH_W) '$(srcdir)/CAnimation.cpp'; fi`
+
 vcmiclient-CBattleInterface.o: CBattleInterface.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(vcmiclient_CXXFLAGS) $(CXXFLAGS) -MT vcmiclient-CBattleInterface.o -MD -MP -MF $(DEPDIR)/vcmiclient-CBattleInterface.Tpo -c -o vcmiclient-CBattleInterface.o `test -f 'CBattleInterface.cpp' || echo '$(srcdir)/'`CBattleInterface.cpp
 @am__fastdepCXX_TRUE@	$(AM_V_at)$(am__mv) $(DEPDIR)/vcmiclient-CBattleInterface.Tpo $(DEPDIR)/vcmiclient-CBattleInterface.Po

+ 9 - 5
hch/CLodHandler.cpp

@@ -91,19 +91,23 @@ unsigned char * CLodHandler::giveFile(const std::string defName, LodFileType typ
 	if (ourEntry.offset<0) //file is in the sprites/ folder; no compression
 	{
 		int result;
-		unsigned char * outp = new unsigned char[ourEntry.realSize];
+		outp = new unsigned char[ourEntry.realSize];
 		FILE * f = fopen((myDir + "/" + ourEntry.realName).c_str(), "rb");
-		if (f) {
+		if (f)
+		{
 			result = fread(outp,1,ourEntry.realSize,f);
 			fclose(f);
-		} else
+		}
+		else
 			result = -1;
 		mutex->unlock();
-		if(result<0) {
+		if(result<0)
+		{
 			tlog1<<"Error in file reading: " << myDir << "/" << ourEntry.name << std::endl;
 			delete[] outp;
 			return NULL;
-		} else
+		}
+		else
 			return outp;
 	}
 	else if (ourEntry.size==0) //file is not compressed