浏览代码

- minor tweaks to quest window
- fixed #531
- fixed query crash (empty funciton)

Ivan Savenko 13 年之前
父节点
当前提交
13de841e10

+ 1 - 1
client/AdventureMapClasses.cpp

@@ -536,7 +536,7 @@ void CMinimap::moveAdvMapSelection()
 	int3 newLocation = translateMousePosition();
 	adventureInt->centerOn(newLocation);
 
-	redraw();
+	GH.totalRedraw(); //redraw this as well as adventure map (which may be inactive)
 }
 
 void CMinimap::clickLeft(tribool down, bool previousState)

+ 15 - 5
client/CCastleInterface.cpp

@@ -367,7 +367,7 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
 			other->setHighlight(false);
 
 			if(allow)
-				LOCPLINT->cb->swapGarrisonHero(owner->town);
+				owner->swapArmies();
 		}
 		else if(hero)
 		{
@@ -1228,10 +1228,7 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
 		townlist->selectNext();
 		break;
 	case SDLK_SPACE:
-		if(!!town->visitingHero && town->garrisonHero)
-		{
-			LOCPLINT->cb->swapGarrisonHero(town);
-		}
+		heroes->swapArmies();
 		break;
 	case SDLK_t:
 		if(town->hasBuilt(EBuilding::TAVERN))
@@ -1266,6 +1263,19 @@ void HeroSlots::splitClicked()
 	}
 }
 
+void HeroSlots::swapArmies()
+{
+	if(!town->garrisonHero && town->visitingHero) //visiting => garrison, merge armies: town army => hero army
+	{
+		if(!town->visitingHero->canBeMergedWith(*town))
+		{
+			LOCPLINT->showInfoDialog(CGI->generaltexth->allTexts[275], std::vector<CComponent*>(), soundBase::sound_todo);
+			return;
+		}
+	}
+	LOCPLINT->cb->swapGarrisonHero(town);
+}
+
 void CHallInterface::CBuildingBox::hover(bool on)
 {
 	if(on)

+ 1 - 0
client/CCastleInterface.h

@@ -107,6 +107,7 @@ public:
 
 	void splitClicked(); //for hero meeting only (splitting stacks is handled by garrison int)
 	void update();
+	void swapArmies(); //exchange garrisoned and visiting heroes or move hero to\from garrison
 };
 
 /// Class for town screen management (town background and structures)

+ 6 - 15
client/CPreGame.cpp

