Forráskód Böngészése

- several changes to get reusable code
- possibly fixed #725
- bug in random seed initializing?

Ivan Savenko 14 éve
szülő
commit
e494171de3

+ 1 - 1
client/CAnimation.cpp

@@ -903,7 +903,7 @@ void TextParser::parseFile(std::map<size_t, std::vector <std::string> > &result)
 			boost::algorithm::trim(res);
 			if (res.empty())
 				break;
-			result[currentBlock].push_back(baseDir+'/'+res);
+			result[currentBlock].push_back(baseDir+res);
 		}
 	}
 }

+ 33 - 17
client/CCastleInterface.cpp

@@ -303,7 +303,7 @@ void CHeroGSlot::hover (bool on)
 		GH.statusbar->clear();
 		return;
 	}
-	CHeroGSlot *other = upg  ?  owner->heroSlotUp :  owner->heroSlotDown;
+	CHeroGSlot *other = upg  ?  owner->garrisonedHero :  owner->visitingHero;
 	std::string temp;
 	if(hero)
 	{
@@ -350,7 +350,7 @@ void CHeroGSlot::hover (bool on)
 
 void CHeroGSlot::clickLeft(tribool down, bool previousState)
 {
-	CHeroGSlot *other = upg  ?  owner->heroSlotUp :  owner->heroSlotDown;
+	CHeroGSlot *other = upg  ?  owner->garrisonedHero :  owner->visitingHero;
 	if(!down)
 	{
 		owner->garr->splitting = false;
@@ -390,7 +390,7 @@ void CHeroGSlot::clickLeft(tribool down, bool previousState)
 		{
 			setHighlight(true);
 			owner->garr->highlighted = NULL;
-			show(screen2);
+			showAll(screen2);
 		}
 		hover(false);hover(true); //refresh statusbar
 	}
@@ -406,13 +406,13 @@ void CHeroGSlot::showAll(SDL_Surface * to)
 {
 	if(hero) //there is hero
 		blitAt(graphics->portraitLarge[hero->portrait],pos,to);
-	else if(!upg) //up garrison
+	else if(!upg && owner->showEmpty) //up garrison
 		blitAt(graphics->flags->ourImages[LOCPLINT->castleInt->town->getOwner()].bitmap,pos,to);
 	if(highlight)
 		blitAt(graphics->bigImgs[-1],pos,to);
 }
 
-CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, CCastleInterface * Owner)
+CHeroGSlot::CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner)
 {
 	used = LCLICK | HOVER;
 	owner = Owner;
@@ -432,7 +432,7 @@ CHeroGSlot::~CHeroGSlot()
 void CHeroGSlot::setHighlight( bool on )
 {
 	highlight = on;
-	if(owner->heroSlotUp->hero && owner->heroSlotDown->hero) //two heroes in town
+	if(owner->garrisonedHero->hero && owner->visitingHero->hero) //two heroes in town
 	{
 		for(size_t i = 0; i<owner->garr->splitButtons.size(); i++) //splitting enabled when slot higlighted
 			owner->garr->splitButtons[i]->block(!on);
@@ -914,9 +914,8 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos):
 	pos.h = builds->pos.h + panel->pos.h;
 	center();
 
-	heroSlotUp = new CHeroGSlot(241, 387, 0, Town->garrisonHero, this);
-	heroSlotDown = new CHeroGSlot(241, 483, 1, Town->visitingHero, this);
 	garr = new CGarrisonInt(305, 387, 4, Point(0,96), panel->bg, Point(62,374), town->getUpperArmy(), town->visitingHero);
+	heroes = new HeroSlots(town, Point(241, 387), Point(241, 483), garr, true);
 	title = new CLabel(85, 387, FONT_MEDIUM, TOPLEFT, zwykly, town->name);
 	income = new CLabel(195, 443, FONT_SMALL, CENTER);
 	icon = new CAnimImage("ITPT", 0, 0, 15, 387);
@@ -926,7 +925,7 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, int listPos):
 	exit->setOffset(4);
 
 	split = new AdventureMapButton(CGI->generaltexth->tcommands[3], "", boost::bind(&CGarrisonInt::splitClick,garr), 744, 382, "TSBTNS.DEF");
-	split->callback += boost::bind(&CCastleInterface::splitClicked, this);
+	split->callback += boost::bind(&HeroSlots::splitClicked, heroes);
 	removeChild(split);
 	garr->addSplitBtn(split);
 
@@ -1065,19 +1064,20 @@ CCreaInfo::CCreaInfo(int posX, int posY, const CGTownInstance *Town, int Level):
 
 void CCreaInfo::hover(bool on)
 {
+	std::string message = CGI->generaltexth->allTexts[588];
+	boost::algorithm::replace_first(message,"%s",creature->namePl);
+
 	if(on)
 	{
-		std::string descr=CGI->generaltexth->allTexts[588];
-		boost::algorithm::replace_first(descr,"%s",creature->namePl);
-		GH.statusbar->print(descr);
+		GH.statusbar->print(message);
 	}
-	else
+	else if (message == GH.statusbar->getCurrent())
 		GH.statusbar->clear();
 }
 
 void CCreaInfo::clickLeft(tribool down, bool previousState)
 {//FIXME: castleInt should be present - may be NULL if no castle window opened
-	if(previousState && (!down))
+	if(previousState && (!down) && LOCPLINT->castleInt)
 		LOCPLINT->castleInt->builds->enterDwelling(level);
 }
 
@@ -1207,7 +1207,7 @@ void CTownInfo::hover(bool on)
 
 void CTownInfo::clickRight(tribool down, bool previousState)
 {//FIXME: castleInt may be NULL
-	if(down && building)
+	if(down && building && LOCPLINT->castleInt)
 	{
 		CInfoPopup *mess = new CInfoPopup();
 		mess->free = true;
@@ -1256,9 +1256,25 @@ void CCastleInterface::keyPressed( const SDL_KeyboardEvent & key )
 	}
 }
 
-void CCastleInterface::splitClicked()
+HeroSlots::HeroSlots(const CGTownInstance * Town, Point garrPos, Point visitPos, CGarrisonInt *Garrison, bool ShowEmpty):
+	showEmpty(ShowEmpty),
+	town(Town),
+	garr(Garrison)
+{
+	OBJ_CONSTRUCTION_CAPTURING_ALL;
+	garrisonedHero = new CHeroGSlot(garrPos.x, garrPos.y, 0, town->garrisonHero, this);
+	visitingHero = new CHeroGSlot(visitPos.x, visitPos.y, 1, town->visitingHero, this);
+}
+
+void HeroSlots::update()
+{
+	garrisonedHero->hero = town->garrisonHero;
+	visitingHero->hero = town->visitingHero;
+}
+
+void HeroSlots::splitClicked()
 {
-	if(!!town->visitingHero && town->garrisonHero && (heroSlotDown->highlight || heroSlotUp->highlight))
+	if(!!town->visitingHero && town->garrisonHero && (visitingHero->highlight || garrisonedHero->highlight))
 	{
 		LOCPLINT->heroExchangeStarted(town->visitingHero->id, town->garrisonHero->id);
 	}

+ 22 - 5
client/CCastleInterface.h

@@ -70,11 +70,12 @@ public:
 	void clickRight(tribool down, bool previousState);
 };
 
-/// Hero army slot
+class HeroSlots;
+/// Hero icon slot
 class CHeroGSlot : public CIntObject
 {
 public:
-	CCastleInterface *owner;
+	HeroSlots *owner;
 	const CGHeroInstance *hero;
 	int upg; //0 - up garrison, 1 - down garrison
 	bool highlight; //indicates id the slot is highlighted
@@ -85,10 +86,27 @@ public:
 	void clickLeft(tribool down, bool previousState);
 	void deactivate();
 	void showAll(SDL_Surface * to);
-	CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h,CCastleInterface * Owner); //c-tor
+	CHeroGSlot(int x, int y, int updown, const CGHeroInstance *h, HeroSlots * Owner); //c-tor
 	~CHeroGSlot(); //d-tor
 };
 
