Explorar o código

Several minor fixes/features
- moved all traslatable strings into one json file, removed threats.txt file
- implemented "spellbook animation" option
- fixed missing central tower when attacking fort

Ivan Savenko %!s(int64=12) %!d(string=hai) anos
pai
achega
6cb3cb006d

+ 8 - 3
client/CSpellWindow.cpp

@@ -284,7 +284,10 @@ void CSpellWindow::selectSchool(int school)
 {
 	if (selectedTab != school) 
 	{
-		turnPageRight();
+		if (selectedTab < school)
+			turnPageLeft();
+		else
+			turnPageRight();
 		selectedTab = school;
 		currentPage = 0;
 	}
@@ -507,12 +510,14 @@ void CSpellWindow::deactivate()
 
 void CSpellWindow::turnPageLeft()
 {
-	CCS->videoh->openAndPlayVideo("PGTRNLFT.SMK", pos.x+13, pos.y+15, screen);
+	if (settings["video"]["spellbookAnimation"].Bool())
+		CCS->videoh->openAndPlayVideo("PGTRNLFT.SMK", pos.x+13, pos.y+15, screen);
 }
 
 void CSpellWindow::turnPageRight()
 {
-	CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15, screen);
+	if (settings["video"]["spellbookAnimation"].Bool())
+		CCS->videoh->openAndPlayVideo("PGTRNRGH.SMK", pos.x+13, pos.y+15, screen);
 }
 
 void CSpellWindow::keyPressed(const SDL_KeyboardEvent & key)

+ 24 - 20
client/GUIClasses.cpp

@@ -3457,23 +3457,17 @@ CSystemOptionsWindow::CSystemOptionsWindow():
     CWindowObject(PLAYER_COLORED, "SysOpBck"),
     onFullscreenChanged(settings.listen["video"]["fullscreen"])
 {
-	//TODO: translation and\or config file
-	static const std::string fsLabel = "Fullscreen";
-	static const std::string fsHelp  = "{Fullscreen}\n\n If selected, VCMI will run in fullscreen mode, othervice VCMI will run in window";
-	static const std::string cwLabel = "Classic creature window";
-	static const std::string cwHelp  = "{Classic creature window}\n\n Enable original Heroes 3 creature window instead of new window from VCMI";
-	static const std::string rsLabel = "Resolution";
-	static const std::string rsHelp = "{Select resolution}\n\n Change in-game screen resolution. Will only affect adventure map. Game restart required to apply new resolution.";
-
 	OBJ_CONSTRUCTION_CAPTURING_ALL;
 	title = new CLabel(242, 32, FONT_BIG, CENTER, Colors::YELLOW, CGI->generaltexth->allTexts[568]);
 
+	const JsonNode & texts = CGI->generaltexth->localizedTexts["systemOptions"];
+
 	//left window section
 	leftGroup =  new CLabelGroup(FONT_MEDIUM, CENTER, Colors::YELLOW);
 	leftGroup->add(122,  64, CGI->generaltexth->allTexts[569]);
 	leftGroup->add(122, 130, CGI->generaltexth->allTexts[570]);
 	leftGroup->add(122, 196, CGI->generaltexth->allTexts[571]);
-	leftGroup->add(122, 262, rsLabel); //CGI->generaltexth->allTexts[20]
+	leftGroup->add(122, 262, texts["resolutionButton"]["label"].String());
 	leftGroup->add(122, 347, CGI->generaltexth->allTexts[394]);
 	leftGroup->add(122, 412, CGI->generaltexth->allTexts[395]);
 
@@ -3482,9 +3476,9 @@ CSystemOptionsWindow::CSystemOptionsWindow():
 	rightGroup->add(282, 57,  CGI->generaltexth->allTexts[572]);
 	rightGroup->add(282, 89,  CGI->generaltexth->allTexts[573]);
 	rightGroup->add(282, 121, CGI->generaltexth->allTexts[574]);
-	rightGroup->add(282, 153, CGI->generaltexth->allTexts[575]);
-	rightGroup->add(282, 185, cwLabel); //CGI->generaltexth->allTexts[576]
-	rightGroup->add(282, 217, fsLabel); //CGI->generaltexth->allTexts[577]
+	rightGroup->add(282, 153, CGI->generaltexth->allTexts[577]);
+	rightGroup->add(282, 185, texts["creatureWindowButton"]["label"].String());
+	rightGroup->add(282, 217, texts["fullscreenButton"]["label"].String());
 
 	//setting up buttons
 	load = new CAdventureMapButton (CGI->generaltexth->zelp[321].first, CGI->generaltexth->zelp[321].second,
@@ -3554,22 +3548,29 @@ CSystemOptionsWindow::CSystemOptionsWindow():
 		boost::bind(&CSystemOptionsWindow::toggleQuickCombat, this, true), boost::bind(&CSystemOptionsWindow::toggleQuickCombat, this, false),
 		std::map<int,std::string>(), CGI->generaltexth->zelp[362].second, false, "sysopchk.def", nullptr, 246, 87+32, false);
 
+	spellbookAnim = new CHighlightableButton(
+		boost::bind(&CSystemOptionsWindow::toggleSpellbookAnim, this, true), boost::bind(&CSystemOptionsWindow::toggleSpellbookAnim, this, false),
+		std::map<int,std::string>(), CGI->generaltexth->zelp[364].second, false, "sysopchk.def", nullptr, 246, 87+64, false);
+
 	newCreatureWin = new CHighlightableButton(
 		boost::bind(&CSystemOptionsWindow::toggleCreatureWin, this, true), boost::bind(&CSystemOptionsWindow::toggleCreatureWin, this, false),
-		std::map<int,std::string>(), cwHelp, false, "sysopchk.def", nullptr, 246, 183, false);
+		std::map<int,std::string>(), texts["creatureWindowButton"]["help"].String(), false, "sysopchk.def", nullptr, 246, 183, false);
 
 	fullscreen = new CHighlightableButton(
 		boost::bind(&CSystemOptionsWindow::toggleFullscreen, this, true), boost::bind(&CSystemOptionsWindow::toggleFullscreen, this, false),
-		std::map<int,std::string>(), fsHelp, false, "sysopchk.def", nullptr, 246, 215, false);
+		std::map<int,std::string>(), texts["fullscreenButton"]["help"].String(), false, "sysopchk.def", nullptr, 246, 215, false);
 
 	showReminder->select(settings["adventure"]["heroReminder"].Bool());
 	quickCombat->select(settings["adventure"]["quickCombat"].Bool());