@@ -434,7 +434,9 @@ void CreditsScreen::clickRight(tribool down, bool previousState)
 CGPreGame::CGPreGame():
 	pregameConfig(new JsonNode(GameConstants::DATA_DIR + "/config/mainmenu.json"))
 {
-	//OBJ_CONSTRUCTION_CAPTURING_ALL;
+	pos.w = screen->w;
+	pos.h = screen->h;
+
 	GH.defActionsDef = 63;
 	CGP = this;
 	menu = new CMenuScreen((*pregameConfig)["window"]);
@@ -453,7 +455,9 @@ void CGPreGame::openSel(CMenuScreen::EState screenType, CMenuScreen::EMultiMode
 
 void CGPreGame::loadGraphics()
 {
-	background = BitmapHandler::loadBitmap("DIBOXBCK");
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+	new CFilledTexture("DIBOXBCK", pos);
+
 	victory = CDefHandler::giveDef("SCNRVICT.DEF");
 	loss = CDefHandler::giveDef("SCNRLOSS.DEF");
 	bonuses = CDefHandler::giveDef("SCNRSTAR.DEF");
@@ -467,7 +471,6 @@ void CGPreGame::disposeGraphics()
 {
 	delete victory;
 	delete loss;
-	SDL_FreeSurface(background);
 	SDL_FreeSurface(rHero);
 	SDL_FreeSurface(nHero);
 	SDL_FreeSurface(rTown);
@@ -504,18 +507,6 @@ void CGPreGame::update()
 	CCS->curh->draw2();
 }
 
-void CGPreGame::showAll(SDL_Surface *to)
-{
-	//fill screen with background texture
-	for (int y=0; y<to->h; y+=background->h)
-	{
-		for (int x=0; x<to->w; x+=background->w)
-		{
-			blitAt(background, x, y, to);
-		}
-	}
-}
-
 void CGPreGame::openCampaignScreen(std::string name)
 {
 	BOOST_FOREACH(const JsonNode& node, (*pregameConfig)["campaignsset"].Vector())

+ 0 - 2
client/CPreGame.h

@@ -500,7 +500,6 @@ class CGPreGame : public CIntObject, public IUpdateable
 public:
 	CMenuScreen* menu;
 
-	SDL_Surface *background;
 	SDL_Surface *nHero, *rHero, *nTown, *rTown; // none/random hero/town imgs
 	CDefHandler *bonuses;
 	CDefHandler *victory, *loss;
@@ -509,7 +508,6 @@ public:
 	void update();
 	void openSel(CMenuScreen::EState type, CMenuScreen::EMultiMode multi = CMenuScreen::SINGLE_PLAYER);
 
-	void showAll(SDL_Surface *to);
 	void openCampaignScreen(std::string name);
 
 	static CGPreGame * create();

+ 10 - 41
client/CQuestLog.cpp

@@ -46,8 +46,8 @@ void CQuestLabel::showAll(SDL_Surface * to)
 		CBoundedLabel::showAll (to);
 }
 
-CQuestIcon::CQuestIcon (const std::string &bmpname, int x, int y) :
-	CPicture (bmpname, x, y)
+CQuestIcon::CQuestIcon (const std::string &defname, int index, int x, int y) :
+	CAnimImage(defname, index, 0, x, y)
 {
 	addUsedEvents(LCLICK);
 }
@@ -60,25 +60,8 @@ void CQuestIcon::clickLeft(tribool down, bool previousState)
 
 void CQuestIcon::showAll(SDL_Surface * to)
 {
-	if(bg)
-	{
-		if(srcRect)
-		{
-			SDL_Rect srcRectCpy = *srcRect;
-			SDL_Rect dstRect = srcRectCpy;
-			dstRect.x = pos.x;
-			dstRect.y = pos.y;
-
-			CSDL_Ext::blitSurface(bg, &srcRectCpy, to, &dstRect);
-		}
-		else //TODO: allow blitting with offset correction (center of picture on the center of pos)
-		{
-			SDL_Rect dstRect = pos;
-			dstRect.x -= pos.w + 2;
-			dstRect.y -= pos.h + 2;
-			blitAt(bg, dstRect, to);
-		}
-	}
+	CSDL_Ext::CClipRectGuard guard(to, parent->pos);
+	CAnimImage::showAll(to);
 }
 
 CQuestMinimap::CQuestMinimap (const Rect & position) :
@@ -101,20 +84,14 @@ void CQuestMinimap::addQuestMarks (const QuestInfo * q)
 	{
 		tile = q->tile;
 	}
-	CQuestIcon * pic = new CQuestIcon ("", 0, 0);
-	CDefHandler * def = CDefHandler::giveDef("VwSymbol.def");
-	CSDL_Ext::alphaTransform(def->ourImages[3].bitmap);
-	pic->bg = def->ourImages[3].bitmap;
-	pic->pos.w = 8;
-	pic->pos.h = 8;
-
-	int x, y;
+	int x,y;
 	minimap->tileToPixels (tile, x, y);
-	pic->moveTo (Point (minimap->pos.x, minimap->pos.y), true);
-	pic->pos.x += x - pic->pos.w / 2 - 1;
-	pic->pos.y += y - pic->pos.h / 2 - 1;
 
+	CQuestIcon * pic = new CQuestIcon ("VwSymbol.def", 3, x, y);
+
+	pic->moveBy (Point ( -pic->pos.w/2, -pic->pos.h/2));
 	pic->callback = boost::bind (&CQuestMinimap::iconClicked, this);
+
 	icons.push_back(pic);
 }
 
@@ -134,7 +111,7 @@ void CQuestMinimap::iconClicked()
 
 void CQuestMinimap::showAll(SDL_Surface * to)
 {
-	CMinimap::showAll(to);
+	CIntObject::showAll(to); // blitting IntObject directly to hide radar
 	BOOST_FOREACH (auto pic, icons)
 		pic->showAll(to);
 }
@@ -159,13 +136,6 @@ void CQuestLog::init()
 	if (quests.size() > QUEST_COUNT)
 		slider = new CSlider(203, 199, 230, boost::bind (&CQuestLog::sliderMoved, this, _1), QUEST_COUNT, quests.size(), false, 0);
 
-	auto map = LOCPLINT->cb->getVisibilityMap(); //TODO: another function to get all tiles?
-
-	for (int g = 0; g < map.size(); ++g)
-		for (int h = 0; h < map[g].size(); ++h)
-			for (int y = 0; y < map[g][h].size(); ++y)
-				minimap->showTile (int3 (g, h, y));
-
 	for (int i = 0; i < quests.size(); ++i)
 	{
 		MetaString text;
@@ -179,7 +149,6 @@ void CQuestLog::init()
 	}
 
 	recreateQuestList (0);
-	showAll (screen2);
 }
 
 void CQuestLog::showAll(SDL_Surface * to)

+ 3 - 3
client/CQuestLog.h

@@ -44,12 +44,12 @@ public:
 	void showAll(SDL_Surface * to);
 };
 
