Browse Source

* Turrets, keep and turret covers can be now be placed by altering wall_pos.txt
* Fixed recruitment slider bug
* Fixed #271
* Improved color management

beegee1 14 years ago
parent
commit
36d29424f0

+ 19 - 12
client/AdventureMapButton.cpp

@@ -26,7 +26,7 @@
 
 CButtonBase::CButtonBase()
 {
-	swappedImages = false;
+	swappedImages = keepFrame = false;
 	bitmapOffset = 0;
 	state=NORMAL;
 	image = NULL;
@@ -53,7 +53,10 @@ void CButtonBase::update()
 		     if (newPos == 0) newPos = 1;
 		else if (newPos == 1) newPos = 0;
 	}
-	image->setFrame(newPos);
+
+	if (!keepFrame)
+		image->setFrame(newPos);
+	
 	if (active)
 	{
 		showAll(screen);
@@ -107,8 +110,8 @@ void CButtonBase::block(bool on)
 
 AdventureMapButton::AdventureMapButton ()
 {
-	hoverable = actOnDown = borderEnabled = false;
-	borderColor.x = -1;
+	hoverable = actOnDown = borderEnabled = soundDisabled = false;
+	borderColor.unused = 1; // represents a transparent color, used for HighlightableButton
 	used = LCLICK | RCLICK | HOVER | KEYBOARD;
 }
 
@@ -139,7 +142,8 @@ void AdventureMapButton::clickLeft(tribool down, bool previousState)
 
 	if (down) 
 	{
-		CCS->soundh->playSound(soundBase::button);
+		if (!soundDisabled)
+			CCS->soundh->playSound(soundBase::button);
 		setState(PRESSED);
 	} 
 	else if(hoverable && hovered)
@@ -209,8 +213,8 @@ void AdventureMapButton::init(const CFunctionList<void()> &Callback, const std::
 	currentImage = -1;
 	used = LCLICK | RCLICK | HOVER | KEYBOARD;
 	callback = Callback;
-	actOnDown = hoverable = borderEnabled = false;
-	borderColor.x = -1;
+	hoverable = actOnDown = borderEnabled = soundDisabled = false;
+	borderColor.unused = 1; // represents a transparent color, used for HighlightableButton
 	assignedKeys.insert(key);
 	hoverTexts = Name;
 	helpBox=HelpBox;
@@ -267,8 +271,8 @@ void AdventureMapButton::showAll(SDL_Surface *to)
 {
 	CIntObject::showAll(to);
 
-	if (borderEnabled && borderColor.x >= 0)
-		CSDL_Ext::drawBorder(to, pos.x - 1, pos.y - 1, pos.w + 2, pos.h + 2, borderColor);
+	if (borderEnabled && borderColor.unused == 0)
+		CSDL_Ext::drawBorder(to, pos.x - 1, pos.y - 1, pos.w + 2, pos.h + 2, int3(borderColor.r, borderColor.g, borderColor.b));
 }
 
 void CHighlightableButton::select(bool on)
@@ -563,9 +567,9 @@ CSlider::CSlider(int x, int y, int totalw, boost::function<void(int)> Moved, int
 	strongInterest = true;
 
 
-	left = new AdventureMapButton;
-	right = new AdventureMapButton;
-	slider = new AdventureMapButton;
+	left = new AdventureMapButton();
+	right = new AdventureMapButton();
+	slider = new AdventureMapButton();
 
 	pos.x += x;
 	pos.y += y;
@@ -620,6 +624,9 @@ CSlider::CSlider(int x, int y, int totalw, boost::function<void(int)> Moved, int
 		slider->setImage(new CAnimation("SCNRBSL.DEF"));
 	}
 	slider->actOnDown = true;
+	slider->soundDisabled = true;
+	left->soundDisabled = true;
+	right->soundDisabled = true;
 
 	value = -1;
 	moveTo(Value);

+ 5 - 3
client/AdventureMapButton.h

@@ -39,7 +39,8 @@ private:
 	ButtonState state;//current state of button from enum
 
 public:
-	bool swappedImages;//fix for some buttons: normal and pressed image are swapped
+	bool swappedImages,//fix for some buttons: normal and pressed image are swapped
+		keepFrame; // don't change visual representation
 
 	void addTextOverlay(const std::string &Text, EFonts font, SDL_Color color = zwykly);
 	void update();//to refresh button after image or text change
@@ -72,8 +73,9 @@ public:
 	CFunctionList<void()> callback;
 	bool actOnDown,//runs when mouse is pressed down over it, not when up
 	     hoverable,//if true, button will be highlighted when hovered
-		 borderEnabled;
-	int3 borderColor;
+		 borderEnabled,
+		 soundDisabled;
+	SDL_Color borderColor;
 
 	void clickRight(tribool down, bool previousState);
 	virtual void clickLeft(tribool down, bool previousState);

+ 37 - 42
client/CBattleInterface.cpp

@@ -1155,8 +1155,8 @@ CBattleInterface::CBattleInterface(const CCreatureSet * army1, const CCreatureSe
 			SDL_Surface * moat = BitmapHandler::loadBitmap( siegeH->getSiegeName(13) ),
 				* mlip = BitmapHandler::loadBitmap( siegeH->getSiegeName(14) );
 
-			Point moatPos = graphics->wallPositions[siegeH->town->town->typeID][10],
-				mlipPos = graphics->wallPositions[siegeH->town->town->typeID][11];
+			Point moatPos = graphics->wallPositions[siegeH->town->town->typeID][12],
+				mlipPos = graphics->wallPositions[siegeH->town->town->typeID][13];
 
 			if(moat) //eg. tower has no moat
 				blitAt(moat, moatPos.x,moatPos.y, background);
@@ -1588,7 +1588,7 @@ void CBattleInterface::show(SDL_Surface * to)
 		THex position = CGI->heroh->obstacles.find(obstacles[b].ID)->second.getMaxBlocked(obstacles[b].pos);
 		hexToObstacle.insert(std::make_pair(position, b));
 	}
-
+	
 	////showing units //a lot of work...
 	std::vector<const CStack *> stackAliveByHex[BFIELD_SIZE];
 	//double loop because dead stacks should be printed first
@@ -2287,6 +2287,27 @@ void CBattleInterface::newStack(const CStack * stack)
 	{
 		const CCreature & turretCreature = *CGI->creh->creatures[ CGI->creh->factionToTurretCreature[siegeH->town->town->typeID] ];
 		creAnims[stack->ID] = new CCreatureAnimation(turretCreature.animDefName);	
+
+		// Remarks: Turret positions are read out of the /config/wall_pos.txt
+		int posID = 0;
+		switch (stack->position)
+		{
+		case -2: // keep creature
+			posID = 18;
+			break;
+		case -3: // bottom creature
+			posID = 19;
+			break;
+		case -4: // upper creature
+			posID = 20;
+			break;
+		}
+
+		if (posID != 0)
+		{
+			coords.x = graphics->wallPositions[siegeH->town->town->typeID][posID - 1].x + this->pos.x;
+			coords.y = graphics->wallPositions[siegeH->town->town->typeID][posID - 1].y + this->pos.y;
+		}
 	}
 	else
 	{
@@ -3748,19 +3769,16 @@ Point CBattleHex::getXYUnitAnim(const int & hexNum, const bool & attacker, const
 	Point ret(-500, -500); //returned value
 	if(stack->position < 0) //creatures in turrets
 	{
-		const CCreature & turretCreature = *CGI->creh->creatures[ CGI->creh->factionToTurretCreature[cbi->siegeH->town->town->typeID] ];
-		int xShift = turretCreature.isDoubleWide() ? 44 : 0;
-
 		switch(stack->position)
 		{
 		case -2: //keep
-			ret = Point(505 + xShift, -66);
+			ret = graphics->wallPositions[cbi->siegeH->town->town->typeID][12];
 			break;
 		case -3: //lower turret
-			ret = Point(368 + xShift, 304);
+			ret = graphics->wallPositions[cbi->siegeH->town->town->typeID][13];
 			break;
 		case -4: //upper turret
-			ret = Point(339 + xShift, -192);
+			ret = graphics->wallPositions[cbi->siegeH->town->town->typeID][14];
 			break;	
 		}
 	}
@@ -3972,7 +3990,7 @@ CBattleResultWindow::CBattleResultWindow(const BattleResult &br, const SDL_Rect
 	SDL_FreeSurface(background);
 	background = pom;
 	exit = new AdventureMapButton (std::string(), std::string(), boost::bind(&CBattleResultWindow::bExitf,this), 384 + pos.x, 505 + pos.y, "iok6432.def", SDLK_RETURN);
-	exit->borderColor = int3(173, 142, 66);
+	exit->borderColor = Colors::MetallicGold;
 	exit->borderEnabled = true;
 
 	if(br.winner==0) //attacker won
@@ -4357,42 +4375,19 @@ std::string CBattleInterface::SiegeHelper::getSiegeName(ui16 what, ui16 additInf
 	}
 }
 
+/// What: 1. background wall, 2. keep, 3. bottom tower, 4. bottom wall, 5. wall below gate, 
+/// 6. wall over gate, 7. upper wall, 8. upper tower, 9. gate, 10. gate arch, 11. bottom static wall, 12. upper static wall, 13. moat, 14. mlip, 
+/// 15. keep turret cover, 16. lower turret cover, 17. upper turret cover
+/// Positions are loaded from the config file: /config/wall_pos.txt
 void CBattleInterface::SiegeHelper::printPartOfWall(SDL_Surface * to, int what)
 {
 	Point pos = Point(-1, -1);
-	switch(what)
+	
+	if (what >= 1 && what <= 17)
 	{
-	case 1: //background wall
-		pos = Point(owner->pos.w + owner->pos.x - walls[1]->w, 55 + owner->pos.y);
-		break;
-	case 2: //keep
-		pos = Point(owner->pos.w + owner->pos.x - walls[2]->w, 154 + owner->pos.y);
-		break;
-	case 3: //bottom tower
-	case 4: //bottom wall
-	case 5: //below gate
-	case 6: //over gate
-	case 7: //upper wall
-	case 8: //upper tower
-	case 9: //gate
-	case 10: //gate arch
-	case 11: //bottom static wall
-	case 12: //upper static wall
-		pos.x = graphics->wallPositions[town->town->typeID][what - 3].x + owner->pos.x;
-		pos.y = graphics->wallPositions[town->town->typeID][what - 3].y + owner->pos.y;
-		break;
-	case 15: //keep creature cover
-		pos = Point(owner->pos.w + owner->pos.x - walls[2]->w, 154 + owner->pos.y);
-		break;
-	case 16: //bottom turret creature cover
-		pos.x = graphics->wallPositions[town->town->typeID][0].x + owner->pos.x;
-		pos.y = graphics->wallPositions[town->town->typeID][0].y + owner->pos.y;
-		break;
-	case 17: //upper turret creature cover
-		pos.x = graphics->wallPositions[town->town->typeID][5].x + owner->pos.x;
-		pos.y = graphics->wallPositions[town->town->typeID][5].y + owner->pos.y;
-		break;
-	};
+		pos.x = graphics->wallPositions[town->town->typeID][what - 1].x + owner->pos.x;
+		pos.y = graphics->wallPositions[town->town->typeID][what - 1].y + owner->pos.y;
+	}
 
 	if(pos.x != -1)
 	{

+ 2 - 3
client/CCastleInterface.cpp

@@ -1493,12 +1493,12 @@ CBuildWindow::CBuildWindow(const CGTownInstance *Town, const CBuilding * Buildin
 	{
 		buy = new AdventureMapButton(boost::str(boost::format(CGI->generaltexth->allTexts[595]) % building->Name()),
 		          "", boost::bind(&CBuildWindow::buyFunc,this), 45, 446,"IBUY30", SDLK_RETURN);
-		buy->borderColor = int3(173, 142, 66);
+		buy->borderColor = Colors::MetallicGold;
 		buy->borderEnabled = true;
 		
 		cancel = new AdventureMapButton(boost::str(boost::format(CGI->generaltexth->allTexts[596]) % building->Name()),
 		             "", boost::bind(&CBuildWindow::close,this), 290, 445, "ICANCEL", SDLK_ESCAPE);
-		cancel->borderColor = int3(173, 142, 66);
+		cancel->borderColor = Colors::MetallicGold;
 		cancel->borderEnabled = true;
 		buy->block(state!=7);
 	}
@@ -1713,7 +1713,6 @@ CMageGuildScreen::CMageGuildScreen(CCastleInterface * owner)
 	exit = new AdventureMapButton(CGI->generaltexth->allTexts[593],"",boost::bind(&CMageGuildScreen::close,this), 748, 556,"TPMAGE1.DEF",SDLK_RETURN);
 	exit->assignedKeys.insert(SDLK_ESCAPE);
 	
-	
 	std::vector<std::vector<Point> > positions;
 
 	positions.resize(5);

+ 2 - 1
client/CPreGame.cpp

@@ -1057,6 +1057,7 @@ SelectionTab::SelectionTab(CMenuScreen::EState Type, const boost::function<void(
 
 	slider = new CSlider(372, 86, tabType != CMenuScreen::saveGame ? 480 : 430, bind(&SelectionTab::sliderMove, this, _1), positions, curItems.size(), 0, false, 1);
 	slider->changeUsedEvents(WHEEL, true);
+	slider->slider->keepFrame = true;
 	format =  CDefHandler::giveDef("SCSELC.DEF");
 
 	sortingBy = _format;
@@ -3020,7 +3021,7 @@ void CBonusSelection::updateBonusSelection()
 			CAnimation * anim = new CAnimation();
 			anim->setCustom(picName, 0);
 			bonusButton->setImage(anim);
-			bonusButton->borderColor = int3(242, 226, 110); // yellow border
+			bonusButton->borderColor = Colors::Yellow; // yellow border
 			bonuses->addButton(bonusButton);
 		}
 	if (active)

+ 10 - 1
client/GUIBase.cpp

@@ -25,6 +25,15 @@
 extern std::queue<SDL_Event*> events;
 extern boost::mutex eventsM;
 
+SDL_Color Colors::MetallicGold = createColor(173, 142, 66);
+SDL_Color Colors::Yellow = createColor(242, 226, 110);
+
+SDL_Color Colors::createColor(int r, int g, int b)
+{
+	SDL_Color temp = {r, g, b, 0};
+	return temp;
+}
+
 void KeyShortcut::keyPressed(const SDL_KeyboardEvent & key)
 {
 	if(vstd::contains(assignedKeys,key.keysym.sym))
@@ -343,7 +352,7 @@ void CGuiHandler::run()
 	setThreadName(-1, "CGuiHandler::run");
 	try
 	{
-		CCS->curh->centerCursor();//Is this essential? random crashes on Linux
+		CCS->curh->centerCursor();
 
 		mainFPSmng->init(); // resets internal clock, needed for FPS manager
 		while(!terminate)

+ 9 - 0
client/GUIBase.h

@@ -597,6 +597,15 @@ struct SetCaptureState
 	~SetCaptureState();
 };
 
+class Colors
+{
+public:
+	static SDL_Color MetallicGold;
+	static SDL_Color Yellow;
+
+	static SDL_Color createColor(int r, int g, int b);
+};
+
 #define OBJ_CONSTRUCTION ObjectConstruction obj__i(this)
 #define OBJ_CONSTRUCTION_CAPTURING_ALL defActions = 255; SetCaptureState obj__i1(true, 255); ObjectConstruction obj__i(this)
 #define BLOCK_CAPTURING SetCaptureState obj__i(false, 0)

+ 3 - 3
client/GUIClasses.cpp

@@ -495,7 +495,7 @@ CInfoWindow::CInfoWindow(std::string Text, int player, const TCompsInfo &comps,
 	for(int i=0;i<Buttons.size();i++)
 	{
 		AdventureMapButton *button = new AdventureMapButton("","",boost::bind(&CInfoWindow::close,this),0,0,Buttons[i].first);
-		button->borderColor = int3(173, 142, 66);
+		button->borderColor = Colors::MetallicGold;
 		button->borderEnabled = true;
 		button->callback.add(Buttons[i].second); //each button will close the window apart from call-defined actions
 		buttons.push_back(button);
@@ -1744,8 +1744,6 @@ void CRecruitmentWindow::clickLeft(tribool down, bool previousState)
 			which = i;
 			int newAmount = std::min(amounts[i],creatures[i].amount);
 			slider->setAmount(newAmount);
-
-			slider->block(!newAmount);
 			max->block(!newAmount);
 
 			if(slider->value > newAmount)
@@ -5973,6 +5971,8 @@ CPuzzleWindow::CPuzzleWindow(const int3 &grailPos, float discoveredRatio)
 	pos = genRect(background->h, background->w, (conf.cc.resx - background->w) / 2, (conf.cc.resy - background->h) / 2);
 	quitb = new AdventureMapButton(CGI->generaltexth->allTexts[599], "", boost::bind(&CGuiHandler::popIntTotally, &GH, this), pos.x+670, pos.y+538, "IOK6432.DEF", SDLK_RETURN);
 	quitb->assignedKeys.insert(SDLK_ESCAPE);
+	quitb->borderColor = Colors::MetallicGold;
+	quitb->borderEnabled = true;
 
 	resdatabar = new CResDataBar("ZRESBAR.bmp", pos.x+3, pos.y+575, 32, 2, 85, 85);
 	resdatabar->pos.x = pos.x+3; resdatabar->pos.y = pos.y+575;

+ 4 - 1
client/Graphics.cpp

@@ -394,12 +394,15 @@ void Graphics::loadWallPositions()
 		const int MAX_BUF = 2000;
 		char buf[MAX_BUF+1];
 
+		// skip the first three lines because they are comment lines
+		inp.getline(buf, MAX_BUF);
+		inp.getline(buf, MAX_BUF);
 		inp.getline(buf, MAX_BUF);
 		std::string dump;
 		for(int g=0; g<ARRAY_COUNT(wallPositions); ++g)
 		{
 			inp >> dump;
-			for(int b=0; b<12; ++b)
+			for(int b = 0; b < 20; ++b)
 			{
 				Point pt;
 				inp >> pt.x;

+ 75 - 1
config/wall_pos.txt

@@ -1,5 +1,9 @@
-//this file is a description of positions of wall parts' positions, following lines contain positions of: bottom tower, bottom wall, wall below gate, wall over gate, upper wall, upper tower, gate, gate arch, bottom static wall and upper static wall, moat, mlip (x, y)
+//this file is a description of positions of wall parts' positions, following lines contain positions of: 1. background wall, 2. keep, 3. bottom tower, 4. bottom wall, 5. wall below gate, 
+//6. wall over gate, 7. upper wall, 8. upper tower, 9. gate, 10. gate arch, 11. bottom static wall, 12. upper static wall, 13. moat, 14. mlip, 
+//15. keep turret cover, 16. lower turret cover, 17. upper turret cover, 18. keep creature, 19. lower turret creature, 20. upper turret creature (x, y)
 //Castle 
+600 55
+720 154
 601 500 
 528 350 
 468 291 
@@ -12,7 +16,15 @@
 488 79 
 410 90 
 410 80 
+720 154
+601 500 
+568 35 
+527 -66
+368 304
+339 -192
 //Rampart 
+608 55
+724 154
 593 511 
 548 451 
 468 309 
@@ -25,7 +37,15 @@
 491 103 
 410 77 
 410 97 
+724 154
+593 511 
+565 31 
+527 -66
+368 304
+339 -192
 //Tower 
+615 55
+726 154
 591 516 
 547 452 
 474 298 
@@ -38,7 +58,15 @@
 513 79 
 410 90 
 410 80 
+726 154
+591 516 
+579 36 
+527 -66
+368 304
+339 -192
 //Inferno 
+606 55
+730 154
 594 514 
 560 451 
 484 316 
@@ -51,7 +79,15 @@
 501 92 
 410 68 
 410 68 
+730 154
+594 514 
+568 27 
+527 -66
+368 304
+339 -192
 //Necropolis 
+604 55
+730 154
 591 512 
 535 445 
 477 323 
@@ -64,7 +100,15 @@
 503 97 
 410 78 
 412 77 
+730 154
+591 512 
+560 26 
+527 -66
+368 304
+339 -192
 //Dungeon 
+608 55
+732 154
 599 495 
 558 448 
 470 296 
@@ -77,7 +121,15 @@
 493 53 
 277 94 
 277 94 
+608 55
+599 495 
+564 15 
+571 -66
+412 304
+383 -192
 //Stronghold 
+617 55
+731 154
 585 508 
 552 440 
 482 304 
@@ -90,7 +142,15 @@
 498 107 
 410 90 
 410 91 
+731 154
+585 508 
+567 30 
+527 -66
+368 304
+339 -192
 //Fortress 
+599 55
+721 154
 599 505 
 545 441 
 486 306 
@@ -103,7 +163,15 @@
 507 130 
 369 95 
 363 70 
+721 154
+599 505 
+547 27 
+527 -66
+368 304
+339 -192
 //Conflux 
+600 55
+736 154
 607 505 
 508 346 
 467 299 
@@ -116,3 +184,9 @@
 489 97 
 410 80 
 410 80 
+736 154
+607 505 
+575 28 
+527 -66
+368 304
+339 -192