+/// Two hero slots that can interact with each other
+class HeroSlots : public CIntObject
+{
+public:
+	bool showEmpty;
+	const CGTownInstance * town;
+
+	CGarrisonInt *garr;
+	CHeroGSlot * garrisonedHero;
+	CHeroGSlot * visitingHero;
+
+	HeroSlots(const CGTownInstance * town, Point garrPos, Point visitPos, CGarrisonInt *Garrison, bool ShowEmpty);
+
+	void splitClicked(); //for hero meeting only (splitting stacks is handled by garrison int)
+	void update();
+};
+
 /// Class for town screen management (town background and structures)
 class CCastleBuildings : public CIntObject
 {
@@ -196,7 +214,7 @@ public:
 
 	//TODO: move to private
 	const CGTownInstance * town;
-	CHeroGSlot *heroSlotUp, *heroSlotDown;
+	HeroSlots *heroes;
 	CCastleBuildings *builds;
 
 	CCastleInterface(const CGTownInstance * Town, int listPos = 1); //c-tor
@@ -205,7 +223,6 @@ public:
 	void castleTeleport(int where);
 	void townChange();
 	void keyPressed(const SDL_KeyboardEvent & key);
-	void splitClicked(); //for hero meeting (splitting stacks is handled by garrison int)
 	void showAll(SDL_Surface *to);
 	void close();
 	void addBuilding(int bid);

+ 5 - 11
client/CPlayerInterface.cpp

@@ -474,12 +474,10 @@ void CPlayerInterface::heroInGarrisonChange(const CGTownInstance *town)
 	if(CCastleInterface *c = castleInt)
 	{
 		c->garr->highlighted = NULL;
-		c->heroSlotUp->hero = town->garrisonHero;
-		c->heroSlotDown->hero = town->visitingHero;
-
 		c->garr->setArmy(town->getUpperArmy(), 0);
 		c->garr->setArmy(town->visitingHero, 1);
 		c->garr->recreateSlots();
+		c->heroes->update();
 	}
 	GH.totalRedraw();
 }