-class CQuestIcon : public CPicture
+class CQuestIcon : public CAnimImage
 {
 public:
 	boost::function<void()> callback; //TODO: merge with other similiar classes?
 
-	CQuestIcon (const std::string &bmpname, int x=0, int y=0);
+	CQuestIcon (const std::string &defname, int index, int x=0, int y=0);
 
 	void clickLeft(tribool down, bool previousState);
 	void showAll(SDL_Surface * to);
@@ -88,13 +88,13 @@ class CQuestLog : public CWindowObject
 	CSlider * slider; //scrolls quests
 	CAdventureMapButton *ok;
 
+	void init ();
 public:
 
 	CQuestLog (const std::vector<QuestInfo> & Quests);
 
 	~CQuestLog(){};
 
-	void init ();
 	void selectQuest (int which);
 	void updateMinimap (int which){};
 	void printDescription (int which){};

+ 4 - 6
client/GUIClasses.cpp

@@ -785,12 +785,7 @@ CComponent::CComponent(const Component &c):
 	if(c.id == Component::RESOURCE && c.when==-1)
 		perDay = true;
 
-	if(c.id == Component::EXPERIENCE)
-		init(experience,c.subtype,c.val, large);
-	else if(c.id == Component::SPELL)
-		init(spell,c.subtype,c.val, large);
-	else
-		init((Etype)c.id,c.subtype,c.val, large);
+	init((Etype)c.id,c.subtype,c.val, large);
 }
 
 void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
@@ -802,6 +797,9 @@ void CComponent::init(Etype Type, int Subtype, int Val, ESize imageSize)
 	val = Val;
 	size = imageSize;
 
+	assert(compType < typeInvalid);
+	assert(size < sizeInvalid);
+
 	setSurface(getFileName()[size], getIndex());
 
 	pos.w = image->pos.w;

+ 3 - 2
client/GUIClasses.h

@@ -176,7 +176,7 @@ class CComponent : public virtual CIntObject
 public:
 	enum Etype
 	{
-		primskill, secskill, resource, creature, artifact, experience, spell, morale, luck, building, hero, flag
+		primskill, secskill, resource, creature, artifact, experience, spell, morale, luck, building, hero, flag, typeInvalid
 	};
 
 	//NOTE: not all types have exact these sizes or have less than 4 of them. In such cases closest one will be used
@@ -185,7 +185,8 @@ public:
 		tiny,  // ~22-24px
 		small, // ~30px
 		medium,// ~42px
-		large  // ~82px
+		large,  // ~82px
+		sizeInvalid
 	};
 
 private:

+ 0 - 21
client/Graphics.cpp

@@ -145,34 +145,13 @@ Graphics::Graphics()
 	tasks += boost::bind(&Graphics::initializeBattleGraphics,this);
 	tasks += boost::bind(&Graphics::loadWallPositions,this);
 	tasks += boost::bind(&Graphics::loadErmuToPicture,this);
-	tasks += GET_SURFACE(hInfo,"HEROQVBK.bmp");
-	tasks += GET_SURFACE(tInfo,"TOWNQVBK.bmp");
-	tasks += GET_SURFACE(heroInGarrison,"TOWNQKGH.bmp");
 	tasks += GET_DEF_ESS(artDefs,"ARTIFACT.DEF");