+	spellbookAnim->select(settings["video"]["spellbookAnimation"].Bool());
 	newCreatureWin->select(settings["general"]["classicCreatureWindow"].Bool());
 	fullscreen->select(settings["video"]["fullscreen"].Bool());
 
 	onFullscreenChanged([&](const JsonNode &newState){ fullscreen->select(newState.Bool());});
 
-	gameResButton = new CAdventureMapButton("", rsHelp, boost::bind(&CSystemOptionsWindow::selectGameRes, this), 28, 275,"SYSOB12", SDLK_g);
+	gameResButton = new CAdventureMapButton("", texts["resolutionButton"]["help"].String(),
+	                                        boost::bind(&CSystemOptionsWindow::selectGameRes, this),
+	                                        28, 275,"SYSOB12", SDLK_g);
 
 	std::string resText;
 	resText += boost::lexical_cast<std::string>(settings["video"]["screenRes"]["width"].Float());
@@ -3581,11 +3582,8 @@ CSystemOptionsWindow::CSystemOptionsWindow():
 
 void CSystemOptionsWindow::selectGameRes()
 {
-	//TODO: translation and\or config file
-	static const std::string rsLabel = "Select resolution";
-	static const std::string rsHelp = "Change in-game screen resolution.";
-
 	std::vector<std::string> items;
+	const JsonNode & texts = CGI->generaltexth->localizedTexts["systemOptions"]["resolutionMenu"];
 
 	for( config::CConfigHandler::GuiOptionsMap::value_type& value : conf.guiOptions)
 	{
@@ -3594,7 +3592,7 @@ void CSystemOptionsWindow::selectGameRes()
 		items.push_back(resX + 'x' + resY);
 	}
 
-	GH.pushInt(new CObjectListWindow(items, nullptr, rsLabel, rsHelp,
+	GH.pushInt(new CObjectListWindow(items, nullptr, texts["label"].String(), texts["help"].String(),
 			   boost::bind(&CSystemOptionsWindow::setGameRes, this, _1)));
 }
 
@@ -3629,6 +3627,12 @@ void CSystemOptionsWindow::toggleQuickCombat(bool on)
 	quickCombat->Bool() = on;
 }
 
+void CSystemOptionsWindow::toggleSpellbookAnim(bool on)
+{
+	Settings quickCombat = settings.write["video"]["spellbookAnimation"];
+	quickCombat->Bool() = on;
+}
+
 void CSystemOptionsWindow::toggleCreatureWin(bool on)
 {
 	Settings classicCreatureWindow = settings.write["general"]["classicCreatureWindow"];

+ 2 - 1
client/GUIClasses.h

@@ -745,7 +745,7 @@ private:
 	//CHighlightableButton * showPath;
 	CHighlightableButton * showReminder;
 	CHighlightableButton * quickCombat;
-	//CHighlightableButton * videoSubs;
+	CHighlightableButton * spellbookAnim;
 	CHighlightableButton * newCreatureWin;
 	CHighlightableButton * fullscreen;
 
@@ -770,6 +770,7 @@ private:
 	//functions for checkboxes
 	void toggleReminder(bool on);
 	void toggleQuickCombat(bool on);
+	void toggleSpellbookAnim(bool on);
 	void toggleCreatureWin(bool on);
 	void toggleFullscreen(bool on);
 

+ 2 - 1
client/battle/CBattleInterface.cpp

@@ -3487,6 +3487,7 @@ BattleObjectsByHex CBattleInterface::sortObjectsByHex()
 	if (siegeH)
 	{
 		sorted.beforeAll.walls.push_back(1);  // 1. background wall
+		sorted.hex[135].walls.push_back(2);   // 2. keep
 		sorted.afterAll.walls.push_back(3);   // 3. bottom tower
 		sorted.hex[182].walls.push_back(4);   // 4. bottom wall
 		sorted.hex[130].walls.push_back(5);   // 5. wall below gate,
@@ -3497,11 +3498,11 @@ BattleObjectsByHex CBattleInterface::sortObjectsByHex()
 		sorted.hex[112].walls.push_back(10);  // 10. gate arch
 		sorted.hex[165].walls.push_back(11);  // 11. bottom static wall
 		sorted.hex[45].walls.push_back(12);   // 12. upper static wall
+
 		if (siegeH && siegeH->town->hasBuilt(BuildingID::CITADEL))
 		{
 			sorted.beforeAll.walls.push_back(13); // 13. moat
 			//sorted.beforeAll.walls.push_back(14); // 14. mlip (moat background terrain), blit as absolute obstacle
-			sorted.hex[135].walls.push_back(2);   // 2. keep
 			sorted.hex[135].walls.push_back(15);  // 15. keep turret cover
 		}
 		if (siegeH && siegeH->town->hasBuilt(BuildingID::CASTLE))

+ 6 - 2
config/schemas/settings.json

@@ -49,7 +49,7 @@
 			"type" : "object",
 			"additionalProperties" : false,
 			"default": {},
-			"required" : [ "screenRes", "bitsPerPixel", "fullscreen" ],
+			"required" : [ "screenRes", "bitsPerPixel", "fullscreen", "spellbookAnimation" ],
 			"properties" : {
 				"screenRes" : {
 					"type" : "object",
@@ -68,7 +68,11 @@
 				"fullscreen" : {
 					"type" : "boolean",
 					"default" : false
-				}
+				},
+				"spellbookAnimation" :  {
+					"type" : "boolean",
+					"default" : true
+				},
 			}
 		},
 		"adventure" : {

+ 0 - 14
config/threatlevel.txt

@@ -1,14 +0,0 @@
-
-Threat: 
-Effortless
-Very Weak
-Weak
-A bit weaker
-Equal
-A bit stronger
-Strong
-Very Strong
-Challenging
-Overpowering
-Deadly
-Impossible

+ 48 - 0
config/translate.json

@@ -0,0 +1,48 @@
+// This file contains all translateable strings added in VCMI
+{
+	"adventureMap":
+	{
+		"monsterThreat" :
+		{
+			"title" : "\n\n Threat: ",
+			"levels" :
+			[
+				"Effortless",
+				"Very Weak",
+				"Weak",
+				"A bit weaker",
+				"Equal",
+				"A bit stronger",
+				"Strong",
+				"Very Strong",
+				"Challenging",
+				"Overpowering",
+				"Deadly",
+				"Impossible"
+			]
+		}
+	},
+	"systemOptions" :
+	{
+		"fullscreenButton" :
+		{
+			"label" : "Fullscreen",
+			"help"  : "{Fullscreen}\n\n If selected, VCMI will run in fullscreen mode, othervice VCMI will run in window",
+		},
+		"creatureWindowButton" :
+		{
+			"label" : "Classic creature window",
+			"help"  : "{Classic creature window}\n\n Enable original Heroes 3 creature window instead of new window from VCMI"
+		},
+		"resolutionButton" :
+		{
+			"label" : "Resolution",
+			"help"  : "{Select resolution}\n\n Change in-game screen resolution. Will only affect adventure map. Game restart required to apply new resolution."
+		},
+		"resolutionMenu" :
+		{
+			"label" : "Select resolution",
+			"help" : "Change in-game screen resolution."
+		}
+	}
+}

+ 2 - 9
lib/CGeneralTextHandler.cpp

@@ -289,6 +289,8 @@ CGeneralTextHandler::CGeneralTextHandler()
 	readToVector("DATA/SKILLLEV.TXT", levels);
 	readToVector("DATA/OBJNAMES.TXT", names);
 
+	localizedTexts = JsonNode(ResourceID("config/translate.json", EResType::TEXT));
+
 	{
 		CLegacyConfigParser parser("DATA/GENRLTXT.TXT");
 		parser.endLine();
@@ -433,13 +435,4 @@ CGeneralTextHandler::CGeneralTextHandler()
 		}
 		while (parser.endLine());
 	}
-
-	std::string buffer;
-	std::ifstream ifs(*CResourceHandler::get()->getResourceName(ResourceID("config/threatlevel.txt")), std::ios::binary);
-	getline(ifs, buffer); //skip 1st line
-	for (int i = 0; i < 13; ++i)
-	{
-		getline(ifs, buffer);
-		threat.push_back(buffer);
-	}
 }

+ 4 - 1
lib/CGeneralTextHandler.h

@@ -10,6 +10,8 @@
  *
  */
 
+#include "JsonNode.h"
+
 /// Namespace that provides utilites for unicode support (UTF-8)
 namespace Unicode
 {
@@ -88,6 +90,8 @@ public:
 class DLL_LINKAGE CGeneralTextHandler //Handles general texts
 {
 public:
+	JsonNode localizedTexts;
+
 	std::vector<std::string> allTexts;
 
 	std::vector<std::string> arraytxt;
@@ -122,7 +126,6 @@ public:
 	//type: quest, progress, complete, rollover, log OR time limit //index: 0-2 seer hut, 3-5 border guard
 	std::vector<std::string> seerNames;
 	std::vector<std::string> tentColors;
-	std::vector<std::string> threat; //power rating for neutral stacks
 
 	//sec skills
 	std::vector <std::string>  skillName;

+ 16 - 16
lib/CObjectHandler.cpp

@@ -3231,24 +3231,24 @@ const std::string & CGCreature::getHoverText() const
 
 	if(const CGHeroInstance *selHero = cb->getSelectedHero(cb->getCurrentPlayer()))
 	{
-		std::vector<std::string> * texts = &VLC->generaltexth->threat;
-		hoverName += "\n\n ";
-		hoverName += (*texts)[0];
+		const JsonNode & texts = VLC->generaltexth->localizedTexts["adventureMap"]["monsterThreat"];
+
+		hoverName += texts["title"].String();
 		int choice;
 		double ratio = ((double)getArmyStrength() / selHero->getTotalStrength());
-		if (ratio < 0.1) choice = 1;
-		else if (ratio < 0.25) choice = 2;
-		else if (ratio < 0.6) choice = 3;
-		else if (ratio < 0.9) choice = 4;
-		else if (ratio < 1.1) choice = 5;
-		else if (ratio < 1.3) choice = 6;
-		else if (ratio < 1.8) choice = 7;
-		else if (ratio < 2.5) choice = 8;
-		else if (ratio < 4) choice = 9;
-		else if (ratio < 8) choice = 10;
-		else if (ratio < 20) choice = 11;
-		else choice = 12;
-		hoverName += (*texts)[choice];
+		     if (ratio < 0.1)  choice = 0;
+		else if (ratio < 0.25) choice = 1;
+		else if (ratio < 0.6)  choice = 2;
+		else if (ratio < 0.9)  choice = 3;
+		else if (ratio < 1.1)  choice = 4;
+		else if (ratio < 1.3)  choice = 5;
+		else if (ratio < 1.8)  choice = 6;
+		else if (ratio < 2.5)  choice = 7;
+		else if (ratio < 4)    choice = 8;
+		else if (ratio < 8)    choice = 9;
+		else if (ratio < 20)   choice = 10;
+		else                   choice = 11;
+		hoverName += texts["levels"].Vector()[choice].String();
 	}
 	return hoverName;
 }