@@ -2174,8 +2172,7 @@ void CPlayerInterface::artifactRemoved(const ArtifactLocation &al)
 	{
 		if(isa->type & IShowActivable::WITH_ARTIFACTS)
 		{
-			BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
-				aoh->artifactRemoved(al);
+			(dynamic_cast<CWindowWithArtifacts*>(isa))->artifactRemoved(al);
 		}
 	}
 }
@@ -2187,8 +2184,7 @@ void CPlayerInterface::artifactMoved(const ArtifactLocation &src, const Artifact
 	{
 		if(isa->type & IShowActivable::WITH_ARTIFACTS)
 		{
-			BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
-				aoh->artifactMoved(src, dst);
+			(dynamic_cast<CWindowWithArtifacts*>(isa))->artifactMoved(src, dst);
 		}
 	}
 }
@@ -2200,8 +2196,7 @@ void CPlayerInterface::artifactAssembled(const ArtifactLocation &al)
 	{
 		if(isa->type & IShowActivable::WITH_ARTIFACTS)
 		{
-			BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
-				aoh->artifactAssembled(al);
+			(dynamic_cast<CWindowWithArtifacts*>(isa))->artifactAssembled(al);
 		}
 	}
 }
@@ -2213,8 +2208,7 @@ void CPlayerInterface::artifactDisassembled(const ArtifactLocation &al)
 	{
 		if(isa->type & IShowActivable::WITH_ARTIFACTS)
 		{
-			BOOST_FOREACH(CArtifactsOfHero *aoh, (dynamic_cast<CWindowWithArtifacts*>(isa))->artSets)
-				aoh->artifactDisassembled(al);
+			(dynamic_cast<CWindowWithArtifacts*>(isa))->artifactAssembled(al);
 		}
 	}
 }

+ 10 - 1
client/CVideoHandler.cpp

@@ -968,6 +968,15 @@ CVideoPlayer::~CVideoPlayer()
 	close();
 }
 
+//In old versions of libavformat this function is defined as static inline and not present in compiled library
+//which results in linkage error if compiler had not inlined it for some reason
+#if  (LIBAVFORMAT_VERSION_MAJOR < 52) || ( LIBAVFORMAT_VERSION_MAJOR == 52 && LIBAVFORMAT_VERSION_MINOR < 32 )
+void av_free_packet(AVPacket *pkt)
+{
+	if (pkt && pkt->destruct) {
+		pkt->destruct(pkt);
+	}
+}
 #endif
 