-	tasks += GET_DEF_ESS(forts,"ITMCLS.DEF");
-	tasks += GET_DEF_ESS(luck22,"ILCK22.DEF");
-	tasks += GET_DEF_ESS(luck30,"ILCK30.DEF");
-	tasks += GET_DEF_ESS(luck42,"ILCK42.DEF");
-	tasks += GET_DEF_ESS(luck82,"ILCK82.DEF");
-	tasks += GET_DEF_ESS(morale22,"IMRL22.DEF");
-	tasks += GET_DEF_ESS(morale30,"IMRL30.DEF");
-	tasks += GET_DEF_ESS(morale42,"IMRL42.DEF");
-	tasks += GET_DEF_ESS(morale82,"IMRL82.DEF");
-	tasks += GET_DEF_ESS(halls,"ITMTLS.DEF");
-	tasks += GET_DEF_ESS(bigTownPic,"ITPT.DEF");
-	tasks += GET_DEF_ESS(pskillsb,"PSKILL.DEF");
-	tasks += GET_DEF_ESS(pskillsm,"PSKIL42.DEF");
-	tasks += GET_DEF_ESS(pskillst,"PSKIL32.DEF");
-	tasks += GET_DEF_ESS(resources,"RESOUR82.DEF");
-	tasks += GET_DEF_ESS(un32,"UN32.DEF");
 	tasks += GET_DEF_ESS(un44,"UN44.DEF");
 	tasks += GET_DEF_ESS(smallIcons,"ITPA.DEF");
 	tasks += GET_DEF_ESS(resources32,"RESOURCE.DEF");
 	tasks += GET_DEF(smi,"CPRSMALL.DEF");
 	tasks += GET_DEF(smi2,"TWCRPORT.DEF");
 	tasks += GET_DEF_ESS(flags,"CREST58.DEF");
-	tasks += GET_DEF_ESS(abils32,"SECSK32.DEF");
-	tasks += GET_DEF_ESS(abils44,"SECSKILL.DEF");
 	tasks += GET_DEF_ESS(abils82,"SECSK82.DEF");
 	tasks += GET_DEF_ESS(spellscr,"SPELLSCR.DEF");
 	tasks += GET_DEF_ESS(heroMoveArrows,"ADAG.DEF");

+ 1 - 10
client/Graphics.h

@@ -44,19 +44,10 @@ public:
 	SDL_Color * playerColorPalette; //palette to make interface colors good - array of size [256]
 	SDL_Color * neutralColorPalette; 
 
-	SDL_Surface * hInfo, *tInfo; //hero and town infobox bgs
-	SDL_Surface *heroInGarrison; //icon for town infobox
-	CDefEssential *luck22, *luck30, *luck42, *luck82,
-		*morale22, *morale30, *morale42, *morale82,
-		*halls, *forts, *bigTownPic;
 	CDefEssential * artDefs; //artifacts
 	std::vector<SDL_Surface *> portraitSmall; //48x32 px portraits of heroes
 	std::vector<SDL_Surface *> portraitLarge; //58x64 px portraits of heroes
 	std::vector<CDefEssential *> flags1, flags2, flags3, flags4; //flags blitted on heroes when ,
-	CDefEssential * pskillsb, *resources; //82x93
-	CDefEssential * pskillsm; //42x42  primary skills
-	CDefEssential * pskillst; //32x32
-	CDefEssential * un32; //many small things
 	CDefEssential * un44; //many things
 	CDefEssential * smallIcons, *resources32; //resources 32x32
 	CDefEssential * flags;
@@ -87,7 +78,7 @@ public:
 	CDefEssential * spellEffectsPics; //bitmaps representing spells affecting a stack in battle
 	std::vector< Point > wallPositions[GameConstants::F_NUMBER]; //positions of different pieces of wall <x, y>
 	//abilities
-	CDefEssential * abils32, * abils44, * abils82;
+	CDefEssential * abils82;
 	//spells
 	CDefEssential *spellscr; //spell on the scroll 83x61
 	//functions

+ 19 - 0
client/UIFramework/CIntObjectClasses.cpp

@@ -176,6 +176,25 @@ void CPicture::colorize(int player)
 	graphics->blueToPlayersAdv(bg, player);
 }
 
+CFilledTexture::CFilledTexture(std::string imageName, Rect position):
+    CIntObject(0, position.topLeft()),
+    texture(BitmapHandler::loadBitmap(imageName))
+{
+	pos.w = position.w;
+	pos.h = position.h;
+}
+
+CFilledTexture::~CFilledTexture()
+{
+	SDL_FreeSurface(texture);
+}
+
+void CFilledTexture::showAll(SDL_Surface *to)
+{
+	CSDL_Ext::CClipRectGuard guard(to, pos);
+	CSDL_Ext::fillTexture(to, texture);
+}
+
 CButtonBase::CButtonBase()
 {
 	swappedImages = keepFrame = false;

+ 11 - 0
client/UIFramework/CIntObjectClasses.h

@@ -67,6 +67,17 @@ public:
 	void colorize(int player);
 };
 
