mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Initial part of dynamically-sized adventure map:
- removed no longer used CConfigHandler - remove no longer use resolutions.json - moved widget management from adventure map to a separate class - adventure map layout is now loaded from config
This commit is contained in:
		| @@ -338,9 +338,6 @@ int main(int argc, char * argv[]) | ||||
| 	testFile("VIDEO/GOOD1A.SMK", "campaign movies"); | ||||
| 	testFile("SOUNDS/G1A.WAV", "campaign music"); //technically not a music but voiced intro sounds | ||||
|  | ||||
| 	conf.init(); | ||||
| 	logGlobal->info("Loading settings: %d ms", pomtime.getDiff()); | ||||
|  | ||||
| 	srand ( (unsigned int)time(nullptr) ); | ||||
|  | ||||
|  | ||||
| @@ -659,10 +656,18 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn | ||||
| 	int renderWidth = 0, renderHeight = 0; | ||||
| 	auto aspectRatio = (float)w / (float)h; | ||||
| 	auto minDiff = 10.f; | ||||
| 	for (const auto& pair : conf.guiOptions) | ||||
|  | ||||
| 	// TODO: CONFIGURABLE ADVMAP | ||||
| 	static const std::vector<Point> supportedResolutions = { | ||||
| 		{ 800, 600 } | ||||
| 	}; | ||||
|  | ||||
|  | ||||
| 	for (const auto& pair : supportedResolutions) | ||||
| 	{ | ||||
| 		int pWidth, pHeight; | ||||
| 		std::tie(pWidth, pHeight) = pair.first; | ||||
| 		int pWidth = pair.x; | ||||
| 		int pHeight = pair.y; | ||||
|  | ||||
| 		/* filter out resolution which is larger than window */ | ||||
| 		if (pWidth > w || pHeight > h) | ||||
| 		{ | ||||
| @@ -690,10 +695,13 @@ static bool recreateWindow(int w, int h, int bpp, bool fullscreen, int displayIn | ||||
| 		// no matching resolution for upscaling - complain & fallback to default resolution. | ||||
| 		logGlobal->error("Failed to match rendering resolution for %dx%d!", w, h); | ||||
| 		Settings newRes = settings.write["video"]["screenRes"]; | ||||
| 		std::tie(w, h) = conf.guiOptions.begin()->first; | ||||
|  | ||||
| 		w = supportedResolutions.front().x; | ||||
| 		h = supportedResolutions.front().y; | ||||
|  | ||||
| 		newRes["width"].Float() = w; | ||||
| 		newRes["height"].Float() = h; | ||||
| 		conf.SetResolution(w, h); | ||||
|  | ||||
| 		logGlobal->error("Falling back to %dx%d", w, h); | ||||
| 		renderWidth = w; | ||||
| 		renderHeight = h; | ||||
|   | ||||
| @@ -2,8 +2,8 @@ set(client_SRCS | ||||
| 	StdInc.cpp | ||||
| 	../CCallback.cpp | ||||
|  | ||||
| 	adventureMap/CAdvMapPanel.cpp | ||||
| 	adventureMap/CAdventureMapInterface.cpp | ||||
| 	adventureMap/CAdventureMapWidget.cpp | ||||
| 	adventureMap/CAdventureOptions.cpp | ||||
| 	adventureMap/CInGameConsole.cpp | ||||
| 	adventureMap/CInfoBar.cpp | ||||
| @@ -129,8 +129,8 @@ set(client_SRCS | ||||
| set(client_HEADERS | ||||
| 	StdInc.h | ||||
|  | ||||
| 	adventureMap/CAdvMapPanel.h | ||||
| 	adventureMap/CAdventureMapInterface.h | ||||
| 	adventureMap/CAdventureMapWidget.h | ||||
| 	adventureMap/CAdventureOptions.h | ||||
| 	adventureMap/CInGameConsole.h | ||||
| 	adventureMap/CInfoBar.h | ||||
|   | ||||
| @@ -15,7 +15,6 @@ | ||||
| #include "adventureMap/CAdventureMapInterface.h" | ||||
| #include "mapView/mapHandler.h" | ||||
| #include "adventureMap/CList.h" | ||||
| #include "adventureMap/CInfoBar.h" | ||||
| #include "battle/BattleInterface.h" | ||||
| #include "battle/BattleEffectsController.h" | ||||
| #include "battle/BattleFieldController.h" | ||||
|   | ||||
| @@ -1,94 +0,0 @@ | ||||
| /* | ||||
|  * CAdvMapPanel.cpp, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
|  | ||||
| #include "StdInc.h" | ||||
| #include "CAdvMapPanel.h" | ||||
|  | ||||
| #include "../widgets/Buttons.h" | ||||
| #include "../widgets/Images.h" | ||||
| #include "../render/CAnimation.h" | ||||
| #include "../render/IImage.h" | ||||
| #include "../gui/CGuiHandler.h" | ||||
|  | ||||
| CAdvMapPanel::CAdvMapPanel(std::shared_ptr<IImage> bg, Point position) | ||||
| 	: CIntObject() | ||||
| 	, background(bg) | ||||
| { | ||||
| 	defActions = 255; | ||||
| 	recActions = 255; | ||||
| 	pos.x += position.x; | ||||
| 	pos.y += position.y; | ||||
| 	if (bg) | ||||
| 	{ | ||||
| 		pos.w = bg->width(); | ||||
| 		pos.h = bg->height(); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CAdvMapPanel::addChildColorableButton(std::shared_ptr<CButton> button) | ||||
| { | ||||
| 	colorableButtons.push_back(button); | ||||
| 	addChildToPanel(button, ACTIVATE | DEACTIVATE); | ||||
| } | ||||
|  | ||||
| void CAdvMapPanel::setPlayerColor(const PlayerColor & clr) | ||||
| { | ||||
| 	for(auto & button : colorableButtons) | ||||
| 	{ | ||||
| 		button->setPlayerColor(clr); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CAdvMapPanel::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	if(background) | ||||
| 		background->draw(to, pos.x, pos.y); | ||||
|  | ||||
| 	CIntObject::showAll(to); | ||||
| } | ||||
|  | ||||
| void CAdvMapPanel::addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions) | ||||
| { | ||||
| 	otherObjects.push_back(obj); | ||||
| 	obj->recActions |= actions | SHOWALL; | ||||
| 	obj->recActions &= ~DISPOSE; | ||||
| 	addChild(obj.get(), false); | ||||
| } | ||||
|  | ||||
| CAdvMapWorldViewPanel::CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, std::shared_ptr<IImage> bg, Point position, int spaceBottom, const PlayerColor &color) | ||||
| 	: CAdvMapPanel(bg, position), icons(_icons) | ||||
| { | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||
| 	int fillerHeight = bg ? spaceBottom - pos.y - pos.h : 0; | ||||
|  | ||||
| 	if(fillerHeight > 0) | ||||
| 	{ | ||||
| 		backgroundFiller = std::make_shared<CFilledTexture>("DIBOXBCK", Rect(0, pos.h, pos.w, fillerHeight)); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CAdvMapWorldViewPanel::recolorIcons(const PlayerColor & color, int indexOffset) | ||||
| { | ||||
| 	assert(iconsData.size() == currentIcons.size()); | ||||
|  | ||||
| 	for(size_t idx = 0; idx < iconsData.size(); idx++) | ||||
| 	{ | ||||
| 		const auto & data = iconsData.at(idx); | ||||
| 		currentIcons[idx]->setFrame(data.first + indexOffset); | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void CAdvMapWorldViewPanel::addChildIcon(std::pair<int, Point> data, int indexOffset) | ||||
| { | ||||
| 	OBJECT_CONSTRUCTION_CUSTOM_CAPTURING(255-DISPOSE); | ||||
| 	iconsData.push_back(data); | ||||
| 	currentIcons.push_back(std::make_shared<CAnimImage>(icons, data.first + indexOffset, 0, data.second.x, data.second.y)); | ||||
| } | ||||
|  | ||||
| @@ -1,60 +0,0 @@ | ||||
| /* | ||||
|  * CAdvMapPanel.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include "../gui/CIntObject.h" | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
| class PlayerColor; | ||||
| VCMI_LIB_NAMESPACE_END | ||||
|  | ||||
| class CAnimation; | ||||
| class CAnimImage; | ||||
| class CFilledTexture; | ||||
| class CButton; | ||||
| class IImage; | ||||
|  | ||||
| /// simple panel that contains other displayable elements; used to separate groups of controls | ||||
| class CAdvMapPanel : public CIntObject | ||||
| { | ||||
| 	std::vector<std::shared_ptr<CButton>> colorableButtons; | ||||
| 	std::vector<std::shared_ptr<CIntObject>> otherObjects; | ||||
| 	/// the surface passed to this obj will be freed in dtor | ||||
| 	std::shared_ptr<IImage> background; | ||||
| public: | ||||
| 	CAdvMapPanel(std::shared_ptr<IImage> bg, Point position); | ||||
|  | ||||
| 	void addChildToPanel(std::shared_ptr<CIntObject> obj, ui8 actions = 0); | ||||
| 	void addChildColorableButton(std::shared_ptr<CButton> button); | ||||
| 	/// recolors all buttons to given player color | ||||
| 	void setPlayerColor(const PlayerColor & clr); | ||||
|  | ||||
| 	void showAll(SDL_Surface * to) override; | ||||
| }; | ||||
|  | ||||
| /// specialized version of CAdvMapPanel that handles recolorable def-based pictures for world view info panel | ||||
| class CAdvMapWorldViewPanel : public CAdvMapPanel | ||||
| { | ||||
| 	/// data that allows reconstruction of panel info icons | ||||
| 	std::vector<std::pair<int, Point>> iconsData; | ||||
| 	/// ptrs to child-pictures constructed from iconsData | ||||
| 	std::vector<std::shared_ptr<CAnimImage>> currentIcons; | ||||
| 	/// surface drawn below world view panel on higher resolutions (won't be needed when world view panel is configured for extraResolutions mod) | ||||
| 	std::shared_ptr<CFilledTexture> backgroundFiller; | ||||
| 	std::shared_ptr<CAnimation> icons; | ||||
| public: | ||||
| 	CAdvMapWorldViewPanel(std::shared_ptr<CAnimation> _icons, std::shared_ptr<IImage> bg, Point position, int spaceBottom, const PlayerColor &color); | ||||
|  | ||||
| 	void addChildIcon(std::pair<int, Point> data, int indexOffset); | ||||
|  | ||||
| 	/// recreates all pictures from given def to recolor them according to current player color | ||||
| 	void recolorIcons(const PlayerColor & color, int indexOffset); | ||||
| }; | ||||
|  | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * CAdvMapInt.cpp, part of VCMI engine | ||||
|  * CAdventureMapInterface.cpp, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
| @@ -10,14 +10,13 @@ | ||||
| #include "StdInc.h" | ||||
| #include "CAdventureMapInterface.h" | ||||
|  | ||||
| #include "CAdvMapPanel.h" | ||||
| #include "CAdventureOptions.h" | ||||
| #include "CInGameConsole.h" | ||||
| #include "CMinimap.h" | ||||
| #include "CResDataBar.h" | ||||
| #include "CList.h" | ||||
| #include "CInfoBar.h" | ||||
| #include "MapAudioPlayer.h" | ||||
| #include "CAdventureMapWidget.h" | ||||
|  | ||||
| #include "../mapView/mapHandler.h" | ||||
| #include "../mapView/MapView.h" | ||||
| @@ -32,6 +31,7 @@ | ||||
| #include "../render/CAnimation.h" | ||||
| #include "../gui/CursorHandler.h" | ||||
| #include "../render/IImage.h" | ||||
| #include "../renderSDL/SDL_Extensions.h" | ||||
| #include "../gui/CGuiHandler.h" | ||||
| #include "../gui/Shortcut.h" | ||||
| #include "../widgets/TextControls.h" | ||||
| @@ -49,171 +49,24 @@ | ||||
| #include "../../lib/CPathfinder.h" | ||||
| #include "../../lib/mapping/CMap.h" | ||||
|  | ||||
| #define ADVOPT (conf.go()->ac) | ||||
|  | ||||
| std::shared_ptr<CAdventureMapInterface> adventureInt; | ||||
|  | ||||
| CAdventureMapInterface::CAdventureMapInterface(): | ||||
| 	minimap(new CMinimap(Rect(ADVOPT.minimapX, ADVOPT.minimapY, ADVOPT.minimapW, ADVOPT.minimapH))), | ||||
| 	statusbar(CGStatusBar::create(ADVOPT.statusbarX,ADVOPT.statusbarY,ADVOPT.statusbarG)), | ||||
| 	heroList(new CHeroList(ADVOPT.hlistSize, Point(ADVOPT.hlistX, ADVOPT.hlistY), ADVOPT.hlistAU, ADVOPT.hlistAD)), | ||||
| 	townList(new CTownList(ADVOPT.tlistSize, Point(ADVOPT.tlistX, ADVOPT.tlistY), ADVOPT.tlistAU, ADVOPT.tlistAD)), | ||||
| 	infoBar(new CInfoBar(Point(ADVOPT.infoboxX, ADVOPT.infoboxY))), | ||||
| 	resdatabar(new CResDataBar), | ||||
| 	mapAudio(new MapAudioPlayer()), | ||||
| 	terrain(new MapView(Point(ADVOPT.advmapX, ADVOPT.advmapY), Point(ADVOPT.advmapW, ADVOPT.advmapH))), | ||||
| 	state(EGameState::NOT_INITIALIZED), | ||||
| 	spellBeingCasted(nullptr), | ||||
| 	activeMapPanel(nullptr), | ||||
| 	scrollingCursorSet(false) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; | ||||
| 	pos.x = pos.y = 0; | ||||
| 	pos.w = GH.screenDimensions().x; | ||||
| 	pos.h = GH.screenDimensions().y; | ||||
| 	strongInterest = true; // handle all mouse move events to prevent dead mouse move space in fullscreen mode | ||||
|  | ||||
| 	bg = IImage::createFromFile(ADVOPT.mainGraphic); | ||||
| 	if(!ADVOPT.worldViewGraphic.empty()) | ||||
| 	{ | ||||
| 		bgWorldView = IImage::createFromFile(ADVOPT.worldViewGraphic); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		bgWorldView = nullptr; | ||||
| 		logGlobal->warn("ADVOPT.worldViewGraphic is empty => bitmap not loaded"); | ||||
| 	} | ||||
| 	if (!bgWorldView) | ||||
| 	{ | ||||
| 		logGlobal->warn("bgWorldView not defined in resolution config; fallback to VWorld.bmp"); | ||||
| 		bgWorldView = IImage::createFromFile("VWorld.bmp"); | ||||
| 	} | ||||
|  | ||||
| 	worldViewIcons = std::make_shared<CAnimation>("VwSymbol");//todo: customize with ADVOPT | ||||
| 	worldViewIcons->preload(); | ||||
|  | ||||
| 	for(int g = 0; g < ADVOPT.gemG.size(); ++g) | ||||
| 	{ | ||||
| 		gems.push_back(std::make_shared<CAnimImage>(ADVOPT.gemG[g], 0, 0, ADVOPT.gemX[g], ADVOPT.gemY[g])); | ||||
| 	} | ||||
|  | ||||
| 	auto makeButton = [&](int textID, std::function<void()> callback, config::ButtonInfo info, EShortcut key) -> std::shared_ptr<CButton> | ||||
| 	{ | ||||
| 		auto button = std::make_shared<CButton>(Point(info.x, info.y), info.defName, CGI->generaltexth->zelp[textID], callback, key, info.playerColoured); | ||||
| 		for(auto image : info.additionalDefs) | ||||
| 			button->addImage(image); | ||||
| 		return button; | ||||
| 	}; | ||||
|  | ||||
| 	kingOverview = makeButton(293, std::bind(&CAdventureMapInterface::fshowOverview,this),     ADVOPT.kingOverview, EShortcut::ADVENTURE_KINGDOM_OVERVIEW); | ||||
| 	underground  = makeButton(294, std::bind(&CAdventureMapInterface::fswitchLevel,this),      ADVOPT.underground,  EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL); | ||||
| 	questlog     = makeButton(295, std::bind(&CAdventureMapInterface::fshowQuestlog,this),     ADVOPT.questlog,     EShortcut::ADVENTURE_QUEST_LOG); | ||||
| 	sleepWake    = makeButton(296, std::bind(&CAdventureMapInterface::fsleepWake,this),        ADVOPT.sleepWake,    EShortcut::ADVENTURE_TOGGLE_SLEEP); | ||||
| 	moveHero     = makeButton(297, std::bind(&CAdventureMapInterface::fmoveHero,this),         ADVOPT.moveHero,     EShortcut::ADVENTURE_MOVE_HERO); | ||||
| 	spellbook    = makeButton(298, std::bind(&CAdventureMapInterface::fshowSpellbok,this),     ADVOPT.spellbook,    EShortcut::ADVENTURE_CAST_SPELL); | ||||
| 	advOptions   = makeButton(299, std::bind(&CAdventureMapInterface::fadventureOPtions,this), ADVOPT.advOptions,   EShortcut::ADVENTURE_GAME_OPTIONS); | ||||
| 	sysOptions   = makeButton(300, std::bind(&CAdventureMapInterface::fsystemOptions,this),    ADVOPT.sysOptions,   EShortcut::GLOBAL_OPTIONS); | ||||
| 	nextHero     = makeButton(301, std::bind(&CAdventureMapInterface::fnextHero,this),         ADVOPT.nextHero,     EShortcut::ADVENTURE_NEXT_HERO); | ||||
| 	endTurn      = makeButton(302, std::bind(&CAdventureMapInterface::fendTurn,this),          ADVOPT.endTurn,      EShortcut::ADVENTURE_END_TURN); | ||||
|  | ||||
| 	int panelSpaceBottom = GH.screenDimensions().y - resdatabar->pos.h - 4; | ||||
|  | ||||
| 	panelMain = std::make_shared<CAdvMapPanel>(nullptr, Point(0, 0)); | ||||
| 	// TODO correct drawing position | ||||
| 	panelWorldView = std::make_shared<CAdvMapWorldViewPanel>(worldViewIcons, bgWorldView, Point(heroList->pos.x - 2, 195), panelSpaceBottom, LOCPLINT->playerID); | ||||
|  | ||||
| 	panelMain->addChildColorableButton(kingOverview); | ||||
| 	panelMain->addChildColorableButton(underground); | ||||
| 	panelMain->addChildColorableButton(questlog); | ||||
| 	panelMain->addChildColorableButton(sleepWake); | ||||
| 	panelMain->addChildColorableButton(moveHero); | ||||
| 	panelMain->addChildColorableButton(spellbook); | ||||
| 	panelMain->addChildColorableButton(advOptions); | ||||
| 	panelMain->addChildColorableButton(sysOptions); | ||||
| 	panelMain->addChildColorableButton(nextHero); | ||||
| 	panelMain->addChildColorableButton(endTurn); | ||||
|  | ||||
|  | ||||
| 	// TODO move configs to resolutions.json, similarly to previous buttons | ||||
| 	config::ButtonInfo worldViewBackConfig = config::ButtonInfo(); | ||||
| 	worldViewBackConfig.defName = "IOK6432.DEF"; | ||||
| 	worldViewBackConfig.x = GH.screenDimensions().x - 73; | ||||
| 	worldViewBackConfig.y = 343 + 195; | ||||
| 	worldViewBackConfig.playerColoured = false; | ||||
| 	panelWorldView->addChildToPanel( | ||||
| 		makeButton(288, std::bind(&CAdventureMapInterface::fworldViewBack,this), worldViewBackConfig, EShortcut::GLOBAL_CANCEL), ACTIVATE | DEACTIVATE); | ||||
|  | ||||
| 	config::ButtonInfo worldViewPuzzleConfig = config::ButtonInfo(); | ||||
| 	worldViewPuzzleConfig.defName = "VWPUZ.DEF"; | ||||
| 	worldViewPuzzleConfig.x = GH.screenDimensions().x - 188; | ||||
| 	worldViewPuzzleConfig.y = 343 + 195; | ||||
| 	worldViewPuzzleConfig.playerColoured = false; | ||||
| 	panelWorldView->addChildToPanel( // no help text for this one | ||||
| 		std::make_shared<CButton>(Point(worldViewPuzzleConfig.x, worldViewPuzzleConfig.y), worldViewPuzzleConfig.defName, std::pair<std::string, std::string>(), | ||||
| 				std::bind(&CPlayerInterface::showPuzzleMap,LOCPLINT), EShortcut::ADVENTURE_VIEW_PUZZLE, worldViewPuzzleConfig.playerColoured), ACTIVATE | DEACTIVATE); | ||||
|  | ||||
| 	config::ButtonInfo worldViewScale1xConfig = config::ButtonInfo(); | ||||
| 	worldViewScale1xConfig.defName = "VWMAG1.DEF"; | ||||
| 	worldViewScale1xConfig.x = GH.screenDimensions().x - 191; | ||||
| 	worldViewScale1xConfig.y = 23 + 195; | ||||
| 	worldViewScale1xConfig.playerColoured = false; | ||||
| 	panelWorldView->addChildToPanel( // help text is wrong for this button | ||||
| 		makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale1x,this), worldViewScale1xConfig, EShortcut::SELECT_INDEX_1), ACTIVATE | DEACTIVATE); | ||||
|  | ||||
| 	config::ButtonInfo worldViewScale2xConfig = config::ButtonInfo(); | ||||
| 	worldViewScale2xConfig.defName = "VWMAG2.DEF"; | ||||
| 	worldViewScale2xConfig.x = GH.screenDimensions().x- 191 + 63; | ||||
| 	worldViewScale2xConfig.y = 23 + 195; | ||||
| 	worldViewScale2xConfig.playerColoured = false; | ||||
| 	panelWorldView->addChildToPanel( // help text is wrong for this button | ||||
| 		makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale2x,this), worldViewScale2xConfig, EShortcut::SELECT_INDEX_2), ACTIVATE | DEACTIVATE); | ||||
|  | ||||
| 	config::ButtonInfo worldViewScale4xConfig = config::ButtonInfo(); | ||||
| 	worldViewScale4xConfig.defName = "VWMAG4.DEF"; | ||||
| 	worldViewScale4xConfig.x = GH.screenDimensions().x- 191 + 126; | ||||
| 	worldViewScale4xConfig.y = 23 + 195; | ||||
| 	worldViewScale4xConfig.playerColoured = false; | ||||
| 	panelWorldView->addChildToPanel( // help text is wrong for this button | ||||
| 		makeButton(291, std::bind(&CAdventureMapInterface::fworldViewScale4x,this), worldViewScale4xConfig, EShortcut::SELECT_INDEX_4), ACTIVATE | DEACTIVATE); | ||||
|  | ||||
| 	config::ButtonInfo worldViewUndergroundConfig = config::ButtonInfo(); | ||||
| 	worldViewUndergroundConfig.defName = "IAM010.DEF"; | ||||
| 	worldViewUndergroundConfig.additionalDefs.push_back("IAM003.DEF"); | ||||
| 	worldViewUndergroundConfig.x = GH.screenDimensions().x - 115; | ||||
| 	worldViewUndergroundConfig.y = 343 + 195; | ||||
| 	worldViewUndergroundConfig.playerColoured = true; | ||||
| 	worldViewUnderground = makeButton(294, std::bind(&CAdventureMapInterface::fswitchLevel,this), worldViewUndergroundConfig, EShortcut::ADVENTURE_TOGGLE_MAP_LEVEL); | ||||
| 	panelWorldView->addChildColorableButton(worldViewUnderground); | ||||
|  | ||||
| 	onCurrentPlayerChanged(LOCPLINT->playerID); | ||||
|  | ||||
| 	int iconColorMultiplier = currentPlayerID.getNum() * 19; | ||||
| 	int wvLeft = heroList->pos.x - 2; // TODO correct drawing position | ||||
| 	//int wvTop = 195; | ||||
| 	for (int i = 0; i < 5; ++i) | ||||
| 	{ | ||||
| 		panelWorldView->addChildIcon(std::pair<int, Point>(i, Point(5, 58 + i * 20)), iconColorMultiplier); | ||||
| 		panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 45, 263 + i * 20, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, | ||||
| 												Colors::WHITE, CGI->generaltexth->allTexts[612 + i])); | ||||
| 	} | ||||
| 	for (int i = 0; i < 7; ++i) | ||||
| 	{ | ||||
| 		panelWorldView->addChildIcon(std::pair<int, Point>(i +  5, Point(5, 182 + i * 20)), iconColorMultiplier); | ||||
| 		panelWorldView->addChildIcon(std::pair<int, Point>(i + 12, Point(160, 182 + i * 20)), iconColorMultiplier); | ||||
| 		panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 45, 387 + i * 20, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, | ||||
| 												Colors::WHITE, CGI->generaltexth->allTexts[619 + i])); | ||||
| 	} | ||||
| 	panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft +   5, 367, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, | ||||
| 											Colors::WHITE, CGI->generaltexth->allTexts[617])); | ||||
| 	panelWorldView->addChildToPanel(std::make_shared<CLabel>(wvLeft + 45, 367, EFonts::FONT_SMALL, ETextAlignment::TOPLEFT, | ||||
| 											Colors::WHITE, CGI->generaltexth->allTexts[618])); | ||||
|  | ||||
| 	activeMapPanel = panelMain; | ||||
|  | ||||
| 	widget = std::make_shared<CAdventureMapWidget>(); | ||||
| 	exitWorldView(); | ||||
|  | ||||
| 	underground->block(!CGI->mh->getMap()->twoLevel); | ||||
| 	questlog->block(!CGI->mh->getMap()->quests.size()); | ||||
| 	worldViewUnderground->block(!CGI->mh->getMap()->twoLevel); | ||||
| 	widget->setOptionHasQuests(!CGI->mh->getMap()->quests.empty()); | ||||
| 	widget->setOptionHasUnderground(CGI->mh->getMap()->twoLevel); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::fshowOverview() | ||||
| @@ -253,18 +106,13 @@ void CAdventureMapInterface::fswitchLevel() | ||||
| 	if (maxLevels < 2) | ||||
| 		return; | ||||
|  | ||||
| 	terrain->onMapLevelSwitched(); | ||||
| 	widget->getMapView()->onMapLevelSwitched(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onMapViewMoved(const Rect & visibleArea, int mapLevel) | ||||
| { | ||||
| 	underground->setIndex(mapLevel, true); | ||||
| 	underground->redraw(); | ||||
|  | ||||
| 	worldViewUnderground->setIndex(mapLevel, true); | ||||
| 	worldViewUnderground->redraw(); | ||||
|  | ||||
| 	minimap->onMapViewMoved(visibleArea, mapLevel); | ||||
| 	widget->setOptionUndergroundLevel(mapLevel > 0); | ||||
| 	widget->getMinimap()->onMapViewMoved(visibleArea, mapLevel); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onAudioResumed() | ||||
| @@ -298,9 +146,6 @@ void CAdventureMapInterface::fsleepWake() | ||||
|  | ||||
| 	if (newSleep) | ||||
| 		fnextHero(); | ||||
|  | ||||
| 	// redraw to update the image of sleep/wake button | ||||
| 	panelMain->redraw(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::fmoveHero() | ||||
| @@ -381,59 +226,48 @@ void CAdventureMapInterface::fendTurn() | ||||
| void CAdventureMapInterface::updateButtons() | ||||
| { | ||||
| 	const auto * hero = LOCPLINT->localState->getCurrentHero(); | ||||
|  | ||||
| 	sleepWake->block(!hero); | ||||
| 	spellbook->block(!hero); | ||||
| 	moveHero->block(!hero || !LOCPLINT->localState->hasPath(hero) || hero->movement == 0); | ||||
|  | ||||
| 	const auto * nextSuitableHero = LOCPLINT->localState->getNextWanderingHero(hero); | ||||
| 	nextHero->block(nextSuitableHero == nullptr); | ||||
|  | ||||
| 	if(hero) | ||||
| 	{ | ||||
| 		bool state = LOCPLINT->localState->isHeroSleeping(hero); | ||||
| 		sleepWake->setIndex(state ? 1 : 0, true); | ||||
| 		sleepWake->redraw(); | ||||
| 	} | ||||
| 	widget->setOptionHeroSelected(hero != nullptr); | ||||
| 	widget->setOptionHeroCanMove(hero && LOCPLINT->localState->hasPath(hero) && hero->movement != 0); | ||||
| 	widget->setOptionHasNextHero(nextSuitableHero != nullptr); | ||||
| 	widget->setOptionHeroSleeping(hero && LOCPLINT->localState->isHeroSleeping(hero)); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onHeroMovementStarted(const CGHeroInstance * hero) | ||||
| { | ||||
| 	infoBar->popAll(); | ||||
| 	infoBar->showSelection(); | ||||
| 	widget->getInfoBar()->popAll(); | ||||
| 	widget->getInfoBar()->showSelection(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onHeroChanged(const CGHeroInstance *h) | ||||
| { | ||||
| 	heroList->update(h); | ||||
| 	widget->getHeroList()->update(h); | ||||
|  | ||||
| 	if (h && h == LOCPLINT->localState->getCurrentHero() && !infoBar->showingComponents()) | ||||
| 		infoBar->showSelection(); | ||||
| 	if (h && h == LOCPLINT->localState->getCurrentHero() && !widget->getInfoBar()->showingComponents()) | ||||
| 		widget->getInfoBar()->showSelection(); | ||||
|  | ||||
| 	updateButtons(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onTownChanged(const CGTownInstance * town) | ||||
| { | ||||
| 	townList->update(town); | ||||
| 	widget->getTownList()->update(town); | ||||
|  | ||||
| 	if (town && town == LOCPLINT->localState->getCurrentTown() && !infoBar->showingComponents()) | ||||
| 		infoBar->showSelection(); | ||||
| 	if (town && town == LOCPLINT->localState->getCurrentTown() && !widget->getInfoBar()->showingComponents()) | ||||
| 		widget->getInfoBar()->showSelection(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::showInfoBoxMessage(const std::vector<Component> & components, std::string message, int timer) | ||||
| { | ||||
| 	infoBar->pushComponents(components, message, timer); | ||||
| 	widget->getInfoBar()->pushComponents(components, message, timer); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::activate() | ||||
| { | ||||
| 	CIntObject::activate(); | ||||
| 	if (!(active & KEYBOARD)) | ||||
| 		CIntObject::activate(KEYBOARD); | ||||
|  | ||||
| 	screenBuf = screen; | ||||
| 	GH.statusbar = statusbar; | ||||
| 	 | ||||
| 	if(LOCPLINT) | ||||
| 	{ | ||||
| @@ -441,94 +275,28 @@ void CAdventureMapInterface::activate() | ||||
| 		LOCPLINT->cingconsole->pos = this->pos; | ||||
| 	} | ||||
|  | ||||
| 	if(state != EGameState::ENEMY_TURN && state != EGameState::HOTSEAT_WAIT) | ||||
| 	{ | ||||
| 		assert(state == EGameState::MAKING_TURN); | ||||
|  | ||||
| 		activeMapPanel->activate(); | ||||
| 		if (state == EGameState::MAKING_TURN) | ||||
| 		{ | ||||
| 			heroList->activate(); | ||||
| 			townList->activate(); | ||||
| 			infoBar->activate(); | ||||
| 		} | ||||
| 		minimap->activate(); | ||||
| 		terrain->activate(); | ||||
| 		statusbar->activate(); | ||||
|  | ||||
| 		GH.fakeMouseMove(); //to restore the cursor | ||||
| 	} | ||||
| 	GH.fakeMouseMove(); //to restore the cursor | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::deactivate() | ||||
| { | ||||
| 	CIntObject::deactivate(); | ||||
|  | ||||
| 	if(state != EGameState::ENEMY_TURN && state != EGameState::HOTSEAT_WAIT) | ||||
| 	{ | ||||
| 		assert(state == EGameState::MAKING_TURN); | ||||
|  | ||||
| 		CCS->curh->set(Cursor::Map::POINTER); | ||||
| 		activeMapPanel->deactivate(); | ||||
| 		if (state == EGameState::MAKING_TURN) | ||||
| 		{ | ||||
| 			heroList->deactivate(); | ||||
| 			townList->deactivate(); | ||||
| 			infoBar->deactivate(); | ||||
| 		} | ||||
| 		minimap->deactivate(); | ||||
| 		terrain->deactivate(); | ||||
| 		statusbar->deactivate(); | ||||
| 	} | ||||
| 	CCS->curh->set(Cursor::Map::POINTER); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::showAll(SDL_Surface * to) | ||||
| { | ||||
| 	bg->draw(to, 0, 0); | ||||
|  | ||||
| //	if(state != EGameState::MAKING_TURN) | ||||
| //		return; | ||||
|  | ||||
| 	heroList->showAll(to); | ||||
| 	townList->showAll(to); | ||||
| 	infoBar->showAll(to); | ||||
|  | ||||
| 	activeMapPanel->showAll(to); | ||||
|  | ||||
| 	minimap->showAll(to); | ||||
| 	terrain->showAll(to); | ||||
| 	show(to); | ||||
|  | ||||
| 	resdatabar->showAll(to); | ||||
| 	statusbar->show(to); | ||||
| 	CSDL_Ext::fillSurface(to, CSDL_Ext::toSDL(ColorRGBA(255, 0,255,255)));// FIXME: CONFIGURABLE ADVMAP - debug fill to detect any empty areas | ||||
| 	CIntObject::showAll(to); | ||||
| 	LOCPLINT->cingconsole->show(to); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::show(SDL_Surface * to) | ||||
| { | ||||
| //	if(state != EGameState::MAKING_TURN) | ||||
| //		return; | ||||
|  | ||||
| 	handleMapScrollingUpdate(); | ||||
|  | ||||
| 	for(int i = 0; i < 4; i++) | ||||
| 	{ | ||||
| 		if(settings["session"]["spectate"].Bool()) | ||||
| 			gems[i]->setFrame(PlayerColor(1).getNum()); | ||||
| 		else | ||||
| 			gems[i]->setFrame(LOCPLINT->playerID.getNum()); | ||||
| 	} | ||||
|  | ||||
| 	minimap->show(to); | ||||
| 	terrain->show(to); | ||||
|  | ||||
| 	for(int i = 0; i < 4; i++) | ||||
| 		gems[i]->showAll(to); | ||||
|  | ||||
| 	CIntObject::show(to); | ||||
| 	LOCPLINT->cingconsole->show(to); | ||||
|  | ||||
| 	infoBar->show(to); | ||||
| 	statusbar->showAll(to); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::handleMapScrollingUpdate() | ||||
| @@ -540,7 +308,7 @@ void CAdventureMapInterface::handleMapScrollingUpdate() | ||||
| 	uint32_t scrollSpeedPixels = settings["adventure"]["scrollSpeedPixels"].Float(); | ||||
| 	uint32_t scrollDistance = scrollSpeedPixels * timePassed / 1000; | ||||
|  | ||||
| 	bool scrollingActive = !GH.isKeyboardCtrlDown() && isActive() && state == EGameState::MAKING_TURN; | ||||
| 	bool scrollingActive = !GH.isKeyboardCtrlDown() && isActive() && widget->getState() == EGameState::MAKING_TURN; | ||||
|  | ||||
| 	Point cursorPosition = GH.getCursorPosition(); | ||||
| 	Point scrollDirection; | ||||
| @@ -560,7 +328,7 @@ void CAdventureMapInterface::handleMapScrollingUpdate() | ||||
| 	Point scrollDelta = scrollDirection * scrollDistance; | ||||
|  | ||||
| 	if (scrollingActive && scrollDelta != Point(0,0)) | ||||
| 		terrain->onMapScrolled(scrollDelta); | ||||
| 		widget->getMapView()->onMapScrolled(scrollDelta); | ||||
|  | ||||
| 	if (scrollDelta == Point(0,0) && !scrollingCursorSet) | ||||
| 		return; | ||||
| @@ -599,17 +367,17 @@ void CAdventureMapInterface::handleMapScrollingUpdate() | ||||
|  | ||||
| void CAdventureMapInterface::centerOnTile(int3 on) | ||||
| { | ||||
| 	terrain->onCenteredTile(on); | ||||
| 	widget->getMapView()->onCenteredTile(on); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::centerOnObject(const CGObjectInstance * obj) | ||||
| { | ||||
| 	terrain->onCenteredObject(obj); | ||||
| 	widget->getMapView()->onCenteredObject(obj); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::keyPressed(EShortcut key) | ||||
| { | ||||
| 	if (state != EGameState::MAKING_TURN) | ||||
| 	if (widget->getState() != EGameState::MAKING_TURN) | ||||
| 		return; | ||||
|  | ||||
| 	//fake mouse use to trigger onTileHovered() | ||||
| @@ -726,7 +494,7 @@ void CAdventureMapInterface::keyPressed(EShortcut key) | ||||
| 	case EShortcut::ADVENTURE_NEXT_TOWN: | ||||
| 			if(isActive() && !GH.isKeyboardCtrlDown()) //no ctrl, advmapint is on the top => switch to town | ||||
| 			{ | ||||
| 				townList->selectNext(); | ||||
| 				widget->getTownList()->selectNext(); | ||||
| 			} | ||||
| 			return; | ||||
| 		} | ||||
| @@ -778,7 +546,7 @@ void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel) | ||||
| { | ||||
| 	assert(sel); | ||||
|  | ||||
| 	infoBar->popAll(); | ||||
| 	widget->getInfoBar()->popAll(); | ||||
| 	mapAudio->onSelectionChanged(sel); | ||||
| 	bool centerView = !settings["session"]["autoSkip"].Bool(); | ||||
|  | ||||
| @@ -789,25 +557,25 @@ void CAdventureMapInterface::onSelectionChanged(const CArmedInstance *sel) | ||||
| 	{ | ||||
| 		auto town = dynamic_cast<const CGTownInstance*>(sel); | ||||
|  | ||||
| 		infoBar->showTownSelection(town); | ||||
| 		townList->select(town); | ||||
| 		heroList->select(nullptr); | ||||
| 		widget->getInfoBar()->showTownSelection(town); | ||||
| 		widget->getTownList()->select(town); | ||||
| 		widget->getHeroList()->select(nullptr); | ||||
| 		onHeroChanged(nullptr); | ||||
| 	} | ||||
| 	else //hero selected | ||||
| 	{ | ||||
| 		auto hero = dynamic_cast<const CGHeroInstance*>(sel); | ||||
|  | ||||
| 		infoBar->showHeroSelection(hero); | ||||
| 		heroList->select(hero); | ||||
| 		townList->select(nullptr); | ||||
| 		widget->getInfoBar()->showHeroSelection(hero); | ||||
| 		widget->getHeroList()->select(hero); | ||||
| 		widget->getTownList()->select(nullptr); | ||||
|  | ||||
| 		LOCPLINT->localState->verifyPath(hero); | ||||
| 		onHeroChanged(hero); | ||||
| 	} | ||||
| 	updateButtons(); | ||||
| 	townList->redraw(); | ||||
| 	heroList->redraw(); | ||||
| 	widget->getHeroList()->redraw(); | ||||
| 	widget->getTownList()->redraw(); | ||||
| } | ||||
|  | ||||
| bool CAdventureMapInterface::isActive() | ||||
| @@ -818,15 +586,15 @@ bool CAdventureMapInterface::isActive() | ||||
| void CAdventureMapInterface::onMapTilesChanged(boost::optional<std::unordered_set<int3>> positions) | ||||
| { | ||||
| 	if (positions) | ||||
| 		minimap->updateTiles(*positions); | ||||
| 		widget->getMinimap()->updateTiles(*positions); | ||||
| 	else | ||||
| 		minimap->update(); | ||||
| 		widget->getMinimap()->update(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onHotseatWaitStarted(PlayerColor playerID) | ||||
| { | ||||
| 	onCurrentPlayerChanged(playerID); | ||||
| 	state = EGameState::HOTSEAT_WAIT; | ||||
| 	widget->setState(EGameState::HOTSEAT_WAIT); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onEnemyTurnStarted(PlayerColor playerID) | ||||
| @@ -836,10 +604,10 @@ void CAdventureMapInterface::onEnemyTurnStarted(PlayerColor playerID) | ||||
|  | ||||
| 	adjustActiveness(true); | ||||
| 	mapAudio->onEnemyTurnStarted(); | ||||
| 	minimap->setAIRadar(true); | ||||
| 	infoBar->startEnemyTurn(LOCPLINT->cb->getCurrentPlayer()); | ||||
| 	minimap->showAll(screen);//force refresh on inactive object | ||||
| 	infoBar->showAll(screen);//force refresh on inactive object | ||||
| 	widget->getMinimap()->setAIRadar(true); | ||||
| 	widget->getInfoBar()->startEnemyTurn(LOCPLINT->cb->getCurrentPlayer()); | ||||
| 	widget->getMinimap()->showAll(screen);//force refresh on inactive object | ||||
| 	widget->getInfoBar()->showAll(screen);//force refresh on inactive object | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::adjustActiveness(bool aiTurnStart) | ||||
| @@ -850,9 +618,9 @@ void CAdventureMapInterface::adjustActiveness(bool aiTurnStart) | ||||
| 		deactivate(); | ||||
|  | ||||
| 	if (aiTurnStart) | ||||
| 		state = EGameState::ENEMY_TURN; | ||||
| 		widget->setState(EGameState::ENEMY_TURN); | ||||
| 	else | ||||
| 		state = EGameState::MAKING_TURN; | ||||
| 		widget->setState(EGameState::MAKING_TURN); | ||||
|  | ||||
| 	if(wasActive) | ||||
| 		activate(); | ||||
| @@ -866,29 +634,24 @@ void CAdventureMapInterface::onCurrentPlayerChanged(PlayerColor playerID) | ||||
| 		return; | ||||
|  | ||||
| 	currentPlayerID = playerID; | ||||
| 	bg->playerColored(currentPlayerID); | ||||
|  | ||||
| 	panelMain->setPlayerColor(currentPlayerID); | ||||
| 	panelWorldView->setPlayerColor(currentPlayerID); | ||||
| 	panelWorldView->recolorIcons(currentPlayerID, currentPlayerID.getNum() * 19); | ||||
| 	resdatabar->colorize(currentPlayerID); | ||||
| 	widget->setPlayer(playerID); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID) | ||||
| { | ||||
| 	onCurrentPlayerChanged(playerID); | ||||
|  | ||||
| 	state = EGameState::MAKING_TURN; | ||||
| 	widget->setState(EGameState::MAKING_TURN); | ||||
| 	if(LOCPLINT->cb->getCurrentPlayer() == LOCPLINT->playerID | ||||
| 		|| settings["session"]["spectate"].Bool()) | ||||
| 	{ | ||||
| 		adjustActiveness(false); | ||||
| 		minimap->setAIRadar(false); | ||||
| 		infoBar->showSelection(); | ||||
| 		widget->getMinimap()->setAIRadar(false); | ||||
| 		widget->getInfoBar()->showSelection(); | ||||
| 	} | ||||
|  | ||||
| 	heroList->update(); | ||||
| 	townList->update(); | ||||
| 	widget->getHeroList()->update(); | ||||
| 	widget->getTownList()->update(); | ||||
|  | ||||
| 	const CGHeroInstance * heroToSelect = nullptr; | ||||
|  | ||||
| @@ -917,7 +680,7 @@ void CAdventureMapInterface::onPlayerTurnStarted(PlayerColor playerID) | ||||
| 	} | ||||
|  | ||||
| 	//show new day animation and sound on infobar | ||||
| 	infoBar->showDate(); | ||||
| 	widget->getInfoBar()->showDate(); | ||||
|  | ||||
| 	onHeroChanged(nullptr); | ||||
| 	showAll(screen); | ||||
| @@ -959,7 +722,7 @@ const CGObjectInstance* CAdventureMapInterface::getActiveObject(const int3 &mapP | ||||
|  | ||||
| void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos) | ||||
| { | ||||
| 	if(state != EGameState::MAKING_TURN) | ||||
| 	if(widget->getState() == EGameState::MAKING_TURN) | ||||
| 		return; | ||||
|  | ||||
| 	//FIXME: this line breaks H3 behavior for Dimension Door | ||||
| @@ -1050,7 +813,7 @@ void CAdventureMapInterface::onTileLeftClicked(const int3 &mapPos) | ||||
|  | ||||
| void CAdventureMapInterface::onTileHovered(const int3 &mapPos) | ||||
| { | ||||
| 	if(state != EGameState::MAKING_TURN) | ||||
| 	if(widget->getState() != EGameState::MAKING_TURN) | ||||
| 		return; | ||||
|  | ||||
| 	//may occur just at the start of game (fake move before full intiialization) | ||||
| @@ -1060,7 +823,7 @@ void CAdventureMapInterface::onTileHovered(const int3 &mapPos) | ||||
| 	if(!LOCPLINT->cb->isVisible(mapPos)) | ||||
| 	{ | ||||
| 		CCS->curh->set(Cursor::Map::POINTER); | ||||
| 		statusbar->clear(); | ||||
| 		GH.statusbar->clear(); | ||||
| 		return; | ||||
| 	} | ||||
| 	auto objRelations = PlayerRelations::ALLIES; | ||||
| @@ -1070,12 +833,12 @@ void CAdventureMapInterface::onTileHovered(const int3 &mapPos) | ||||
| 		objRelations = LOCPLINT->cb->getPlayerRelations(LOCPLINT->playerID, objAtTile->tempOwner); | ||||
| 		std::string text = LOCPLINT->localState->getCurrentHero() ? objAtTile->getHoverText(LOCPLINT->localState->getCurrentHero()) : objAtTile->getHoverText(LOCPLINT->playerID); | ||||
| 		boost::replace_all(text,"\n"," "); | ||||
| 		statusbar->write(text); | ||||
| 		GH.statusbar->write(text); | ||||
| 	} | ||||
| 	else | ||||
| 	{ | ||||
| 		std::string hlp = CGI->mh->getTerrainDescr(mapPos, false); | ||||
| 		statusbar->write(hlp); | ||||
| 		GH.statusbar->write(hlp); | ||||
| 	} | ||||
|  | ||||
| 	if(spellBeingCasted) | ||||
| @@ -1212,12 +975,12 @@ void CAdventureMapInterface::showMoveDetailsInStatusbar(const CGHeroInstance & h | ||||
| 	boost::replace_first(result, "%POINTS", std::to_string(movementPointsLastTurnCost)); | ||||
| 	boost::replace_first(result, "%REMAINING", std::to_string(remainingPointsAfterMove)); | ||||
|  | ||||
| 	statusbar->write(result); | ||||
| 	GH.statusbar->write(result); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::onTileRightClicked(const int3 &mapPos) | ||||
| { | ||||
| 	if(state != EGameState::MAKING_TURN) | ||||
| 	if(widget->getState() != EGameState::MAKING_TURN) | ||||
| 		return; | ||||
|  | ||||
| 	if(spellBeingCasted) | ||||
| @@ -1255,17 +1018,14 @@ void CAdventureMapInterface::enterCastingMode(const CSpell * sp) | ||||
| 	Settings config = settings.write["session"]["showSpellRange"]; | ||||
| 	config->Bool() = true; | ||||
|  | ||||
| 	deactivate(); | ||||
| 	terrain->activate(); | ||||
| 	GH.fakeMouseMove(); | ||||
| 	widget->setState(EGameState::CASTING_SPELL); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::exitCastingMode() | ||||
| { | ||||
| 	assert(spellBeingCasted); | ||||
| 	spellBeingCasted = nullptr; | ||||
| 	terrain->deactivate(); | ||||
| 	activate(); | ||||
| 	widget->setState(EGameState::MAKING_TURN); | ||||
|  | ||||
| 	Settings config = settings.write["session"]["showSpellRange"]; | ||||
| 	config->Bool() = false; | ||||
| @@ -1286,7 +1046,7 @@ void CAdventureMapInterface::leaveCastingMode(const int3 & dest) | ||||
|  | ||||
| Rect CAdventureMapInterface::terrainAreaPixels() const | ||||
| { | ||||
| 	return terrain->pos; | ||||
| 	return widget->getMapView()->pos; | ||||
| } | ||||
|  | ||||
| const IShipyard * CAdventureMapInterface::ourInaccessibleShipyard(const CGObjectInstance *obj) const | ||||
| @@ -1303,35 +1063,14 @@ const IShipyard * CAdventureMapInterface::ourInaccessibleShipyard(const CGObject | ||||
|  | ||||
| void CAdventureMapInterface::exitWorldView() | ||||
| { | ||||
| 	state = EGameState::MAKING_TURN; | ||||
|  | ||||
| 	panelMain->activate(); | ||||
| 	panelWorldView->deactivate(); | ||||
| 	activeMapPanel = panelMain; | ||||
|  | ||||
| 	townList->activate(); | ||||
| 	heroList->activate(); | ||||
| 	infoBar->activate(); | ||||
|  | ||||
| 	redraw(); | ||||
| 	terrain->onViewMapActivated(); | ||||
| 	widget->setState(EGameState::MAKING_TURN); | ||||
| 	widget->getMapView()->onViewMapActivated(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::openWorldView(int tileSize) | ||||
| { | ||||
| 	state = EGameState::WORLD_VIEW; | ||||
| 	panelMain->deactivate(); | ||||
| 	panelWorldView->activate(); | ||||
|  | ||||
| 	activeMapPanel = panelWorldView; | ||||
|  | ||||
| 	townList->deactivate(); | ||||
| 	heroList->deactivate(); | ||||
| 	infoBar->showSelection(); // to prevent new day animation interfering world view mode | ||||
| 	infoBar->deactivate(); | ||||
|  | ||||
| 	redraw(); | ||||
| 	terrain->onViewWorldActivated(tileSize); | ||||
| 	widget->setState(EGameState::WORLD_VIEW); | ||||
| 	widget->getMapView()->onViewWorldActivated(tileSize); | ||||
| } | ||||
|  | ||||
| void CAdventureMapInterface::openWorldView() | ||||
| @@ -1342,5 +1081,5 @@ void CAdventureMapInterface::openWorldView() | ||||
| void CAdventureMapInterface::openWorldView(const std::vector<ObjectPosInfo>& objectPositions, bool showTerrain) | ||||
| { | ||||
| 	openWorldView(11); | ||||
| 	terrain->onViewSpellActivated(11, objectPositions, showTerrain); | ||||
| 	widget->getMapView()->onViewSpellActivated(11, objectPositions, showTerrain); | ||||
| } | ||||
|   | ||||
| @@ -1,5 +1,5 @@ | ||||
| /* | ||||
|  * CAdvMapInt.h, part of VCMI engine | ||||
|  * CAdventureMapInterface.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
| @@ -29,6 +29,7 @@ class CButton; | ||||
| class IImage; | ||||
| class CAnimImage; | ||||
| class CGStatusBar; | ||||
| class CAdventureMapWidget; | ||||
| class CAdvMapPanel; | ||||
| class CAdvMapWorldViewPanel; | ||||
| class CAnimation; | ||||
| @@ -48,17 +49,6 @@ struct MapDrawingInfo; | ||||
| class CAdventureMapInterface : public CIntObject | ||||
| { | ||||
| private: | ||||
| 	enum class EGameState | ||||
| 	{ | ||||
| 		NOT_INITIALIZED, | ||||
| 		HOTSEAT_WAIT, | ||||
| 		MAKING_TURN, | ||||
| 		ENEMY_TURN, | ||||
| 		WORLD_VIEW | ||||
| 	}; | ||||
|  | ||||
| 	EGameState state; | ||||
|  | ||||
| 	/// currently acting player | ||||
| 	PlayerColor currentPlayerID; | ||||
|  | ||||
| @@ -67,37 +57,8 @@ private: | ||||
|  | ||||
| 	const CSpell *spellBeingCasted; //nullptr if none | ||||
|  | ||||
| 	std::vector<std::shared_ptr<CAnimImage>> gems; | ||||
|  | ||||
| 	std::shared_ptr<IImage> bg; | ||||
| 	std::shared_ptr<IImage> bgWorldView; | ||||
| 	std::shared_ptr<CButton> kingOverview; | ||||
| 	std::shared_ptr<CButton> sleepWake; | ||||
| 	std::shared_ptr<CButton> underground; | ||||
| 	std::shared_ptr<CButton> questlog; | ||||
| 	std::shared_ptr<CButton> moveHero; | ||||
| 	std::shared_ptr<CButton> spellbook; | ||||
| 	std::shared_ptr<CButton> advOptions; | ||||
| 	std::shared_ptr<CButton> sysOptions; | ||||
| 	std::shared_ptr<CButton> nextHero; | ||||
| 	std::shared_ptr<CButton> endTurn; | ||||
| 	std::shared_ptr<CButton> worldViewUnderground; | ||||
|  | ||||
| 	std::shared_ptr<MapView> terrain; | ||||
| 	std::shared_ptr<CMinimap> minimap; | ||||
| 	std::shared_ptr<CHeroList> heroList; | ||||
| 	std::shared_ptr<CTownList> townList; | ||||
| 	std::shared_ptr<CInfoBar> infoBar; | ||||
| 	std::shared_ptr<CGStatusBar> statusbar; | ||||
| 	std::shared_ptr<CResDataBar> resdatabar; | ||||
|  | ||||
| 	std::shared_ptr<CAdvMapPanel> panelMain; // panel that holds all right-side buttons in normal view | ||||
| 	std::shared_ptr<CAdvMapWorldViewPanel> panelWorldView; // panel that holds all buttons and other ui in world view | ||||
| 	std::shared_ptr<CAdvMapPanel> activeMapPanel; // currently active panel (either main or world view, depending on current mode) | ||||
|  | ||||
| 	std::shared_ptr<CAnimation> worldViewIcons;// images for world view overlay | ||||
|  | ||||
| 	std::shared_ptr<MapAudioPlayer> mapAudio; | ||||
| 	std::shared_ptr<CAdventureMapWidget> widget; | ||||
|  | ||||
| private: | ||||
| 	//functions bound to buttons | ||||
|   | ||||
							
								
								
									
										390
									
								
								client/adventureMap/CAdventureMapWidget.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										390
									
								
								client/adventureMap/CAdventureMapWidget.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,390 @@ | ||||
| /* | ||||
|  * CAdventureMapWidget.cpp, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| #include "StdInc.h" | ||||
| #include "CAdventureMapWidget.h" | ||||
|  | ||||
| #include "CInfoBar.h" | ||||
| #include "CList.h" | ||||
| #include "CMinimap.h" | ||||
| #include "CResDataBar.h" | ||||
|  | ||||
| #include "../gui/CGuiHandler.h" | ||||
| #include "../mapView/MapView.h" | ||||
| #include "../render/CAnimation.h" | ||||
| #include "../render/IImage.h" | ||||
| #include "../widgets/Buttons.h" | ||||
| #include "../widgets/Images.h" | ||||
| #include "../widgets/TextControls.h" | ||||
|  | ||||
| #include "../CPlayerInterface.h" | ||||
| #include "../PlayerLocalState.h" | ||||
|  | ||||
| #include "../../lib/StringConstants.h" | ||||
| #include "../../lib/filesystem/ResourceID.h" | ||||
|  | ||||
| CAdventureMapWidget::CAdventureMapWidget() | ||||
| 	: state(EGameState::NOT_INITIALIZED) | ||||
| { | ||||
| 	pos.w = 800; | ||||
| 	pos.h = 600; | ||||
| 	REGISTER_BUILDER("adventureInfobar",         &CAdventureMapWidget::buildInfobox         ); | ||||
| 	REGISTER_BUILDER("adventureMapImage",        &CAdventureMapWidget::buildMapImage        ); | ||||
| 	REGISTER_BUILDER("adventureMapButton",       &CAdventureMapWidget::buildMapButton       ); | ||||
| 	REGISTER_BUILDER("adventureMapContainer",    &CAdventureMapWidget::buildMapContainer    ); | ||||
| 	REGISTER_BUILDER("adventureMapGameArea",     &CAdventureMapWidget::buildMapGameArea     ); | ||||
| 	REGISTER_BUILDER("adventureMapHeroList",     &CAdventureMapWidget::buildMapHeroList     ); | ||||
| 	REGISTER_BUILDER("adventureMapIcon",         &CAdventureMapWidget::buildMapIcon         ); | ||||
| 	REGISTER_BUILDER("adventureMapTownList",     &CAdventureMapWidget::buildMapTownList     ); | ||||
| 	REGISTER_BUILDER("adventureMinimap",         &CAdventureMapWidget::buildMinimap         ); | ||||
| 	REGISTER_BUILDER("adventureResourceDateBar", &CAdventureMapWidget::buildResourceDateBar ); | ||||
| 	REGISTER_BUILDER("adventureStatusBar",       &CAdventureMapWidget::buildStatusBar       ); | ||||
|  | ||||
| 	const JsonNode config(ResourceID("config/widgets/adventureMap.json")); | ||||
|  | ||||
| 	for(const auto & entry : config["options"]["imagesPlayerColored"].Vector()) | ||||
| 	{ | ||||
| 		ResourceID resourceName(entry.String(), EResType::IMAGE); | ||||
| 		playerColorerImages.push_back(resourceName.getName()); | ||||
| 	} | ||||
|  | ||||
| 	build(config); | ||||
| } | ||||
|  | ||||
| Rect CAdventureMapWidget::readSourceArea(const JsonNode & source, const JsonNode & sourceCommon) | ||||
| { | ||||
| 	const auto & input = source.isNull() ? sourceCommon : source; | ||||
|  | ||||
| 	return readArea(input, Rect(Point(0, 0), Point(800, 600))); | ||||
| } | ||||
|  | ||||
| Rect CAdventureMapWidget::readTargetArea(const JsonNode & source) | ||||
| { | ||||
| 	if(subwidgetSizes.empty()) | ||||
| 		return readArea(source, pos); | ||||
| 	return readArea(source, subwidgetSizes.back()); | ||||
| } | ||||
|  | ||||
| Rect CAdventureMapWidget::readArea(const JsonNode & source, const Rect & boundingBox) | ||||
| { | ||||
| 	const auto & object = source.Struct(); | ||||
|  | ||||
| 	if(object.count("left") + object.count("width") + object.count("right") != 2) | ||||
| 		logGlobal->error("Invalid area definition in widget! Unable to load width!"); | ||||
|  | ||||
| 	if(object.count("top") + object.count("height") + object.count("bottom") != 2) | ||||
| 		logGlobal->error("Invalid area definition in widget! Unable to load height!"); | ||||
|  | ||||
| 	int left = source["left"].Integer(); | ||||
| 	int width = source["width"].Integer(); | ||||
| 	int right = source["right"].Integer(); | ||||
|  | ||||
| 	int top = source["top"].Integer(); | ||||
| 	int height = source["height"].Integer(); | ||||
| 	int bottom = source["bottom"].Integer(); | ||||
|  | ||||
| 	Point topLeft(left, top); | ||||
| 	Point dimensions(width, height); | ||||
|  | ||||
| 	if(source["left"].isNull()) | ||||
| 		topLeft.x = boundingBox.w - right - width; | ||||
|  | ||||
| 	if(source["width"].isNull()) | ||||
| 		dimensions.x = boundingBox.w - right - left; | ||||
|  | ||||
| 	if(source["top"].isNull()) | ||||
| 		topLeft.y = boundingBox.h - bottom - height; | ||||
|  | ||||
| 	if(source["height"].isNull()) | ||||
| 		dimensions.y = boundingBox.h - bottom - top; | ||||
|  | ||||
| 	return Rect(topLeft + boundingBox.topLeft(), dimensions); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<IImage> CAdventureMapWidget::loadImage(const std::string & name) | ||||
| { | ||||
| 	ResourceID resource(name, EResType::IMAGE); | ||||
|  | ||||
| 	if(images.count(resource.getName()) == 0) | ||||
| 		images[resource.getName()] = IImage::createFromFile(resource.getName()); | ||||
| 	; | ||||
|  | ||||
| 	return images[resource.getName()]; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CAnimation> CAdventureMapWidget::loadAnimation(const std::string & name) | ||||
| { | ||||
| 	ResourceID resource(name, EResType::ANIMATION); | ||||
|  | ||||
| 	if(animations.count(resource.getName()) == 0) | ||||
| 		animations[resource.getName()] = std::make_shared<CAnimation>(resource.getName()); | ||||
|  | ||||
| 	return animations[resource.getName()]; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildInfobox(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	return std::make_shared<CInfoBar>(area); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapImage(const JsonNode & input) | ||||
| { | ||||
| 	Rect targetArea = readTargetArea(input["area"]); | ||||
| 	Rect sourceArea = readSourceArea(input["sourceArea"], input["area"]); | ||||
| 	std::string image = input["image"].String(); | ||||
|  | ||||
| 	return std::make_shared<CFilledTexture>(loadImage(image), targetArea, sourceArea); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapButton(const JsonNode & input) | ||||
| { | ||||
| 	auto position = readTargetArea(input["area"]); | ||||
| 	auto image = input["image"].String(); | ||||
| 	auto help = readHintText(input["help"]); | ||||
| 	return std::make_shared<CButton>(position.topLeft(), image, help); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapContainer(const JsonNode & input) | ||||
| { | ||||
| 	auto position = readTargetArea(input["area"]); | ||||
| 	auto result = std::make_shared<CAdventureMapContainerWidget>(); | ||||
|  | ||||
| 	result->moveBy(position.topLeft()); | ||||
| 	subwidgetSizes.push_back(position); | ||||
| 	for(const auto & entry : input["items"].Vector()) | ||||
| 	{ | ||||
| 		result->ownedChildren.push_back(buildWidget(entry)); | ||||
| 		result->addChild(result->ownedChildren.back().get(), true); | ||||
| 	} | ||||
| 	subwidgetSizes.pop_back(); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapGameArea(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	return std::make_shared<MapView>(area.topLeft(), area.dimensions()); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapHeroList(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	Rect item = readTargetArea(input["item"]); | ||||
|  | ||||
| 	Point itemOffset(input["itemsOffset"]["x"].Integer(), input["itemsOffset"]["y"].Integer()); | ||||
| 	int itemsCount = input["itemsCount"].Integer(); | ||||
|  | ||||
| 	auto result = std::make_shared<CHeroList>(itemsCount, area.topLeft() + item.topLeft(), itemOffset, LOCPLINT->localState->getWanderingHeroes().size()); | ||||
|  | ||||
| 	subwidgetSizes.push_back(area); | ||||
|  | ||||
| 	if(!input["scrollUp"].isNull()) | ||||
| 		result->setScrollUpButton(std::dynamic_pointer_cast<CButton>(buildMapButton(input["scrollUp"]))); | ||||
|  | ||||
| 	if(!input["scrollDown"].isNull()) | ||||
| 		result->setScrollDownButton(std::dynamic_pointer_cast<CButton>(buildMapButton(input["scrollDown"]))); | ||||
|  | ||||
| 	subwidgetSizes.pop_back(); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapIcon(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	size_t index = input["index"].Integer(); | ||||
| 	size_t perPlayer = input["perPlayer"].Integer(); | ||||
| 	std::string image = input["image"].String(); | ||||
|  | ||||
| 	return std::make_shared<CAdventureMapIcon>(area.topLeft(), loadAnimation(image), index, perPlayer); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMapTownList(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	Rect item = readTargetArea(input["item"]); | ||||
|  | ||||
| 	Point itemOffset(input["itemsOffset"]["x"].Integer(), input["itemsOffset"]["y"].Integer()); | ||||
| 	int itemsCount = input["itemsCount"].Integer(); | ||||
|  | ||||
| 	auto result = std::make_shared<CTownList>(itemsCount, area.topLeft() + item.topLeft(), itemOffset, LOCPLINT->localState->getOwnedTowns().size()); | ||||
|  | ||||
| 	subwidgetSizes.push_back(area); | ||||
|  | ||||
| 	if(!input["scrollUp"].isNull()) | ||||
| 		result->setScrollUpButton(std::dynamic_pointer_cast<CButton>(buildMapButton(input["scrollUp"]))); | ||||
|  | ||||
| 	if(!input["scrollDown"].isNull()) | ||||
| 		result->setScrollDownButton(std::dynamic_pointer_cast<CButton>(buildMapButton(input["scrollDown"]))); | ||||
|  | ||||
| 	subwidgetSizes.pop_back(); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildMinimap(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	return std::make_shared<CMinimap>(area); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildResourceDateBar(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	std::string image = input["image"].String(); | ||||
|  | ||||
| 	auto result = std::make_shared<CResDataBar>(image, area.topLeft()); | ||||
|  | ||||
| 	for(auto i = 0; i < GameConstants::RESOURCE_QUANTITY; i++) | ||||
| 	{ | ||||
| 		const auto & node = input[GameConstants::RESOURCE_NAMES[i]]; | ||||
|  | ||||
| 		if(node.isNull()) | ||||
| 			continue; | ||||
|  | ||||
| 		result->setResourcePosition(GameResID(i), Point(node["x"].Integer(), node["y"].Integer())); | ||||
| 	} | ||||
|  | ||||
| 	result->setDatePosition(Point(input["date"]["x"].Integer(), input["date"]["y"].Integer())); | ||||
|  | ||||
| 	return result; | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CAdventureMapWidget::buildStatusBar(const JsonNode & input) | ||||
| { | ||||
| 	Rect area = readTargetArea(input["area"]); | ||||
| 	std::string image = input["image"].String(); | ||||
|  | ||||
| 	auto background = std::make_shared<CFilledTexture>(image, area); | ||||
|  | ||||
| 	return CGStatusBar::create(background); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CHeroList> CAdventureMapWidget::getHeroList() | ||||
| { | ||||
| 	return widget<CHeroList>("heroList"); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CTownList> CAdventureMapWidget::getTownList() | ||||
| { | ||||
| 	return widget<CTownList>("townList"); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CMinimap> CAdventureMapWidget::getMinimap() | ||||
| { | ||||
| 	return widget<CMinimap>("minimap"); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<MapView> CAdventureMapWidget::getMapView() | ||||
| { | ||||
| 	return widget<MapView>("mapView"); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CInfoBar> CAdventureMapWidget::getInfoBar() | ||||
| { | ||||
| 	return widget<CInfoBar>("infoBar"); | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setPlayer(const PlayerColor & player) | ||||
| { | ||||
| 	setPlayerChildren(this, player); | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setPlayerChildren(CIntObject * widget, const PlayerColor & player) | ||||
| { | ||||
| 	for(auto & entry : widget->children) | ||||
| 	{ | ||||
| 		auto container = dynamic_cast<CAdventureMapContainerWidget *>(entry); | ||||
| 		auto icon = dynamic_cast<CAdventureMapIcon *>(entry); | ||||
| 		auto button = dynamic_cast<CButton *>(entry); | ||||
|  | ||||
| 		if(button) | ||||
| 			button->setPlayerColor(player); | ||||
|  | ||||
| 		if(icon) | ||||
| 			icon->setPlayer(player); | ||||
|  | ||||
| 		if(container) | ||||
| 			setPlayerChildren(container, player); | ||||
| 	} | ||||
|  | ||||
| 	for(const auto & entry : playerColorerImages) | ||||
| 	{ | ||||
| 		if(images.count(entry)) | ||||
| 			images[entry]->playerColored(player); | ||||
| 	} | ||||
|  | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setState(EGameState newState) | ||||
| { | ||||
| 	state = newState; | ||||
|  | ||||
| 	if(newState == EGameState::WORLD_VIEW) | ||||
| 		widget<CIntObject>("worldViewContainer")->enable(); | ||||
| 	else | ||||
| 		widget<CIntObject>("worldViewContainer")->disable(); | ||||
| } | ||||
|  | ||||
| EGameState CAdventureMapWidget::getState() | ||||
| { | ||||
| 	return state; | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionHasQuests(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionHasUnderground(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionUndergroundLevel(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionHeroSleeping(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionHeroSelected(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionHeroCanMove(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CAdventureMapWidget::setOptionHasNextHero(bool on) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| CAdventureMapIcon::CAdventureMapIcon(const Point & position, std::shared_ptr<CAnimation> animation, size_t index, size_t iconsPerPlayer) | ||||
| 	: index(index) | ||||
| 	, iconsPerPlayer(iconsPerPlayer) | ||||
| { | ||||
| 	OBJ_CONSTRUCTION_CAPTURING_ALL_NO_DISPOSE; | ||||
| 	pos += position; | ||||
| 	image = std::make_shared<CAnimImage>(animation, index); | ||||
| } | ||||
|  | ||||
| void CAdventureMapIcon::setPlayer(const PlayerColor & player) | ||||
| { | ||||
| 	image->setFrame(index + player.getNum() * iconsPerPlayer); | ||||
| } | ||||
							
								
								
									
										105
									
								
								client/adventureMap/CAdventureMapWidget.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								client/adventureMap/CAdventureMapWidget.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,105 @@ | ||||
| /* | ||||
|  * CAdventureMapWidget.h, part of VCMI engine | ||||
|  * | ||||
|  * Authors: listed in file AUTHORS in main folder | ||||
|  * | ||||
|  * License: GNU General Public License v2.0 or later | ||||
|  * Full text of license available in license.txt file, in main folder | ||||
|  * | ||||
|  */ | ||||
| #pragma once | ||||
|  | ||||
| #include "../gui/InterfaceObjectConfigurable.h" | ||||
|  | ||||
| class CHeroList; | ||||
| class CTownList; | ||||
| class CMinimap; | ||||
| class MapView; | ||||
| class CInfoBar; | ||||
| class IImage; | ||||
|  | ||||
| enum class EGameState | ||||
| { | ||||
| 	NOT_INITIALIZED, | ||||
| 	HOTSEAT_WAIT, | ||||
| 	MAKING_TURN, | ||||
| 	ENEMY_TURN, | ||||
| 	CASTING_SPELL, | ||||
| 	WORLD_VIEW | ||||
| }; | ||||
|  | ||||
| /// Internal class of AdventureMapInterface that contains actual UI elements | ||||
| class CAdventureMapWidget : public InterfaceObjectConfigurable | ||||
| { | ||||
| 	EGameState state; | ||||
| 	/// temporary stack of sizes of currently building widgets | ||||
| 	std::vector<Rect> subwidgetSizes; | ||||
|  | ||||
| 	/// list of images on which player-colored palette will be applied | ||||
| 	std::vector<std::string> playerColorerImages; | ||||
|  | ||||
| 	/// list of named images shared between widgets | ||||
| 	std::map<std::string, std::shared_ptr<IImage>> images; | ||||
| 	std::map<std::string, std::shared_ptr<CAnimation>> animations; | ||||
|  | ||||
| 	Rect readTargetArea(const JsonNode & source); | ||||
| 	Rect readSourceArea(const JsonNode & source, const JsonNode & sourceCommon); | ||||
| 	Rect readArea(const JsonNode & source, const Rect & boundingBox); | ||||
|  | ||||
| 	std::shared_ptr<IImage> loadImage(const std::string & name); | ||||
| 	std::shared_ptr<CAnimation> loadAnimation(const std::string & name); | ||||
|  | ||||
| 	std::shared_ptr<CIntObject> buildInfobox(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapImage(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapButton(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapContainer(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapGameArea(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapHeroList(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapIcon(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMapTownList(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildMinimap(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildResourceDateBar(const JsonNode & input); | ||||
| 	std::shared_ptr<CIntObject> buildStatusBar(const JsonNode & input); | ||||
|  | ||||
| 	void setPlayerChildren(CIntObject * widget, const PlayerColor & player); | ||||
| public: | ||||
| 	CAdventureMapWidget(); | ||||
|  | ||||
| 	std::shared_ptr<CHeroList> getHeroList(); | ||||
| 	std::shared_ptr<CTownList> getTownList(); | ||||
| 	std::shared_ptr<CMinimap> getMinimap(); | ||||
| 	std::shared_ptr<MapView> getMapView(); | ||||
| 	std::shared_ptr<CInfoBar> getInfoBar(); | ||||
|  | ||||
| 	void setPlayer(const PlayerColor & player); | ||||
| 	void setState(EGameState newState); | ||||
| 	EGameState getState(); | ||||
|  | ||||
| 	void setOptionHasQuests(bool on); | ||||
| 	void setOptionHasUnderground(bool on); | ||||
| 	void setOptionUndergroundLevel(bool on); | ||||
| 	void setOptionHeroSleeping(bool on); | ||||
| 	void setOptionHeroSelected(bool on); | ||||
| 	void setOptionHeroCanMove(bool on); | ||||
| 	void setOptionHasNextHero(bool on); | ||||
| }; | ||||
|  | ||||
| /// Small helper class that provides ownership for shared_ptr's of child elements | ||||
| class CAdventureMapContainerWidget : public CIntObject | ||||
| { | ||||
| 	friend class CAdventureMapWidget; | ||||
| 	std::vector<std::shared_ptr<CIntObject>> ownedChildren; | ||||
| }; | ||||
|  | ||||
| /// Small helper class that provides player-colorable icon using animation file | ||||
| class CAdventureMapIcon : public CIntObject | ||||
| { | ||||
| 	std::shared_ptr<CAnimImage> image; | ||||
|  | ||||
| 	size_t index; | ||||
| 	size_t iconsPerPlayer; | ||||
| public: | ||||
| 	CAdventureMapIcon(const Point & position, std::shared_ptr<CAnimation> image, size_t index, size_t iconsPerPlayer); | ||||
|  | ||||
| 	void setPlayer(const PlayerColor & player); | ||||
| }; | ||||
| @@ -83,7 +83,7 @@ void CInGameConsole::print(const std::string & txt) | ||||
| 	// boost::unique_lock scope | ||||
| 	{ | ||||
| 		boost::unique_lock<boost::mutex> lock(texts_mx); | ||||
| 		int lineLen = conf.go()->ac.outputLineLength; | ||||
| 		int lineLen = 60; //FIXME: CONFIGURABLE ADVMAP | ||||
|  | ||||
| 		if(txt.size() < lineLen) | ||||
| 		{ | ||||
|   | ||||
| @@ -81,24 +81,33 @@ void CList::CListItem::onSelect(bool on) | ||||
| 	redraw(); | ||||
| } | ||||
|  | ||||
| CList::CList(int Size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, int helpUp, int helpDown, CListBox::CreateFunc create) | ||||
| CList::CList(int Size, Point position) | ||||
| 	: CIntObject(0, position), | ||||
| 	size(Size), | ||||
| 	selected(nullptr) | ||||
| { | ||||
|  | ||||
| } | ||||
|  | ||||
| void CList::createList(Point itemOffset, size_t listAmount) | ||||
| { | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||
| 	scrollUp = std::make_shared<CButton>(Point(0, 0), btnUp, CGI->generaltexth->zelp[helpUp]); | ||||
| 	scrollDown = std::make_shared<CButton>(Point(0, scrollUp->pos.h + 32*(int)size), btnDown, CGI->generaltexth->zelp[helpDown]); | ||||
| 	listBox = std::make_shared<CListBox>(std::bind(&CList::createItem, this, _1), Point(0, 0), itemOffset, size, listAmount); | ||||
| } | ||||
|  | ||||
| 	listBox = std::make_shared<CListBox>(create, Point(1,scrollUp->pos.h), Point(0, 32), size, listAmount); | ||||
|  | ||||
| 	//assign callback only after list was created | ||||
| void CList::setScrollUpButton(std::shared_ptr<CButton> button) | ||||
| { | ||||
| 	scrollUp = button; | ||||
| 	scrollUp->addCallback(std::bind(&CListBox::moveToPrev, listBox)); | ||||
| 	scrollDown->addCallback(std::bind(&CListBox::moveToNext, listBox)); | ||||
|  | ||||
| 	scrollUp->addCallback(std::bind(&CList::update, this)); | ||||
| 	scrollDown->addCallback(std::bind(&CList::update, this)); | ||||
| 	update(); | ||||
| } | ||||
|  | ||||
| void CList::setScrollDownButton(std::shared_ptr<CButton> button) | ||||
| { | ||||
| 	scrollDown = button; | ||||
| 	scrollDown->addCallback(std::bind(&CList::update, this)); | ||||
| 	scrollDown->addCallback(std::bind(&CListBox::moveToNext, listBox)); | ||||
| 	update(); | ||||
| } | ||||
|  | ||||
| @@ -107,8 +116,11 @@ void CList::update() | ||||
| 	bool onTop = listBox->getPos() == 0; | ||||
| 	bool onBottom = listBox->getPos() + size >= listBox->size(); | ||||
|  | ||||
| 	scrollUp->block(onTop); | ||||
| 	scrollDown->block(onBottom); | ||||
| 	if (scrollUp) | ||||
| 		scrollUp->block(onTop); | ||||
|  | ||||
| 	if (scrollDown) | ||||
| 		scrollDown->block(onBottom); | ||||
| } | ||||
|  | ||||
| void CList::select(std::shared_ptr<CListItem> which) | ||||
| @@ -223,16 +235,17 @@ std::string CHeroList::CHeroItem::getHoverText() | ||||
| 	return boost::str(boost::format(CGI->generaltexth->allTexts[15]) % hero->getNameTranslated() % hero->type->heroClass->getNameTranslated()); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CHeroList::createHeroItem(size_t index) | ||||
| std::shared_ptr<CIntObject> CHeroList::createItem(size_t index) | ||||
| { | ||||
| 	if (LOCPLINT->localState->getWanderingHeroes().size() > index) | ||||
| 		return std::make_shared<CHeroItem>(this, LOCPLINT->localState->getWanderingHero(index)); | ||||
| 	return std::make_shared<CEmptyHeroItem>(); | ||||
| } | ||||
|  | ||||
| CHeroList::CHeroList(int size, Point position, std::string btnUp, std::string btnDown): | ||||
| 	CList(size, position, btnUp, btnDown, LOCPLINT->localState->getWanderingHeroes().size(), 303, 304, std::bind(&CHeroList::createHeroItem, this, _1)) | ||||
| CHeroList::CHeroList(int size, Point position, Point itemOffset, size_t listAmount) | ||||
| 	: CList(size, position) | ||||
| { | ||||
| 	createList(itemOffset, listAmount); | ||||
| } | ||||
|  | ||||
| void CHeroList::select(const CGHeroInstance * hero) | ||||
| @@ -261,7 +274,7 @@ void CHeroList::update(const CGHeroInstance * hero) | ||||
| 	CList::update(); | ||||
| } | ||||
|  | ||||
| std::shared_ptr<CIntObject> CTownList::createTownItem(size_t index) | ||||
| std::shared_ptr<CIntObject> CTownList::createItem(size_t index) | ||||
| { | ||||
| 	if (LOCPLINT->localState->getOwnedTowns().size() > index) | ||||
| 		return std::make_shared<CTownItem>(this, LOCPLINT->localState->getOwnedTown(index)); | ||||
| @@ -312,9 +325,10 @@ std::string CTownList::CTownItem::getHoverText() | ||||
| 	return town->getObjectName(); | ||||
| } | ||||
|  | ||||
| CTownList::CTownList(int size, Point position, std::string btnUp, std::string btnDown): | ||||
| 	CList(size, position, btnUp, btnDown, LOCPLINT->localState->getOwnedTowns().size(),  306, 307, std::bind(&CTownList::createTownItem, this, _1)) | ||||
| CTownList::CTownList(int size, Point position, Point itemOffset, size_t listAmount) | ||||
| 	: CList(size, position) | ||||
| { | ||||
| 	createList(itemOffset, listAmount); | ||||
| } | ||||
|  | ||||
| void CTownList::select(const CGTownInstance * town) | ||||
|   | ||||
| @@ -53,23 +53,9 @@ protected: | ||||
| 		virtual std::string getHoverText()=0; | ||||
| 	}; | ||||
|  | ||||
| 	std::shared_ptr<CListBox> listBox; | ||||
| private: | ||||
| 	const size_t size; | ||||
|  | ||||
| 	/** | ||||
| 	 * @brief CList - protected constructor | ||||
| 	 * @param size - maximal amount of visible at once items | ||||
| 	 * @param position - cordinates | ||||
| 	 * @param btnUp - path to image to use as top button | ||||
| 	 * @param btnDown - path to image to use as bottom button | ||||
| 	 * @param listAmount - amount of items in the list | ||||
| 	 * @param helpUp - index in zelp.txt for button help tooltip | ||||
| 	 * @param helpDown - index in zelp.txt for button help tooltip | ||||
| 	 * @param create - function for creating items in listbox | ||||
| 	 * @param destroy - function for deleting items in listbox | ||||
| 	 */ | ||||
| 	CList(int size, Point position, std::string btnUp, std::string btnDown, size_t listAmount, int helpUp, int helpDown, CListBox::CreateFunc create); | ||||
|  | ||||
| 	//for selection\deselection | ||||
| 	std::shared_ptr<CListItem> selected; | ||||
| 	void select(std::shared_ptr<CListItem> which); | ||||
| @@ -78,8 +64,14 @@ protected: | ||||
| 	std::shared_ptr<CButton> scrollUp; | ||||
| 	std::shared_ptr<CButton> scrollDown; | ||||
|  | ||||
| 	/// should be called when list is invalidated | ||||
| 	void update(); | ||||
| protected: | ||||
| 	std::shared_ptr<CListBox> listBox; | ||||
|  | ||||
| 	CList(int size, Point position); | ||||
|  | ||||
| 	void createList(Point itemOffset, size_t listAmount); | ||||
|  | ||||
| 	virtual std::shared_ptr<CIntObject> createItem(size_t index) = 0; | ||||
|  | ||||
| public: | ||||
| 	/// functions that will be called when selection changes | ||||
| @@ -88,6 +80,12 @@ public: | ||||
| 	/// return index of currently selected element | ||||
| 	int getSelectedIndex(); | ||||
|  | ||||
| 	void setScrollUpButton(std::shared_ptr<CButton> button); | ||||
| 	void setScrollDownButton(std::shared_ptr<CButton> button); | ||||
|  | ||||
| 	/// should be called when list is invalidated | ||||
| 	void update(); | ||||
|  | ||||
| 	/// set of methods to switch selection | ||||
| 	void selectIndex(int which); | ||||
| 	void selectNext(); | ||||
| @@ -125,13 +123,9 @@ class CHeroList	: public CList | ||||
| 		std::string getHoverText() override; | ||||
| 	}; | ||||
|  | ||||
| 	std::shared_ptr<CIntObject> createHeroItem(size_t index); | ||||
| 	std::shared_ptr<CIntObject> createItem(size_t index); | ||||
| public: | ||||
| 	/** | ||||
| 	 * @brief CHeroList | ||||
| 	 * @param size, position, btnUp, btnDown @see CList::CList | ||||
| 	 */ | ||||
| 	CHeroList(int size, Point position, std::string btnUp, std::string btnDown); | ||||
| 	CHeroList(int size, Point position, Point itemOffset, size_t listAmount); | ||||
|  | ||||
| 	/// Select specific hero and scroll if needed | ||||
| 	void select(const CGHeroInstance * hero = nullptr); | ||||
| @@ -159,13 +153,9 @@ class CTownList	: public CList | ||||
| 		std::string getHoverText() override; | ||||
| 	}; | ||||
|  | ||||
| 	std::shared_ptr<CIntObject> createTownItem(size_t index); | ||||
| 	std::shared_ptr<CIntObject> createItem(size_t index) override; | ||||
| public: | ||||
| 	/** | ||||
| 	 * @brief CTownList | ||||
| 	 * @param size, position, btnUp, btnDown @see CList::CList | ||||
| 	 */ | ||||
| 	CTownList(int size, Point position, std::string btnUp, std::string btnDown); | ||||
| 	CTownList(int size, Point position, Point itemOffset, size_t listAmount); | ||||
|  | ||||
| 	/// Select specific town and scroll if needed | ||||
| 	void select(const CGTownInstance * town = nullptr); | ||||
|   | ||||
| @@ -19,50 +19,40 @@ | ||||
| #include "../../CCallback.h" | ||||
| #include "../../lib/CConfigHandler.h" | ||||
| #include "../../lib/CGeneralTextHandler.h" | ||||
| #include "../../lib/ResourceSet.h" | ||||
|  | ||||
| #define ADVOPT (conf.go()->ac) | ||||
|  | ||||
| CResDataBar::CResDataBar(const std::string & defname, int x, int y, int offx, int offy, int resdist, int datedist) | ||||
| CResDataBar::CResDataBar(const std::string & imageName, const Point & position) | ||||
| { | ||||
| 	pos.x += x; | ||||
| 	pos.y += y; | ||||
| 	pos.x += position.x; | ||||
| 	pos.y += position.y; | ||||
|  | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||
| 	background = std::make_shared<CPicture>(defname, 0, 0); | ||||
| 	background = std::make_shared<CPicture>(imageName, 0, 0); | ||||
| 	background->colorize(LOCPLINT->playerID); | ||||
|  | ||||
| 	pos.w = background->pos.w; | ||||
| 	pos.h = background->pos.h; | ||||
|  | ||||
| 	txtpos.resize(8); | ||||
| 	for (int i = 0; i < 8 ; i++) | ||||
| 	{ | ||||
| 		txtpos[i].first = pos.x + offx + resdist*i; | ||||
| 		txtpos[i].second = pos.y + offy; | ||||
| 	} | ||||
| 	txtpos[7].first = txtpos[6].first + datedist; | ||||
| 	addUsedEvents(RCLICK); | ||||
| } | ||||
|  | ||||
| CResDataBar::CResDataBar() | ||||
| CResDataBar::CResDataBar(const std::string & defname, int x, int y, int offx, int offy, int resdist, int datedist): | ||||
| 	CResDataBar(defname, Point(x,y)) | ||||
| { | ||||
| 	pos.x += ADVOPT.resdatabarX; | ||||
| 	pos.y += ADVOPT.resdatabarY; | ||||
| 	for (int i = 0; i < 7 ; i++) | ||||
| 		resourcePositions[GameResID(i)] = Point( offx + resdist*i, offy ); | ||||
|  | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||
| 	background = std::make_shared<CPicture>(ADVOPT.resdatabarG, 0, 0); | ||||
| 	background->colorize(LOCPLINT->playerID); | ||||
| 	datePosition = resourcePositions[EGameResID::GOLD] + Point(datedist, 0); | ||||
| } | ||||
|  | ||||
| 	pos.w = background->pos.w; | ||||
| 	pos.h = background->pos.h; | ||||
|  | ||||
| 	txtpos.resize(8); | ||||
| 	for (int i = 0; i < 8 ; i++) | ||||
| 	{ | ||||
| 		txtpos[i].first = pos.x + ADVOPT.resOffsetX + ADVOPT.resDist*i; | ||||
| 		txtpos[i].second = pos.y + ADVOPT.resOffsetY; | ||||
| 	} | ||||
| 	txtpos[7].first = txtpos[6].first + ADVOPT.resDateDist; | ||||
| void CResDataBar::setDatePosition(const Point & position) | ||||
| { | ||||
| 	datePosition = position; | ||||
| } | ||||
|  | ||||
| void CResDataBar::setResourcePosition(const GameResID & resource, const Point & position) | ||||
| { | ||||
| 	resourcePositions[resource] = position; | ||||
| } | ||||
|  | ||||
| std::string CResDataBar::buildDateString() | ||||
| @@ -80,13 +70,15 @@ std::string CResDataBar::buildDateString() | ||||
| void CResDataBar::draw(SDL_Surface * to) | ||||
| { | ||||
| 	//TODO: all this should be labels, but they require proper text update on change | ||||
| 	for (GameResID i=EGameResID::WOOD; i <= GameResID(EGameResID::GOLD); ++i) | ||||
| 	for (auto & entry : resourcePositions) | ||||
| 	{ | ||||
| 		std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(i)); | ||||
| 		std::string text = std::to_string(LOCPLINT->cb->getResourceAmount(entry.first)); | ||||
|  | ||||
| 		graphics->fonts[FONT_SMALL]->renderTextLeft(to, text, Colors::WHITE, Point(txtpos[i].first, txtpos[i].second)); | ||||
| 		graphics->fonts[FONT_SMALL]->renderTextLeft(to, text, Colors::WHITE, pos.topLeft() + entry.second); | ||||
| 	} | ||||
| 	graphics->fonts[FONT_SMALL]->renderTextLeft(to, buildDateString(), Colors::WHITE, Point(txtpos[7].first, txtpos[7].second)); | ||||
|  | ||||
| 	if (datePosition) | ||||
| 		graphics->fonts[FONT_SMALL]->renderTextLeft(to, buildDateString(), Colors::WHITE, pos.topLeft() + *datePosition); | ||||
| } | ||||
|  | ||||
| void CResDataBar::showAll(SDL_Surface * to) | ||||
|   | ||||
| @@ -11,6 +11,9 @@ | ||||
|  | ||||
| #include "../gui/CIntObject.h" | ||||
|  | ||||
| enum class EGameResID : int8_t; | ||||
| using GameResID = Identifier<EGameResID>; | ||||
|  | ||||
| /// Resources bar which shows information about how many gold, crystals,... you have | ||||
| /// Current date is displayed too | ||||
| class CResDataBar : public CIntObject | ||||
| @@ -19,14 +22,21 @@ class CResDataBar : public CIntObject | ||||
|  | ||||
| 	std::shared_ptr<CPicture> background; | ||||
|  | ||||
| 	std::vector<std::pair<int,int> > txtpos; | ||||
|  | ||||
| 	std::map<GameResID, Point> resourcePositions; | ||||
| 	std::optional<Point> datePosition; | ||||
|  | ||||
| 	void draw(SDL_Surface * to); | ||||
| public: | ||||
| 	CResDataBar(); | ||||
|  | ||||
| 	/// For dynamically-sized UI windows, e.g. adventure map interface | ||||
| 	CResDataBar(const std::string & imageName, const Point & position); | ||||
|  | ||||
| 	/// For fixed-size UI windows, e.g. CastleInterface | ||||
| 	CResDataBar(const std::string &defname, int x, int y, int offx, int offy, int resdist, int datedist); | ||||
|  | ||||
| 	void setDatePosition(const Point & position); | ||||
| 	void setResourcePosition(const GameResID & resource, const Point & position); | ||||
|  | ||||
| 	void colorize(PlayerColor player); | ||||
| 	void showAll(SDL_Surface * to) override; | ||||
| }; | ||||
|   | ||||
| @@ -174,6 +174,8 @@ EFonts InterfaceObjectConfigurable::readFont(const JsonNode & config) const | ||||
| 			return EFonts::FONT_SMALL; | ||||
| 		if(config.String() == "tiny") | ||||
| 			return EFonts::FONT_TINY; | ||||
| 		if(config.String() == "calisto") | ||||
| 			return EFonts::FONT_CALLI; | ||||
| 	} | ||||
| 	logGlobal->debug("Uknown font attribute"); | ||||
| 	return EFonts::FONT_TIMES; | ||||
|   | ||||
| @@ -16,13 +16,7 @@ | ||||
| #include <SDL_pixels.h> | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| namespace config | ||||
| { | ||||
| struct ButtonInfo; | ||||
| } | ||||
| class Rect; | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
|  | ||||
| struct SDL_Surface; | ||||
|   | ||||
| @@ -109,6 +109,16 @@ void CPicture::colorize(PlayerColor player) | ||||
| CFilledTexture::CFilledTexture(std::string imageName, Rect position): | ||||
|     CIntObject(0, position.topLeft()), | ||||
| 	texture(IImage::createFromFile(imageName)) | ||||
| { | ||||
| 	pos.w = position.w; | ||||
| 	pos.h = position.h; | ||||
| 	imageArea = Rect(Point(), texture->dimensions()); | ||||
| } | ||||
|  | ||||
| CFilledTexture::CFilledTexture(std::shared_ptr<IImage> image, Rect position, Rect imageArea) | ||||
| 	: CIntObject(0, position.topLeft()) | ||||
| 	, texture(image) | ||||
| 	, imageArea(imageArea) | ||||
| { | ||||
| 	pos.w = position.w; | ||||
| 	pos.h = position.h; | ||||
| @@ -121,7 +131,7 @@ void CFilledTexture::showAll(SDL_Surface *to) | ||||
| 	for (int y=pos.top(); y < pos.bottom(); y+= texture->height()) | ||||
| 	{ | ||||
| 		for (int x=pos.left(); x < pos.right(); x+=texture->width()) | ||||
| 			texture->draw(to, x, y); | ||||
| 			texture->draw(to, x, y, &imageArea); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -69,9 +69,11 @@ public: | ||||
| class CFilledTexture : public CIntObject | ||||
| { | ||||
| 	std::shared_ptr<IImage> texture; | ||||
| 	Rect imageArea; | ||||
|  | ||||
| public: | ||||
| 	CFilledTexture(std::string imageName, Rect position); | ||||
| 	CFilledTexture(std::shared_ptr<IImage> image, Rect position, Rect imageArea); | ||||
|  | ||||
| 	void showAll(SDL_Surface *to) override; | ||||
| }; | ||||
|   | ||||
| @@ -399,7 +399,7 @@ void CGStatusBar::clear() | ||||
| 	write({}); | ||||
| } | ||||
|  | ||||
| CGStatusBar::CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font, ETextAlignment Align, const SDL_Color & Color) | ||||
| CGStatusBar::CGStatusBar(std::shared_ptr<CIntObject> background_, EFonts Font, ETextAlignment Align, const SDL_Color & Color) | ||||
| 	: CLabel(background_->pos.x, background_->pos.y, Font, Align, Color, "") | ||||
| 	, enteringText(false) | ||||
| { | ||||
| @@ -419,14 +419,15 @@ CGStatusBar::CGStatusBar(int x, int y, std::string name, int maxw) | ||||
| 	addUsedEvents(LCLICK); | ||||
|  | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255 - DISPOSE); | ||||
| 	background = std::make_shared<CPicture>(name); | ||||
| 	auto backgroundImage = std::make_shared<CPicture>(name); | ||||
| 	background = backgroundImage; | ||||
| 	pos = background->pos; | ||||
|  | ||||
| 	if((unsigned)maxw < (unsigned)pos.w) //(insigned)-1 > than any correct value of pos.w | ||||
| 	{ | ||||
| 		//execution of this block when maxw is incorrect breaks text centralization (issue #3151) | ||||
| 		vstd::amin(pos.w, maxw); | ||||
| 		background->srcRect = Rect(0, 0, maxw, pos.h); | ||||
| 		backgroundImage->srcRect = Rect(0, 0, maxw, pos.h); | ||||
| 	} | ||||
| 	autoRedraw = false; | ||||
| } | ||||
|   | ||||
| @@ -45,7 +45,7 @@ protected: | ||||
| 	Point getBorderSize() override; | ||||
| 	virtual std::string visibleText(); | ||||
|  | ||||
| 	std::shared_ptr<CPicture> background; | ||||
| 	std::shared_ptr<CIntObject> background; | ||||
| 	std::string text; | ||||
| 	bool autoRedraw;  //whether control will redraw itself on setTxt | ||||
|  | ||||
| @@ -127,7 +127,7 @@ class CGStatusBar : public CLabel, public std::enable_shared_from_this<CGStatusB | ||||
|  | ||||
| 	void init(); | ||||
|  | ||||
| 	CGStatusBar(std::shared_ptr<CPicture> background_, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::CENTER, const SDL_Color & Color = Colors::WHITE); | ||||
| 	CGStatusBar(std::shared_ptr<CIntObject> background_, EFonts Font = FONT_SMALL, ETextAlignment Align = ETextAlignment::CENTER, const SDL_Color & Color = Colors::WHITE); | ||||
| 	CGStatusBar(int x, int y, std::string name, int maxw = -1); | ||||
|  | ||||
| 	//make CLabel API private | ||||
|   | ||||
| @@ -1200,7 +1200,10 @@ CCastleInterface::CCastleInterface(const CGTownInstance * Town, const CGTownInst | ||||
| 	statusbar = CGStatusBar::create(statusbarBackground); | ||||
| 	resdatabar = std::make_shared<CResDataBar>("ARESBAR", 3, 575, 32, 2, 85, 85); | ||||
|  | ||||
| 	townlist = std::make_shared<CTownList>(3, Point(744, 414), "IAM014", "IAM015"); | ||||
| 	townlist = std::make_shared<CTownList>(3, Point(745, 430), Point(0, 32), LOCPLINT->localState->getOwnedTowns().size() ); | ||||
| 	townlist->setScrollUpButton( std::make_shared<CButton>( Point(744, 414), "IAM014", CButton::tooltipLocalized("core.help.306"))); | ||||
| 	townlist->setScrollDownButton( std::make_shared<CButton>( Point(744, 526), "IAM015", CButton::tooltipLocalized("core.help.307"))); | ||||
|  | ||||
| 	if(from) | ||||
| 		townlist->select(from); | ||||
|  | ||||
|   | ||||
| @@ -39,6 +39,9 @@ | ||||
| #include "../../lib/mapObjects/CGTownInstance.h" | ||||
| #include "../../lib/mapObjects/MiscObjects.h" | ||||
|  | ||||
| static const std::string OVERVIEW_BACKGROUND = "OvCast.pcx"; | ||||
| static const size_t OVERVIEW_SIZE = 4; | ||||
|  | ||||
| InfoBox::InfoBox(Point position, InfoPos Pos, InfoSize Size, std::shared_ptr<IInfoBoxData> Data): | ||||
| 	size(Size), | ||||
| 	infoPos(Pos), | ||||
| @@ -468,10 +471,10 @@ void InfoBoxCustom::prepareMessage(std::string & text, std::shared_ptr<CComponen | ||||
| } | ||||
|  | ||||
| CKingdomInterface::CKingdomInterface() | ||||
| 	: CWindowObject(PLAYER_COLORED | BORDERED, conf.go()->ac.overviewBg) | ||||
| 	: CWindowObject(PLAYER_COLORED | BORDERED, OVERVIEW_BACKGROUND) | ||||
| { | ||||
| 	OBJECT_CONSTRUCTION_CAPTURING(255-DISPOSE); | ||||
| 	ui32 footerPos = conf.go()->ac.overviewSize * 116; | ||||
| 	ui32 footerPos = OVERVIEW_SIZE * 116; | ||||
|  | ||||
| 	tabArea = std::make_shared<CTabbedInt>(std::bind(&CKingdomInterface::createMainTab, this, _1), Point(4,4)); | ||||
|  | ||||
| @@ -486,7 +489,7 @@ CKingdomInterface::CKingdomInterface() | ||||
|  | ||||
| void CKingdomInterface::generateObjectsList(const std::vector<const CGObjectInstance * > &ownedObjects) | ||||
| { | ||||
| 	ui32 footerPos = conf.go()->ac.overviewSize * 116; | ||||
| 	ui32 footerPos = OVERVIEW_SIZE * 116; | ||||
| 	size_t dwellSize = (footerPos - 64)/57; | ||||
|  | ||||
| 	//Map used to determine image number for several objects | ||||
| @@ -550,7 +553,7 @@ std::shared_ptr<CIntObject> CKingdomInterface::createOwnedObject(size_t index) | ||||
|  | ||||
| std::shared_ptr<CIntObject> CKingdomInterface::createMainTab(size_t index) | ||||
| { | ||||
| 	size_t size = conf.go()->ac.overviewSize; | ||||
| 	size_t size = OVERVIEW_SIZE; | ||||
| 	switch(index) | ||||
| 	{ | ||||
| 	case 0: | ||||
| @@ -564,7 +567,7 @@ std::shared_ptr<CIntObject> CKingdomInterface::createMainTab(size_t index) | ||||
|  | ||||
| void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstance *> & ownedObjects) | ||||
| { | ||||
| 	ui32 footerPos = conf.go()->ac.overviewSize * 116; | ||||
| 	ui32 footerPos = OVERVIEW_SIZE * 116; | ||||
| 	TResources minesCount(GameConstants::RESOURCE_QUANTITY, 0); | ||||
| 	int totalIncome=0; | ||||
|  | ||||
| @@ -610,7 +613,7 @@ void CKingdomInterface::generateMinesList(const std::vector<const CGObjectInstan | ||||
|  | ||||
| void CKingdomInterface::generateButtons() | ||||
| { | ||||
| 	ui32 footerPos = conf.go()->ac.overviewSize * 116; | ||||
| 	ui32 footerPos = OVERVIEW_SIZE * 116; | ||||
|  | ||||
| 	//Main control buttons | ||||
| 	btnHeroes = std::make_shared<CButton>(Point(748, 28+footerPos), "OVBUTN1.DEF", CButton::tooltip(CGI->generaltexth->overview[11], CGI->generaltexth->overview[6]), | ||||
| @@ -689,7 +692,7 @@ CKingdHeroList::CKingdHeroList(size_t maxSize) | ||||
| 	skillsLabel = std::make_shared<CLabel>(500, 10, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[1]); | ||||
|  | ||||
| 	ui32 townCount = LOCPLINT->cb->howManyHeroes(false); | ||||
| 	ui32 size = conf.go()->ac.overviewSize*116 + 19; | ||||
| 	ui32 size = OVERVIEW_SIZE*116 + 19; | ||||
| 	heroes = std::make_shared<CListBox>(std::bind(&CKingdHeroList::createHeroItem, this, _1), | ||||
| 		Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size)); | ||||
| } | ||||
| @@ -705,7 +708,7 @@ void CKingdHeroList::updateGarrisons() | ||||
|  | ||||
| std::shared_ptr<CIntObject> CKingdHeroList::createHeroItem(size_t index) | ||||
| { | ||||
| 	ui32 picCount = conf.go()->ac.overviewPics; | ||||
| 	ui32 picCount = 4; // OVSLOT contains 4 images | ||||
| 	size_t heroesCount = LOCPLINT->cb->howManyHeroes(false); | ||||
|  | ||||
| 	if(index < heroesCount) | ||||
| @@ -730,7 +733,7 @@ CKingdTownList::CKingdTownList(size_t maxSize) | ||||
| 	visitHeroLabel = std::make_shared<CLabel>(608, 10, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, CGI->generaltexth->overview[5]); | ||||
|  | ||||
| 	ui32 townCount = LOCPLINT->cb->howManyTowns(); | ||||
| 	ui32 size = conf.go()->ac.overviewSize*116 + 19; | ||||
| 	ui32 size = OVERVIEW_SIZE*116 + 19; | ||||
| 	towns = std::make_shared<CListBox>(std::bind(&CKingdTownList::createTownItem, this, _1), | ||||
| 		Point(19,21), Point(0,116), maxSize, townCount, 0, 1, Rect(-19, -21, size, size)); | ||||
| } | ||||
| @@ -756,7 +759,7 @@ void CKingdTownList::updateGarrisons() | ||||
|  | ||||
| std::shared_ptr<CIntObject> CKingdTownList::createTownItem(size_t index) | ||||
| { | ||||
| 	ui32 picCount = conf.go()->ac.overviewPics; | ||||
| 	ui32 picCount = 4; // OVSLOT contains 4 images | ||||
| 	size_t townsCount = LOCPLINT->cb->howManyTowns(); | ||||
|  | ||||
| 	if(index < townsCount) | ||||
|   | ||||
| @@ -243,10 +243,13 @@ void GeneralOptionsTab::fillSelectableResolutions() | ||||
| { | ||||
| 	selectableResolutions.clear(); | ||||
|  | ||||
| 	for(const auto & it : conf.guiOptions) | ||||
| 	{ | ||||
| 		const Point dimensions(it.first.first, it.first.second); | ||||
| 	// TODO: CONFIGURABLE ADVMAP | ||||
| 	static const std::vector<Point> supportedResolutions = { | ||||
| 		{ 800, 600 } | ||||
| 	}; | ||||
|  | ||||
| 	for(const auto & dimensions : supportedResolutions) | ||||
| 	{ | ||||
| 		if(isResolutionSupported(dimensions)) | ||||
| 			selectableResolutions.push_back(dimensions); | ||||
| 	} | ||||
|   | ||||
| @@ -1,33 +0,0 @@ | ||||
| { | ||||
| 	"GUISettings": | ||||
| 	[ | ||||
| 		{ | ||||
| 			"resolution": { "x": 800, "y": 600 }, | ||||
| 			"InGameConsole": { "maxInputPerLine": 60, "maxOutputPerLine": 60 }, | ||||
| 			"AdvMap": { "x": 7, "y": 7, "width": 594, "height": 546, "smoothMove": 1, "puzzleSepia": 1, "objectFading" : 1, "screenFading" : 1 }, | ||||
| 			"InfoBox": { "x": 605, "y": 389 }, | ||||
| 			"gem0": { "x": 6, "y": 508, "graphic": "agemLL.def" }, | ||||
| 			"gem1": { "x": 556, "y": 508, "graphic": "agemLR.def" }, | ||||
| 			"gem2": { "x": 6, "y": 6, "graphic": "agemUL.def" }, | ||||
| 			"gem3": { "x": 556, "y": 6, "graphic": "agemUR.def" }, | ||||
| 			"background": "AdvMap.bmp", | ||||
| 			"backgroundWorldView": "VWorld.bmp", | ||||
| 			"HeroList": { "size": 5, "x": 609, "y": 196, "movePoints": "IMOBIL.DEF", "manaPoints": "IMANA.DEF", "arrowUp": "IAM012.DEF", "arrowDown": "IAM013.DEF" }, | ||||
| 			"TownList": { "size": 5, "x": 747, "y": 196, "arrowUp": "IAM014.DEF", "arrowDown": "IAM015.DEF" }, | ||||
| 			"Minimap": { "width": 144, "height": 144, "x": 630, "y": 26 }, | ||||
| 			"Overview": { "pics": 4, "size": 4, "graphic": "OvCast.pcx" }, | ||||
| 			"Statusbar": { "x": 7, "y": 556, "graphic": "AdRollvr.bmp" }, | ||||
| 			"ResDataBar": { "x": 3, "y": 575, "graphic": "ARESBAR.bmp", "offsetX": 32, "offsetY": 2, "resSpace": 85, "resDateSpace": 85 }, | ||||
| 			"ButtonKingdomOv": { "x": 679, "y": 196, "graphic": "IAM002.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonUnderground": { "x": 711, "y": 196, "graphic": "IAM010.DEF", "playerColoured": 1, "additionalDefs": [ "IAM003.DEF" ] }, | ||||
| 			"ButtonQuestLog": { "x": 679, "y": 228, "graphic": "IAM004.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonSleepWake": { "x": 711, "y": 228, "graphic": "IAM005.DEF", "playerColoured": 1, "additionalDefs":["IAM011.DEF"] }, | ||||
| 			"ButtonMoveHero": { "x": 679, "y": 260, "graphic": "IAM006.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonSpellbook": { "x": 711, "y": 260, "graphic": "IAM007.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonAdvOptions": { "x": 679, "y": 292, "graphic": "IAM008.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonSysOptions": { "x": 711, "y": 292, "graphic": "IAM009.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonNextHero": { "x": 679, "y": 324, "graphic": "IAM000.DEF", "playerColoured": 1 }, | ||||
| 			"ButtonEndTurn": { "x": 679, "y": 356, "graphic": "IAM001.DEF", "playerColoured": 1 } | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
							
								
								
									
										612
									
								
								config/widgets/adventureMap.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										612
									
								
								config/widgets/adventureMap.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,612 @@ | ||||
| { | ||||
| 	"options" : { | ||||
|  | ||||
| 		// player-colored images used for background | ||||
| 		"imagesPlayerColored" : [ "AdvMap.pcx" ], | ||||
|  | ||||
| 		// widgets that are only visible in world view mode | ||||
| 		"worldViewWidgets" : [ "worldViewContainer" ], | ||||
| 		 | ||||
| 		// widgets that are only visible in game view mode | ||||
| 		"gameViewWidgets" : [ "townListContainer", "heroListContainer", "buttonsContainer", "infobox" ], | ||||
| 		 | ||||
| 		// widgets that should be drawn on top of game area | ||||
| 		// NOTE: semi-transparency is not supported, only fully transparent/fully opaque | ||||
| 		"overlayWidgets" : [ "gemTopLeft", "gemTopRight", "gemBottomLeft", "gemBottomRight" ] | ||||
| 	}, | ||||
|  | ||||
| 	"items": | ||||
| 	[ | ||||
| 		// GEMS - set of images with different image for each player | ||||
| 		{ | ||||
| 			"type": "adventureMapIcon", | ||||
| 			"name" : "gemTopLeft", | ||||
| 			"image" : "agemUL.def", | ||||
| 			"index" : 0, | ||||
| 			"perPlayer" : 1, | ||||
| 			"area" : { "left": 7, "top" : 7, "width" : 46, "height" : 46 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapIcon", | ||||
| 			"name" : "gemTopRight", | ||||
| 			"image" : "agemUR.def", | ||||
| 			"index" : 0, | ||||
| 			"perPlayer" : 1, | ||||
| 			"area" : { "right": 198, "top" : 7, "width" : 46, "height" : 46 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapIcon", | ||||
| 			"name" : "gemBottomLeft", | ||||
| 			"image" : "agemLL.def", | ||||
| 			"index" : 0, | ||||
| 			"perPlayer" : 1, | ||||
| 			"area" : { "left": 7, "bottom" : 46, "width" : 46, "height" : 46 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapIcon", | ||||
| 			"name" : "gemBottomRight", | ||||
| 			"image" : "agemLR.def", | ||||
| 			"index" : 0, | ||||
| 			"perPlayer" : 1, | ||||
| 			"area" : { "right": 198, "bottom" : 46, "width" : 46, "height" : 46 } | ||||
| 		}, | ||||
|  | ||||
| 		// Background sections | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name" : "backgroundTopLeft", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area" : { "left": 0, "top" : 0, "width" : 7, "height" : 7 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name" : "backgroundBottomLeft", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area" : { "left": 0, "bottom" : 0, "width" : 7, "height" : 46 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name" : "backgroundTopRight", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area" : { "right": 0, "top" : 0, "width" : 199, "height" : 196 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name" : "backgroundBottomRight", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area" : { "bottom": 0, "right" : 0, "width" : 199, "height" : 211 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "sideBorderLeft", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "top": 7, "left" : 0, "bottom" : 46, "width" : 7 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "sideBorderTop", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "top": 0, "left" : 7, "right" : 199, "height" : 7 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "sideBorderBottom", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "bottom": 0, "right" : 199, "left" : 0, "height" : 47 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "heroListBorderLeft", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "top": 196, "bottom" : 210, "right" : 192, "width" : 7 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "heroListBorderRight", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "top": 196, "bottom" : 210, "right" : 122, "width" : 3 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "townListBorderLeft", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "top": 196, "bottom" : 210, "right" : 54, "width" : 3 } | ||||
| 		}, | ||||
| 		{ | ||||
| 			"type": "adventureMapImage", | ||||
| 			"name": "townListBorderRight", | ||||
| 			"image" : "AdvMap.pcx", | ||||
| 			"area": { "top": 196, "bottom" : 210, "right" : 0, "width" : 3 } | ||||
| 		}, | ||||
| 		 | ||||
| 		// Game area | ||||
| 		{ | ||||
| 			"type": "adventureMapGameArea", | ||||
| 			"name": "mapView", | ||||
| 			"area": { "top": 7, "bottom" : 47, "left" : 7, "right" : 199 } | ||||
| 		}, | ||||
| 		 | ||||
| 		// Minimap | ||||
| 		{ | ||||
| 			"type": "adventureMinimap", | ||||
| 			"name": "minimap", | ||||
| 			"area": { "top": 26, "right" : 26, "width" : 144, "height" : 144 } | ||||
| 		}, | ||||
|  | ||||
| 		// Adventure map buttons | ||||
| 		{ | ||||
| 			"type": "adventureMapContainer", | ||||
| 			"name" : "buttonsContainer", | ||||
| 			"area": { "top": 196, "right" : 57, "width" : 64, "height" : 192 }, | ||||
| 			"items" : [ | ||||
| 				{ | ||||
| 					"type" : "adventureMapButton", | ||||
| 					"name" : "buttonKingdomOverview", | ||||
| 					"image" : "IAM002.DEF", | ||||
| 					"help" : "core.help.293", | ||||
| 					"area": { "top" : 0, "left": 0, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonUnderground", | ||||
| 					"image" : "IAM010.DEF", | ||||
| 					"help" : "core.help.294", | ||||
| 					"area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonSurface", | ||||
| 					"image" : "IAM003.DEF", | ||||
| 					"help" : "core.help.294", | ||||
| 					"area": { "top" : 0, "left": 32, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonQuestLog", | ||||
| 					"image" : "IAM004.DEF", | ||||
| 					"help" : "core.help.295", | ||||
| 					"area": { "top" : 32, "left": 0, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonSleep", | ||||
| 					"image" : "IAM005.DEF", | ||||
| 					"help" : "core.help.296", | ||||
| 					"area": { "top" : 32, "left": 32, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonWake", | ||||
| 					"image" : "IAM011.DEF", | ||||
| 					"help" : "core.help.296", | ||||
| 					"area": { "top" : 32, "left": 32, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonMove", | ||||
| 					"image" : "IAM006.DEF", | ||||
| 					"help" : "core.help.297", | ||||
| 					"area": { "top" : 64, "left": 0, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonCast", | ||||
| 					"image" : "IAM007.DEF", | ||||
| 					"help" : "core.help.298", | ||||
| 					"area": { "top" : 64, "left": 32, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonAdventureOptions", | ||||
| 					"image" : "IAM008.DEF", | ||||
| 					"help" : "core.help.299", | ||||
| 					"area": { "top" : 96, "left": 0, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonSystemOptions", | ||||
| 					"image" : "IAM009.DEF", | ||||
| 					"help" : "core.help.300", | ||||
| 					"area": { "top" : 96, "left": 32, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonNextHero", | ||||
| 					"image" : "IAM000.DEF", | ||||
| 					"help" : "core.help.301", | ||||
| 					"area": { "top" : 128, "left": 0, "width" : 64, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "buttonEndTurn", | ||||
| 					"image" : "IAM001.DEF", | ||||
| 					"help" : "core.help.302", | ||||
| 					"area": { "top" : 160, "left": 0, "width" : 64, "height" : 32 } | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| 		// Hero List | ||||
| 		{ | ||||
| 			"type": "adventureMapHeroList", | ||||
| 			"name" : "heroList", | ||||
| 			"area": { "top": 196, "right" : 127, "width" : 64, "height" : 192 }, | ||||
| 			"scrollUp" : { | ||||
| 				"type": "adventureMapButton", | ||||
| 				"name": "heroListScrollUp", | ||||
| 				"image" : "IAM012.DEF", | ||||
| 				"help" : "core.help.303", | ||||
| 				"area": { "top" : 0, "left": 0, "width" : 64, "height" : 16 } | ||||
| 			}, | ||||
| 			"scrollDown" : { | ||||
| 				"type": "adventureMapButton", | ||||
| 				"name": "heroListScrollDown", | ||||
| 				"image" : "IAM013.DEF", | ||||
| 				"help" : "core.help.304", | ||||
| 				"area": { "top" : 176, "left": 0, "width" : 64, "height" : 16 } | ||||
| 			}, | ||||
| 			"item" : { "top" :  16, "left": 1, "width" : 62, "height" : 32 }, | ||||
| 			"itemsOffset" : { "x" : 0, "y" : 32 }, | ||||
| 			"itemsCount" : 5 | ||||
| 		}, | ||||
| 		 | ||||
| 		// Town List | ||||
| 		{ | ||||
| 			"type": "adventureMapTownList", | ||||
| 			"name" : "townList", | ||||
| 			"area": { "top": 196, "right" : 5, "width" : 48, "height" : 192 }, | ||||
| 			"scrollUp" : { | ||||
| 				"type": "adventureMapButton", | ||||
| 				"name": "townListScrollUp", | ||||
| 				"image" : "IAM014.DEF", | ||||
| 				"help" : "core.help.306", | ||||
| 				"area": { "top" : 0, "left": 0, "width" : 48, "height" : 16 } | ||||
| 			}, | ||||
| 			"scrollDown" : { | ||||
| 				"type": "adventureMapButton", | ||||
| 				"name": "townListScrollDown", | ||||
| 				"image" : "IAM015.DEF", | ||||
| 				"help" : "core.help.307", | ||||
| 				"area": { "top" : 176, "left": 0, "width" : 48, "height" : 16 } | ||||
| 			}, | ||||
| 			"item" : { "top" :  16, "left": 0, "width" : 48, "height" : 32 }, | ||||
| 			"itemsOffset" : { "x" : 0, "y" : 32 }, | ||||
| 			"itemsCount" : 5 | ||||
| 		}, | ||||
| 		 | ||||
| 		// Infobar | ||||
| 		{ | ||||
| 			"type": "adventureInfobar", | ||||
| 			"name": "infoBar", | ||||
| 			"area": { "bottom": 44, "right" : 19, "width" : 175, "height" : 168 } | ||||
| 		}, | ||||
| 		// Status bar | ||||
| 		{ | ||||
| 			"type": "adventureStatusBar", | ||||
| 			"name": "statusBar", | ||||
| 			"image" : "DiBoxBck.pcx", | ||||
| 			"area": { "left": 8, "bottom" : 26, "right" : 199, "height" : 18 } | ||||
| 		}, | ||||
| 		// Resource & Data bar | ||||
| 		{ | ||||
| 			"type": "adventureResourceDateBar", | ||||
| 			"name": "resourceDataBar", | ||||
| 			"image" : "AResBar.pcx", | ||||
| 			"area": { "bottom" : 3, "right" : 3, "height" : 22, "width" : 794 }, | ||||
| 			 | ||||
| 			"wood"    : { "x" :  36, "y" : 2 }, | ||||
| 			"mercury" : { "x" : 120, "y" : 2 }, | ||||
| 			"ore"     : { "x" : 204, "y" : 2 }, | ||||
| 			"sulfur"  : { "x" : 288, "y" : 2 }, | ||||
| 			"crystal" : { "x" : 372, "y" : 2 }, | ||||
| 			"gems"    : { "x" : 456, "y" : 2 }, | ||||
| 			"gold"    : { "x" : 540, "y" : 2 }, | ||||
| 			"date"    : { "x" : 615, "y" : 2 } | ||||
| 		}, | ||||
| 		// World view mode widgets | ||||
| 		{ | ||||
| 			"type": "adventureMapContainer", | ||||
| 			"name" : "worldViewContainer", | ||||
| 			"area": { "top": 195, "right" : 4, "width" : 190, "height" : 381 }, | ||||
| 			"items" : [ | ||||
| 				{ | ||||
| 					"type": "adventureMapImage", | ||||
| 					"name": "worldViewBackground", | ||||
| 					"image" : "VWorld.pcx", | ||||
| 					"area": { "top" : 0, "left": 0, "width" : 48, "height" : 192 }, | ||||
| 					"areaSource": { "left" : 0, "right" : 0, "top" : 0, "bottom" : 0 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewZoom1", | ||||
| 					"image" : "VWMAG1.DEF", | ||||
| 					"area": { "top" : 23, "left": 1, "width" : 60, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewZoom2", | ||||
| 					"image" : "VWMAG2.DEF", | ||||
| 					"area": { "top" : 23, "left": 64, "width" : 60, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewZoom4", | ||||
| 					"image" : "VWMAG4.DEF", | ||||
| 					"area": { "top" : 23, "left": 1, "width" : 60, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewSurface", | ||||
| 					"image" : "IAM003.DEF", | ||||
| 					"area": { "top" : 79, "left": 343, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewPuzzle", | ||||
| 					"image" : "VWPUZ.DEF", | ||||
| 					"area": { "top" : 343, "left": 5, "width" : 66, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewUnderground", | ||||
| 					"image" : "IAM010.DEF", | ||||
| 					"area": { "top" : 343, "left": 79, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapButton", | ||||
| 					"name": "worldViewExit", | ||||
| 					"image" : "IOK6432.DEF", | ||||
| 					"area": { "top" : 343, "left": 117, "width" : 66, "height" : 32 } | ||||
| 				}, | ||||
| 				// World view - objects icons | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconTown", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 0, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 66, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconHero", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 1, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 86, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconArtifact", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 2, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 106, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconTeleporter", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 3, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 126, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconGate", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 4, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 146, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				 | ||||
| 				// World view - mines icons | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineWood", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 5, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 190, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineMercury", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 6, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 210, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconOre", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 7, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 230, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineSulfur", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 8, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 250, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineCrystal", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 9, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 270, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineGems", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 10, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 290, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineGold", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 11, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 310, "left": 12, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				 | ||||
| 				// World view - resources icons | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineWood", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 12, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 190, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineMercury", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 13, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 210, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconOre", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 14, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 230, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineSulfur", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 15, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 250, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineCrystal", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 16, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 270, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineGems", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 17, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 290, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
| 				{ | ||||
| 					"type": "adventureMapIcon", | ||||
| 					"name": "worldViewIconMineGold", | ||||
| 					"image" : "VwSymbol.def", | ||||
| 					"index" : 18, | ||||
| 					"perPlayer" : 19, | ||||
| 					"area": { "top" : 310, "left": 160, "width" : 32, "height" : 32 } | ||||
| 				}, | ||||
|  | ||||
| 				{ | ||||
| 					"name": "worldViewLabelTitle", | ||||
| 					"type": "label", | ||||
| 					"font": "big", | ||||
| 					"alignment": "center", | ||||
| 					"color": "yellow", | ||||
| 					"position": {"x": 100, "y": 10}, | ||||
| 					"text": "core.genrltxt.611" | ||||
| 				}, | ||||
| 				{ | ||||
| 					"name": "worldViewLabelMine", | ||||
| 					"type": "label", | ||||
| 					"font": "calisto", | ||||
| 					"alignment": "center", | ||||
| 					"color": "yellow", | ||||
| 					"position": {"x": 10, "y": 175}, | ||||
| 					"text": "core.genrltxt.617" | ||||
| 				}, | ||||
| 				{ | ||||
| 					"name": "worldViewLabelResource", | ||||
| 					"type": "label", | ||||
| 					"font": "calisto", | ||||
| 					"alignment": "center", | ||||
| 					"color": "yellow", | ||||
| 					"position": {"x": 185, "y": 185}, | ||||
| 					"text": "core.genrltxt.618" | ||||
| 				}, | ||||
| 				{ | ||||
| 					"name": "worldViewLabelsObjects", | ||||
| 					"type": "labelGroup", | ||||
| 					"font": "calisto", | ||||
| 					"alignment": "left", | ||||
| 					"color": "white", | ||||
| 					"items": | ||||
| 					[ | ||||
| 						{ | ||||
| 							"position": {"x": 45, "y": 70}, | ||||
| 							"text": "core.genrltxt.612" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 45, "y": 90}, | ||||
| 							"text": "core.genrltxt.613" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 45, "y": 110}, | ||||
| 							"text": "core.genrltxt.614" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 45, "y": 130}, | ||||
| 							"text": "core.genrltxt.615" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 45, "y": 150}, | ||||
| 							"text": "core.genrltxt.616" | ||||
| 						} | ||||
| 					] | ||||
| 				}, | ||||
| 				{ | ||||
| 					"name": "worldViewLabelsResources", | ||||
| 					"type": "labelGroup", | ||||
| 					"font": "calisto", | ||||
| 					"alignment": "center", | ||||
| 					"color": "white", | ||||
| 					"items": | ||||
| 					[ | ||||
| 						{ | ||||
| 							"position": {"x": 100, "y": 200}, | ||||
| 							"text": "core.genrltxt.619" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 100, "y": 220}, | ||||
| 							"text": "core.genrltxt.620" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 100, "y": 240}, | ||||
| 							"text": "core.genrltxt.621" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 100, "y": 260}, | ||||
| 							"text": "core.genrltxt.622" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 100, "y": 280}, | ||||
| 							"text": "core.genrltxt.623" | ||||
| 						}, | ||||
| 						{ | ||||
| 							"position": {"x": 100, "y": 300}, | ||||
| 							"text": "core.genrltxt.624" | ||||
| 						} | ||||
| 					] | ||||
| 				}, | ||||
| 			] | ||||
| 		} | ||||
| 	] | ||||
| } | ||||
| @@ -17,10 +17,7 @@ | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_BEGIN | ||||
|  | ||||
| using namespace config; | ||||
|  | ||||
| SettingsStorage settings; | ||||
| CConfigHandler conf; | ||||
|  | ||||
| template<typename Accessor> | ||||
| SettingsStorage::NodeAccessor<Accessor>::NodeAccessor(SettingsStorage & _parent, std::vector<std::string> _path): | ||||
| @@ -178,123 +175,6 @@ JsonNode & Settings::operator[](const std::string & value) | ||||
| { | ||||
| 	return node[value]; | ||||
| } | ||||
| // | ||||
| // template DLL_LINKAGE struct SettingsStorage::NodeAccessor<SettingsListener>; | ||||
| // template DLL_LINKAGE struct SettingsStorage::NodeAccessor<Settings>; | ||||
|  | ||||
| static void setButton(ButtonInfo &button, const JsonNode &g) | ||||
| { | ||||
| 	button.x = static_cast<int>(g["x"].Float()); | ||||
| 	button.y = static_cast<int>(g["y"].Float()); | ||||
| 	button.playerColoured = g["playerColoured"].Float(); | ||||
| 	button.defName = g["graphic"].String(); | ||||
|  | ||||
| 	if (!g["additionalDefs"].isNull()) { | ||||
| 		const JsonVector &defs_vec = g["additionalDefs"].Vector(); | ||||
|  | ||||
| 		for(const JsonNode &def : defs_vec) { | ||||
| 			button.additionalDefs.push_back(def.String()); | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
|  | ||||
| static void setGem(AdventureMapConfig &ac, const int gem, const JsonNode &g) | ||||
| { | ||||
| 	ac.gemX[gem] = static_cast<int>(g["x"].Float()); | ||||
| 	ac.gemY[gem] = static_cast<int>(g["y"].Float()); | ||||
| 	ac.gemG.push_back(g["graphic"].String()); | ||||
| } | ||||
|  | ||||
| CConfigHandler::CConfigHandler() | ||||
| 	: current(nullptr) | ||||
| { | ||||
| } | ||||
|  | ||||
| void config::CConfigHandler::init() | ||||
| { | ||||
| 	/* Read resolutions. */ | ||||
| 	const JsonNode config(ResourceID("config/resolutions.json")); | ||||
| 	const JsonVector &guisettings_vec = config["GUISettings"].Vector(); | ||||
|  | ||||
| 	for(const JsonNode &g : guisettings_vec) | ||||
| 	{ | ||||
| 		std::pair<int, int> curRes(static_cast<int>(g["resolution"]["x"].Float()), static_cast<int>(g["resolution"]["y"].Float())); | ||||
| 		GUIOptions *current = &conf.guiOptions[curRes]; | ||||
|  | ||||
| 		current->ac.inputLineLength =  static_cast<int>(g["InGameConsole"]["maxInputPerLine"].Float()); | ||||
| 		current->ac.outputLineLength = static_cast<int>(g["InGameConsole"]["maxOutputPerLine"].Float()); | ||||
|  | ||||
| 		current->ac.advmapX = static_cast<int>(g["AdvMap"]["x"].Float()); | ||||
| 		current->ac.advmapY = static_cast<int>(g["AdvMap"]["y"].Float()); | ||||
| 		current->ac.advmapW = static_cast<int>(g["AdvMap"]["width"].Float()); | ||||
| 		current->ac.advmapH = static_cast<int>(g["AdvMap"]["height"].Float()); | ||||
| 		current->ac.smoothMove = g["AdvMap"]["smoothMove"].Float(); | ||||
| 		current->ac.puzzleSepia = g["AdvMap"]["puzzleSepia"].Float(); | ||||
| 		current->ac.screenFading = g["AdvMap"]["screenFading"].isNull() ? true : g["AdvMap"]["screenFading"].Float(); // enabled by default | ||||
| 		current->ac.objectFading = g["AdvMap"]["objectFading"].isNull() ? true : g["AdvMap"]["objectFading"].Float(); | ||||
|  | ||||
| 		current->ac.infoboxX = static_cast<int>(g["InfoBox"]["x"].Float()); | ||||
| 		current->ac.infoboxY = static_cast<int>(g["InfoBox"]["y"].Float()); | ||||
|  | ||||
| 		setGem(current->ac, 0, g["gem0"]); | ||||
| 		setGem(current->ac, 1, g["gem1"]); | ||||
| 		setGem(current->ac, 2, g["gem2"]); | ||||
| 		setGem(current->ac, 3, g["gem3"]); | ||||
|  | ||||
| 		current->ac.mainGraphic = g["background"].String(); | ||||
| 		current->ac.worldViewGraphic = g["backgroundWorldView"].String(); | ||||
|  | ||||
| 		current->ac.hlistX =    static_cast<int>(g["HeroList"]["x"].Float()); | ||||
| 		current->ac.hlistY =    static_cast<int>(g["HeroList"]["y"].Float()); | ||||
| 		current->ac.hlistSize = static_cast<int>(g["HeroList"]["size"].Float()); | ||||
| 		current->ac.hlistMB = g["HeroList"]["movePoints"].String(); | ||||
| 		current->ac.hlistMN = g["HeroList"]["manaPoints"].String(); | ||||
| 		current->ac.hlistAU = g["HeroList"]["arrowUp"].String(); | ||||
| 		current->ac.hlistAD = g["HeroList"]["arrowDown"].String(); | ||||
|  | ||||
| 		current->ac.tlistX =    static_cast<int>(g["TownList"]["x"].Float()); | ||||
| 		current->ac.tlistY =    static_cast<int>(g["TownList"]["y"].Float()); | ||||
| 		current->ac.tlistSize = static_cast<int>(g["TownList"]["size"].Float()); | ||||
| 		current->ac.tlistAU = g["TownList"]["arrowUp"].String(); | ||||
| 		current->ac.tlistAD = g["TownList"]["arrowDown"].String(); | ||||
|  | ||||
| 		current->ac.minimapW = static_cast<int>(g["Minimap"]["width"].Float()); | ||||
| 		current->ac.minimapH = static_cast<int>(g["Minimap"]["height"].Float()); | ||||
| 		current->ac.minimapX = static_cast<int>(g["Minimap"]["x"].Float()); | ||||
| 		current->ac.minimapY = static_cast<int>(g["Minimap"]["y"].Float()); | ||||
|  | ||||
| 		current->ac.overviewPics = static_cast<int>(g["Overview"]["pics"].Float()); | ||||
| 		current->ac.overviewSize = static_cast<int>(g["Overview"]["size"].Float()); | ||||
| 		current->ac.overviewBg = g["Overview"]["graphic"].String(); | ||||
|  | ||||
| 		current->ac.statusbarX = static_cast<int>(g["Statusbar"]["x"].Float()); | ||||
| 		current->ac.statusbarY = static_cast<int>(g["Statusbar"]["y"].Float()); | ||||
| 		current->ac.statusbarG = g["Statusbar"]["graphic"].String(); | ||||
|  | ||||
| 		current->ac.resdatabarX = static_cast<int>(g["ResDataBar"]["x"].Float()); | ||||
| 		current->ac.resdatabarY = static_cast<int>(g["ResDataBar"]["y"].Float()); | ||||
| 		current->ac.resOffsetX =  static_cast<int>(g["ResDataBar"]["offsetX"].Float()); | ||||
| 		current->ac.resOffsetY =  static_cast<int>(g["ResDataBar"]["offsetY"].Float()); | ||||
| 		current->ac.resDist =     static_cast<int>(g["ResDataBar"]["resSpace"].Float()); | ||||
| 		current->ac.resDateDist = static_cast<int>(g["ResDataBar"]["resDateSpace"].Float()); | ||||
| 		current->ac.resdatabarG = g["ResDataBar"]["graphic"].String(); | ||||
|  | ||||
| 		setButton(current->ac.kingOverview, g["ButtonKingdomOv"]); | ||||
| 		setButton(current->ac.underground, g["ButtonUnderground"]); | ||||
| 		setButton(current->ac.questlog, g["ButtonQuestLog"]); | ||||
| 		setButton(current->ac.sleepWake, g["ButtonSleepWake"]); | ||||
| 		setButton(current->ac.moveHero, g["ButtonMoveHero"]); | ||||
| 		setButton(current->ac.spellbook, g["ButtonSpellbook"]); | ||||
| 		setButton(current->ac.advOptions, g["ButtonAdvOptions"]); | ||||
| 		setButton(current->ac.sysOptions, g["ButtonSysOptions"]); | ||||
| 		setButton(current->ac.nextHero, g["ButtonNextHero"]); | ||||
| 		setButton(current->ac.endTurn, g["ButtonEndTurn"]); | ||||
| 	} | ||||
|  | ||||
| 	const JsonNode& screenRes = settings["video"]["screenRes"]; | ||||
|  | ||||
| 	SetResolution(static_cast<int>(screenRes["width"].Float()), static_cast<int>(screenRes["height"].Float())); | ||||
| } | ||||
|  | ||||
| // Force instantiation of the SettingsStorage::NodeAccessor class template. | ||||
| // That way method definitions can sit in the cpp file | ||||
|   | ||||
| @@ -112,83 +112,6 @@ public: | ||||
| 	friend class SettingsStorage; | ||||
| }; | ||||
|  | ||||
| namespace config | ||||
| { | ||||
| 	struct DLL_LINKAGE ButtonInfo | ||||
| 	{ | ||||
| 		std::string defName; | ||||
| 		std::vector<std::string> additionalDefs; | ||||
| 		int x, y; //position on the screen | ||||
| 		bool playerColoured; //if true button will be colored to main player's color (works properly only for appropriate 8bpp graphics) | ||||
| 	}; | ||||
| 	/// Struct which holds data about position of several GUI elements at the adventure map screen | ||||
| 	struct DLL_LINKAGE AdventureMapConfig | ||||
| 	{ | ||||
| 		//minimap properties | ||||
| 		int minimapX, minimapY, minimapW, minimapH; | ||||
| 		//statusbar | ||||
| 		int statusbarX, statusbarY; //pos | ||||
| 		std::string statusbarG; //graphic name | ||||
| 		//resdatabar | ||||
| 		int resdatabarX, resdatabarY, resDist, resDateDist, resOffsetX, resOffsetY; //pos | ||||
| 		std::string resdatabarG; //graphic name | ||||
| 		//infobox | ||||
| 		int infoboxX, infoboxY; | ||||
| 		//advmap | ||||
| 		int advmapX, advmapY, advmapW, advmapH; | ||||
| 		bool smoothMove; | ||||
| 		bool puzzleSepia; | ||||
| 		bool screenFading; | ||||
| 		bool objectFading; | ||||
| 		//general properties | ||||
| 		std::string mainGraphic; | ||||
| 		std::string worldViewGraphic; | ||||
| 		//buttons | ||||
| 		ButtonInfo kingOverview, underground, questlog,	sleepWake, moveHero, spellbook,	advOptions, | ||||
| 			sysOptions,	nextHero, endTurn; | ||||
| 		//hero list | ||||
| 		int hlistX, hlistY, hlistSize; | ||||
| 		std::string hlistMB, hlistMN, hlistAU, hlistAD; | ||||
| 		//town list | ||||
| 		int tlistX, tlistY, tlistSize; | ||||
| 		std::string tlistAU, tlistAD; | ||||
| 		//gems | ||||
| 		int gemX[4], gemY[4]; | ||||
| 		std::vector<std::string> gemG; | ||||
| 		//in-game console | ||||
| 		int inputLineLength, outputLineLength; | ||||
| 		//kingdom overview | ||||
| 		int overviewPics, overviewSize; //pic count in def and count of visible slots | ||||
| 		std::string overviewBg; //background name | ||||
| 	}; | ||||
| 	struct DLL_LINKAGE GUIOptions | ||||
| 	{ | ||||
| 		AdventureMapConfig ac; | ||||
| 	}; | ||||
| 	/// Handles adventure map screen settings | ||||
| 	class DLL_LINKAGE CConfigHandler | ||||
| 	{ | ||||
| 		GUIOptions *current; // pointer to current gui options | ||||
|  | ||||
| 	public: | ||||
| 		using GuiOptionsMap = std::map<std::pair<int, int>, GUIOptions>; | ||||
| 		GuiOptionsMap guiOptions; | ||||
| 		void init(); | ||||
| 		CConfigHandler(); | ||||
|  | ||||
| 		GUIOptions *go() { return current; }; | ||||
| 		void SetResolution(int x, int y) | ||||
| 		{ | ||||
| 			std::pair<int,int> index(x, y); | ||||
| 			if (guiOptions.count(index) == 0) | ||||
| 				current = nullptr; | ||||
| 			else | ||||
| 				current = &guiOptions.at(index); | ||||
| 		} | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| extern DLL_LINKAGE SettingsStorage settings; | ||||
| extern DLL_LINKAGE config::CConfigHandler conf; | ||||
|  | ||||
| VCMI_LIB_NAMESPACE_END | ||||
|   | ||||
| @@ -191,9 +191,6 @@ MainWindow::MainWindow(QWidget* parent) : | ||||
| 		QApplication::quit(); | ||||
| 	} | ||||
|  | ||||
| 	conf.init(); | ||||
| 	logGlobal->info("Loading settings"); | ||||
|  | ||||
| 	loadTranslation(); | ||||
|  | ||||
| 	ui->setupUi(this); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user