- 	  	 
+#endif

+ 39 - 10
client/GUIClasses.cpp

@@ -5159,7 +5159,7 @@ void CArtifactsOfHero::scrollBackpack(int dir)
 			assert(art);
 			if(!vstd::contains(toOmit, art))
 			{ 
-				if(s - omitedSoFar < 5)
+				if(s - omitedSoFar < backpack.size())
 					setSlotData(backpack[s-omitedSoFar], slotID);
 			}
 			else
@@ -5170,13 +5170,13 @@ void CArtifactsOfHero::scrollBackpack(int dir)
 			}
 		}
 	}
-	for( ; s - omitedSoFar < 5; s++)
+	for( ; s - omitedSoFar < backpack.size(); s++)
 		eraseSlotData(backpack[s-omitedSoFar], 19 + s);
 
 	//in artifact merchant selling artifacts we may have highlight on one of backpack artifacts -> market needs update, cause artifact under highlight changed
 	if(highlightModeCallback)
 	{
-		for(int i = 0; i < 5; i++)
+		for(int i = 0; i < backpack.size(); i++)
 		{
 			if(backpack[i]->marked)
 			{
@@ -5295,6 +5295,9 @@ CArtifactsOfHero::CArtifactsOfHero(std::vector<CArtPlace *> ArtWorn, std::vector
 		backpack[s]->ourOwner = this;
 		eraseSlotData(backpack[s], 19 + s);
 	}
+
+	leftArtRoll->callback  += boost::bind(&CArtifactsOfHero::scrollBackpack,this,-1);
+	rightArtRoll->callback += boost::bind(&CArtifactsOfHero::scrollBackpack,this,+1);
 }
 
 CArtifactsOfHero::CArtifactsOfHero(const Point& position, bool createCommonPart /*= false*/)
@@ -5818,8 +5821,9 @@ CExchangeWindow::CExchangeWindow(si32 hero1, si32 hero2) : bg(NULL)
 	questlogButton[0] = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CExchangeWindow::questlog,this, 0), pos.x+10, pos.y+44, "hsbtns4.def");
 	questlogButton[1] = new AdventureMapButton(CGI->generaltexth->heroscrn[0], std::string(), boost::bind(&CExchangeWindow::questlog,this, 1), pos.x+740, pos.y+44, "hsbtns4.def");
 
-	//statusbar
-	ourBar = new CStatusBar(pos.x + 3, pos.y + 577, "TSTATBAR.bmp", 726);
+	//statusbar 
+	//FIXME - this image is a bit bigger than required - part of background should be used instead
+	ourBar = new CGStatusBar(pos.x + 3, pos.y + 577, "KSTATBAR");
 
 	//garrison interface
 	garr = new CGarrisonInt(pos.x + 69, pos.y + 131, 4, Point(418,0), bg, Point(69,131), heroInst[0],heroInst[1], true, true);
@@ -6739,14 +6743,19 @@ void MoraleLuckBox::set(const IBonusBearer *node)
 
 void MoraleLuckBox::showAll(SDL_Surface * to)
 {
-	CDefEssential *def = morale ? graphics->morale42 : graphics->luck42;
+	CDefEssential *def;
+	if (small)
+		def = morale ? graphics->morale30 : graphics->luck30;
+	else
+		def = morale ? graphics->morale42 : graphics->luck42;
 	SDL_Surface *img = def->ourImages[bonusValue + 3].bitmap;
 	
 	blitAt(img, Rect(img).centerIn(pos), to); //put img in the center of our pos
 }
 
-MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r)
-	:morale(Morale)
+MoraleLuckBox::MoraleLuckBox(bool Morale, const Rect &r, bool Small)
+	:morale(Morale),
+	 small(Small)
 {
 	bonusValue = 0;
 	pos = r + pos;
@@ -7093,13 +7102,33 @@ void CFocusable::moveFocus()
 	}
 }
 
-CWindowWithArtifacts::CWindowWithArtifacts()
+CArtifactHolder::CArtifactHolder()
 {
 	type |= WITH_ARTIFACTS;
 }
 