+/// area filled with specific texture
+class CFilledTexture : CIntObject
+{
+	SDL_Surface * texture;
+
+public:
+	CFilledTexture(std::string imageName, Rect position);
+	~CFilledTexture();
+	void showAll(SDL_Surface *to);
+};
+
 namespace config{struct ButtonInfo;}
 
 /// Base class for buttons.

+ 18 - 0
client/UIFramework/SDL_Extensions.cpp

@@ -1273,6 +1273,24 @@ void CSDL_Ext::fillRect( SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color )
 	SDL_FillRect(dst, &newRect, color);
 }
 
+void CSDL_Ext::fillTexture(SDL_Surface *dst, SDL_Surface * src)
+{
+	SDL_Rect srcRect;
+	SDL_Rect dstRect;
+
+	SDL_GetClipRect(src, &srcRect);
+	SDL_GetClipRect(dst, &dstRect);
+
+	for (int y=dstRect.y; y<dstRect.h; y+=srcRect.h)
+	{
+		for (int x=dstRect.x; x<dstRect.w; x+=srcRect.w)
+		{
+			Rect currentDest(x, y, srcRect.w, srcRect.h);
+			SDL_BlitSurface(src, &srcRect, dst, &currentDest);
+		}
+	}
+}
+
 std::string CSDL_Ext::trimToFit(std::string text, int widthLimit, EFonts font)
 {
 	int widthSoFar = 0;

+ 21 - 1
client/UIFramework/SDL_Extensions.h

@@ -77,7 +77,6 @@ std::string makeNumberShort(IntType number) //the output is a string containing
 typedef void (*TColorPutter)(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, const Uint8 & B);
 typedef void (*TColorPutterAlpha)(Uint8 *&ptr, const Uint8 & R, const Uint8 & G, const Uint8 & B, const Uint8 & A);
 
-
 inline SDL_Rect genRect(const int & hh, const int & ww, const int & xx, const int & yy)
 {
 	SDL_Rect ret;
@@ -103,8 +102,29 @@ typedef void (*BlitterWithRotationVal)(SDL_Surface *src,SDL_Rect srcRect, SDL_Su
 
 namespace CSDL_Ext
 {
+	/// helper that will safely set and un-set ClipRect for SDL_Surface
+	class CClipRectGuard
+	{
+		SDL_Surface * surf;
+		SDL_Rect oldRect;
+	public:
+		CClipRectGuard(SDL_Surface * surface, const SDL_Rect & rect):
+		    surf(surface)
+		{
+			SDL_GetClipRect(surf, &oldRect);
+			SDL_SetClipRect(surf, &rect);
+		}
+
+		~CClipRectGuard()
+		{
+			SDL_SetClipRect(surf, &oldRect);
+		}
+	};
+
 	void blitSurface(SDL_Surface * src, SDL_Rect * srcRect, SDL_Surface * dst, SDL_Rect * dstRect);
 	void fillRect(SDL_Surface *dst, SDL_Rect *dstrect, Uint32 color);
+	//fill dest image with source texture.
+	void fillTexture(SDL_Surface *dst, SDL_Surface * sourceTexture);
 
 	void SDL_PutPixelWithoutRefresh(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255);
 	void SDL_PutPixelWithoutRefreshIfInSurf(SDL_Surface *ekran, const int & x, const int & y, const Uint8 & R, const Uint8 & G, const Uint8 & B, Uint8 A = 255);

+ 3 - 2
server/CGameHandler.cpp

@@ -912,7 +912,7 @@ void CGameHandler::handleConnection(std::set<int> players, CConnection &c)
 		tlog1 << e.what() << std::endl;
 		end2 = true;
 	}
-	HANDLE_EXCEPTION(end2 = true);
+	//HANDLE_EXCEPTION(end2 = true);
 
 	tlog1 << "Ended handling connection\n";
 }
@@ -4760,7 +4760,8 @@ void CGameHandler::showGarrisonDialog( int upobj, int hid, bool removableUnits,
 		callbacks[gd.queryID] = [=](ui32 answer)
 		{ 
 			// Garrison callback calls the "original callback" and closes the exchange between objs.
-			cb();
+			if (cb)
+				cb();
 			boost::unique_lock<boost::recursive_mutex> lockGsm(this->gsm);
 			allowedExchanges.erase(gd.queryID);
 		};