-CWindowWithArtifacts::~CWindowWithArtifacts()
+void CWindowWithArtifacts::artifactRemoved(const ArtifactLocation &artLoc)
+{
+	BOOST_FOREACH(CArtifactsOfHero *aoh, artSets)
+		aoh->artifactRemoved(artLoc);
+}
+
+void CWindowWithArtifacts::artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)
+{
+	BOOST_FOREACH(CArtifactsOfHero *aoh, artSets)
+		aoh->artifactMoved(artLoc, destLoc);
+}
+
+void CWindowWithArtifacts::artifactDisassembled(const ArtifactLocation &artLoc)
+{
+	BOOST_FOREACH(CArtifactsOfHero *aoh, artSets)
+		aoh->artifactDisassembled(artLoc);
+}
+
+void CWindowWithArtifacts::artifactAssembled(const ArtifactLocation &artLoc)
 {
+	BOOST_FOREACH(CArtifactsOfHero *aoh, artSets)
+		aoh->artifactAssembled(artLoc);
 }
 
 void CArtifactsOfHero::SCommonPart::Artpos::clear()

+ 19 - 5
client/GUIClasses.h

@@ -609,13 +609,26 @@ public:
 	void showAll(SDL_Surface * to);
 };
 
-class CWindowWithArtifacts : public virtual CIntObject
+class CArtifactHolder : public virtual CIntObject
+{
+public:
+	CArtifactHolder();
+
+	virtual void artifactRemoved(const ArtifactLocation &artLoc)=0;
+	virtual void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc)=0;
+	virtual void artifactDisassembled(const ArtifactLocation &artLoc)=0;
+	virtual void artifactAssembled(const ArtifactLocation &artLoc)=0;
+};
+
+class CWindowWithArtifacts : public CArtifactHolder
 {
 public:
 	std::vector<CArtifactsOfHero *> artSets;
 
-	CWindowWithArtifacts();
-	~CWindowWithArtifacts();
+	void artifactRemoved(const ArtifactLocation &artLoc);
+	void artifactMoved(const ArtifactLocation &artLoc, const ArtifactLocation &destLoc);
+	void artifactDisassembled(const ArtifactLocation &artLoc);
+	void artifactAssembled(const ArtifactLocation &artLoc);
 };
 
 class CTradeWindow : public CWindowWithArtifacts //base for markets and altar of sacrifice
@@ -891,11 +904,12 @@ class MoraleLuckBox : public LRClickableAreaWTextComp
 {
 public:
 	bool morale; //true if morale, false if luck
+	bool small;
 	
 	void set(const IBonusBearer *node);
 	void showAll(SDL_Surface * to);
 
-	MoraleLuckBox(bool Morale, const Rect &r);
+	MoraleLuckBox(bool Morale, const Rect &r, bool Small=false);
 	~MoraleLuckBox();
 };
 
@@ -1067,7 +1081,7 @@ public:
 
 class CExchangeWindow : public CWindowWithGarrison, public CWindowWithArtifacts
 {
-	CStatusBar * ourBar; //internal statusbar
+	CGStatusBar * ourBar; //internal statusbar
 
 	SDL_Surface *bg; //background
 	AdventureMapButton * quit, * questlogButton[2];

+ 1 - 1
server/CGameHandler.cpp

@@ -4270,7 +4270,7 @@ void CGameHandler::handleAfterAttackCasting( const BattleAttack & bat )
 		{
 			boost::poisson_distribution<int, double> p((int)mean);
 			boost::mt19937 rng;
-			boost::variate_generator<boost::mt19937&, boost::poisson_distribution<int, double>> dice (rng, p);
+			boost::variate_generator<boost::mt19937&, boost::poisson_distribution<int, double> > dice (rng, p);
 			staredCreatures += dice();
 		}
 		if (((int)(mean * 100)) < rand() % 100) //fractional chance for one last kill

+ 1 - 1
server/CVCMIServer.cpp

@@ -335,7 +335,7 @@ CGameHandler * CVCMIServer::initGhFromHostingConnection(CConnection &c)
 		c << ui8(0); //OK!
 	}
 
-	gh->init(&si,std::clock());
+	gh->init(&si,std::time(NULL));
 	c.addStdVecItems(gh->gs);
 	gh->conns.insert(&c);