Bladeren bron

tab support for battle mode

Laserlicht 1 maand geleden
bovenliggende
commit
45aeba74c3

+ 1 - 0
Mods/vcmi/Content/config/english.json

@@ -139,6 +139,7 @@
 	"vcmi.lobby.deleteFolder" : "Do you want to delete following folder?",
 	"vcmi.lobby.deleteMode" : "Switch to delete mode and back",
 	"vcmi.lobby.battleOnlyMode" : "Battle only mode",
+	"vcmi.lobby.battleOnlyModeSubTitle" : "Select heroes and army for simple battle without adventure map",
 	"vcmi.lobby.battleOnlyModeBattlefield" : "Battlefield",
 	"vcmi.lobby.battleOnlyModeBattlefieldSelect" : "Select Battlefield",
 	"vcmi.lobby.battleOnlyModeHeroSelect" : "Select Hero",

+ 1 - 0
Mods/vcmi/Content/config/german.json

@@ -139,6 +139,7 @@
 	"vcmi.lobby.deleteFolder" : "Möchtet Ihr folgenden Ordner löschen?",
 	"vcmi.lobby.deleteMode" : "In den Löschmodus wechseln und zurück",
 	"vcmi.lobby.battleOnlyMode" : "Nur Kämpfen Modus",
+	"vcmi.lobby.battleOnlyModeSubTitle" : "Wähle Helden und eine Armee für einen einfachen Kampf ohne Abenteuerkarte",
 	"vcmi.lobby.battleOnlyModeBattlefield" : "Schlachtfeld",
 	"vcmi.lobby.battleOnlyModeBattlefieldSelect" : "Schlachtfeld auswählen",
 	"vcmi.lobby.battleOnlyModeHeroSelect" : "Helden auswählen",

+ 3 - 6
client/NetPacksLobbyClient.cpp

@@ -114,9 +114,6 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction & pack
 	if(!lobby || !handler.isGuest())
 		return;
 
-	if(auto topWindow = ENGINE->windows().topWindow<BattleOnlyModeWindow>())
-		topWindow->close();
-
 	switch(pack.action)
 	{
 	case LobbyGuiAction::NO_TAB:
@@ -138,7 +135,7 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyGuiAction(LobbyGuiAction & pack
 		lobby->toggleTab(lobby->tabExtraOptions);
 		break;
 	case LobbyGuiAction::BATTLE_MODE:
-		BattleOnlyMode::openBattleWindow();
+		lobby->toggleTab(lobby->tabBattleOnlyMode);
 		break;
 	}
 }
@@ -242,6 +239,6 @@ void ApplyOnLobbyScreenNetPackVisitor::visitLobbyShowMessage(LobbyShowMessage &
 
 void ApplyOnLobbyScreenNetPackVisitor::visitLobbySetBattleOnlyModeStartInfo(LobbySetBattleOnlyModeStartInfo & pack)
 {
-	if(auto topWindow = ENGINE->windows().topWindow<BattleOnlyModeWindow>())
-		topWindow->applyStartInfo(pack.startInfo);
+	if(lobby->tabBattleOnlyMode)
+		lobby->tabBattleOnlyMode->applyStartInfo(pack.startInfo);
 }

+ 19 - 38
client/lobby/BattleOnlyMode.cpp

@@ -56,39 +56,21 @@
 #include "../../lib/texts/TextOperations.h"
 #include "../../lib/filesystem/Filesystem.h"
 
-void BattleOnlyMode::openBattleWindow()
-{
-	GAME->server().sendGuiAction(LobbyGuiAction::BATTLE_MODE);
-	ENGINE->windows().createAndPushWindow<BattleOnlyModeWindow>();
-}
-
-BattleOnlyModeWindow::BattleOnlyModeWindow()
-	: CWindowObject(BORDERED)
-	, startInfo(std::make_shared<BattleOnlyModeStartInfo>())
+BattleOnlyModeTab::BattleOnlyModeTab()
+	: startInfo(std::make_shared<BattleOnlyModeStartInfo>())
 	, disabledColor(GAME->server().isHost() ? Colors::WHITE : Colors::ORANGE)
 {
 	OBJECT_CONSTRUCTION;
 
-	pos.w = 519;
-	pos.h = 238;
-
-	updateShadow();
-	center();
-
 	init();
 
-	backgroundTexture = std::make_shared<FilledTexturePlayerColored>(Rect(0, 0, pos.w, pos.h));
-	backgroundTexture->setPlayerColor(PlayerColor(1));
-	buttonOk = std::make_shared<CButton>(Point(191, 203), AnimationPath::builtin("MuBchck"), CButton::tooltip(), [this](){ startBattle(); }, EShortcut::GLOBAL_ACCEPT);
+	backgroundImage = std::make_shared<CPicture>(ImagePath::builtin("AdventureOptionsBackgroundClear"), 0, 6);
+	buttonOk = std::make_shared<CButton>(Point(148, 430), AnimationPath::builtin("CBBEGIB"), CButton::tooltip(), [this](){ startBattle(); }, EShortcut::GLOBAL_ACCEPT);
 	buttonOk->block(true);
-	buttonAbort = std::make_shared<CButton>(Point(265, 203), AnimationPath::builtin("MuBcanc"), CButton::tooltip(), [this](){
-		GAME->server().sendGuiAction(LobbyGuiAction::NO_TAB);
-		close();
-	}, EShortcut::GLOBAL_CANCEL);
-	buttonAbort->block(true);
-	title = std::make_shared<CLabel>(260, 20, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyMode"));
-
-	battlefieldSelector = std::make_shared<CButton>(Point(29, 174), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){
+	title = std::make_shared<CLabel>(220, 35, FONT_BIG, ETextAlignment::CENTER, Colors::YELLOW, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyMode"));
+	subTitle = std::make_shared<CMultiLineLabel>(Rect(55, 40, 333, 40), FONT_SMALL, ETextAlignment::BOTTOMCENTER, Colors::WHITE, LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeSubTitle"));
+
+	battlefieldSelector = std::make_shared<CButton>(Point(120, 370), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){
 		std::vector<std::string> texts;
 		std::vector<std::shared_ptr<IImage>> images;
 
@@ -137,7 +119,7 @@ BattleOnlyModeWindow::BattleOnlyModeWindow()
 		}, (startInfo->selectedTerrain ? static_cast<int>(*startInfo->selectedTerrain) : static_cast<int>(*startInfo->selectedTown + terrains.size())), images, true, true);
 	});
 	battlefieldSelector->block(GAME->server().isGuest());
-	buttonReset = std::make_shared<CButton>(Point(289, 174), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){
+	buttonReset = std::make_shared<CButton>(Point(120, 400), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){
 		if(GAME->server().isHost())
 		{
 			startInfo->selectedTerrain = TerrainId::DIRT;
@@ -155,15 +137,15 @@ BattleOnlyModeWindow::BattleOnlyModeWindow()
 	});
 	buttonReset->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeReset"), EFonts::FONT_SMALL, Colors::WHITE);
 
-	heroSelector1 = std::make_shared<BattleOnlyModeHeroSelector>(0, *this, Point(0, 40));
-	heroSelector2 = std::make_shared<BattleOnlyModeHeroSelector>(1, *this, Point(260, 40));
+	heroSelector1 = std::make_shared<BattleOnlyModeHeroSelector>(0, *this, Point(91, 90));
+	heroSelector2 = std::make_shared<BattleOnlyModeHeroSelector>(1, *this, Point(91, 225));
 
 	heroSelector1->setInputEnabled(GAME->server().isHost());
 
 	onChange();
 }
 
-void BattleOnlyModeWindow::init()
+void BattleOnlyModeTab::init()
 {
 	map = std::make_unique<CMap>(nullptr);
 	map->version = EMapFormat::VCMI;
@@ -177,12 +159,12 @@ void BattleOnlyModeWindow::init()
 	cb = std::make_unique<EditorCallback>(map.get());
 }
 
-void BattleOnlyModeWindow::onChange()
+void BattleOnlyModeTab::onChange()
 {
 	GAME->server().setBattleOnlyModeStartInfo(startInfo);
 }
 
-void BattleOnlyModeWindow::update()
+void BattleOnlyModeTab::update()
 {
 	setTerrainButtonText();
 	setOkButtonEnabled();
@@ -194,25 +176,24 @@ void BattleOnlyModeWindow::update()
 	redraw();
 }
 
-void BattleOnlyModeWindow::applyStartInfo(std::shared_ptr<BattleOnlyModeStartInfo> si)
+void BattleOnlyModeTab::applyStartInfo(std::shared_ptr<BattleOnlyModeStartInfo> si)
 {
 	startInfo = si;
 	update();
 }
 
-void BattleOnlyModeWindow::setTerrainButtonText()
+void BattleOnlyModeTab::setTerrainButtonText()
 {
 	battlefieldSelector->setTextOverlay(LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyModeBattlefield") + ":   " + (startInfo->selectedTerrain ? (*startInfo->selectedTerrain).toEntity(LIBRARY)->getNameTranslated() : (*startInfo->selectedTown).toEntity(LIBRARY)->getNameTranslated()), EFonts::FONT_SMALL, disabledColor);
 }
 
-void BattleOnlyModeWindow::setOkButtonEnabled()
+void BattleOnlyModeTab::setOkButtonEnabled()
 {
 	bool army2Empty = std::all_of(startInfo->selectedArmy[1].begin(), startInfo->selectedArmy[1].end(), [](const auto x) { return x.getId() == CreatureID::NONE; });
 
 	bool canStart = (startInfo->selectedTerrain || startInfo->selectedTown);
 	canStart &= (startInfo->selectedHero[0] && ((startInfo->selectedHero[1]) || (startInfo->selectedTown && !army2Empty)));
 	buttonOk->block(!canStart || GAME->server().isGuest());
-	buttonAbort->block(GAME->server().isGuest());
 }
 
 std::shared_ptr<IImage> drawBlackBox(Point size, std::string text, ColorRGBA color)
@@ -224,7 +205,7 @@ std::shared_ptr<IImage> drawBlackBox(Point size, std::string text, ColorRGBA col
 	return image;
 }
 
-BattleOnlyModeHeroSelector::BattleOnlyModeHeroSelector(int id, BattleOnlyModeWindow& p, Point position)
+BattleOnlyModeHeroSelector::BattleOnlyModeHeroSelector(int id, BattleOnlyModeTab& p, Point position)
 : parent(p)
 , id(id)
 {
@@ -440,7 +421,7 @@ void BattleOnlyModeHeroSelector::setCreatureIcons()
 	}
 }
 
-void BattleOnlyModeWindow::startBattle()
+void BattleOnlyModeTab::startBattle()
 {
 	auto rng = &CRandomGenerator::getDefault();
 	

+ 9 - 13
client/lobby/BattleOnlyMode.h

@@ -11,6 +11,7 @@
 
 #include "../windows/CWindowObject.h"
 #include "../../lib/constants/EntityIdentifiers.h"
+#include "../../lib/mapping/CMap.h"
 
 
 VCMI_LIB_NAMESPACE_BEGIN
@@ -25,22 +26,17 @@ class FilledTexturePlayerColored;
 class CButton;
 class CPicture;
 class CLabel;
-class BattleOnlyModeWindow;
+class CMultiLineLabel;
+class BattleOnlyModeTab;
 class CAnimImage;
 class GraphicalPrimitiveCanvas;
 class CTextInput;
 class TransparentFilledRectangle;
 
-class BattleOnlyMode
-{
-public:
-	static void openBattleWindow();
-};
-
 class BattleOnlyModeHeroSelector : public CIntObject
 {
 private:
-	BattleOnlyModeWindow& parent;
+	BattleOnlyModeTab& parent;
 
 	std::shared_ptr<CPicture> backgroundImage;
 	std::shared_ptr<CPicture> heroImage;
@@ -57,10 +53,10 @@ public:
 
 	void setHeroIcon();
 	void setCreatureIcons();
-	BattleOnlyModeHeroSelector(int id, BattleOnlyModeWindow& parent, Point position);
+	BattleOnlyModeHeroSelector(int id, BattleOnlyModeTab& parent, Point position);
 };
 
-class BattleOnlyModeWindow : public CWindowObject
+class BattleOnlyModeTab : public CIntObject
 {
 	friend class BattleOnlyModeHeroSelector;
 private:
@@ -68,10 +64,10 @@ private:
 	std::unique_ptr<CMap> map;
 	std::shared_ptr<EditorCallback> cb;
 
-	std::shared_ptr<FilledTexturePlayerColored> backgroundTexture;
+	std::shared_ptr<CPicture> backgroundImage;
 	std::shared_ptr<CButton> buttonOk;
-	std::shared_ptr<CButton> buttonAbort;
 	std::shared_ptr<CLabel> title;
+	std::shared_ptr<CMultiLineLabel> subTitle;
 
 	std::shared_ptr<CButton> battlefieldSelector;
 	std::shared_ptr<CButton> buttonReset;
@@ -87,6 +83,6 @@ private:
 	void setOkButtonEnabled();
 	void startBattle();
 public:
-	BattleOnlyModeWindow();
+	BattleOnlyModeTab();
 	void applyStartInfo(std::shared_ptr<BattleOnlyModeStartInfo> si);
 };

+ 10 - 0
client/lobby/CLobbyScreen.cpp

@@ -16,6 +16,7 @@
 #include "OptionsTab.h"
 #include "RandomMapTab.h"
 #include "SelectionTab.h"
+#include "BattleOnlyMode.h"
 
 #include "../CServerHandler.h"
 #include "../GameEngine.h"
@@ -146,6 +147,8 @@ void CLobbyScreen::toggleTab(std::shared_ptr<CIntObject> tab)
 		GAME->server().sendGuiAction(LobbyGuiAction::OPEN_TURN_OPTIONS);
 	else if(tab == tabExtraOptions)
 		GAME->server().sendGuiAction(LobbyGuiAction::OPEN_EXTRA_OPTIONS);
+	else if(tab == tabBattleOnlyMode)
+		GAME->server().sendGuiAction(LobbyGuiAction::BATTLE_MODE);
 	CSelectionBase::toggleTab(tab);
 }
 
@@ -239,6 +242,13 @@ void CLobbyScreen::toggleChat()
 
 void CLobbyScreen::updateAfterStateChange()
 {
+	OBJECT_CONSTRUCTION;
+	if(!tabBattleOnlyMode)
+	{
+		tabBattleOnlyMode = std::make_shared<BattleOnlyModeTab>();
+		tabBattleOnlyMode->setEnabled(false);
+	}
+
 	if(GAME->server().isHost() && screenType == ESelectionScreen::newGame)
 	{
 		bool isMultiplayer = GAME->server().loadMode == ELoadMode::MULTI;

+ 2 - 0
client/lobby/CSelectionBase.h

@@ -29,6 +29,7 @@ class OptionsTab;
 class TurnOptionsTab;
 class ExtraOptionsTab;
 class SelectionTab;
+class BattleOnlyModeTab;
 class InfoCard;
 class CChatBox;
 class PvPBox;
@@ -78,6 +79,7 @@ public:
 	std::shared_ptr<TurnOptionsTab> tabTurnOptions;
 	std::shared_ptr<ExtraOptionsTab> tabExtraOptions;
 	std::shared_ptr<RandomMapTab> tabRand;
+	std::shared_ptr<BattleOnlyModeTab> tabBattleOnlyMode;
 	std::shared_ptr<CIntObject> curTab;
 
 	CSelectionBase(ESelectionScreen type);

+ 4 - 3
client/lobby/SelectionTab.cpp

@@ -244,9 +244,10 @@ SelectionTab::SelectionTab(ESelectionScreen Type)
 
 		if(tabType == ESelectionScreen::newGame)
 		{
-			buttonBattleOnlyMode = std::make_shared<CButton>(Point(23, 18), AnimationPath::builtin("lobby/battleButton"), CButton::tooltip("", LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyMode")), [tabTitle, tabTitleDelete](){
-				BattleOnlyMode::openBattleWindow();
-			});
+			buttonBattleOnlyMode = std::make_shared<CButton>(Point(23, 18), AnimationPath::builtin("lobby/battleButton"), CButton::tooltip("", LIBRARY->generaltexth->translate("vcmi.lobby.battleOnlyMode")), [this](){
+				auto lobby = static_cast<CLobbyScreen *>(parent);
+				lobby->toggleTab(lobby->tabBattleOnlyMode);
+			}, EShortcut::LOBBY_ADDITIONAL_OPTIONS);
 		}
 
 		if(tabType == ESelectionScreen::loadGame || tabType == ESelectionScreen::newGame)

+ 7 - 6
client/widgets/TextControls.cpp

@@ -351,12 +351,13 @@ Rect CMultiLineLabel::getTextLocation()
 
 	switch(alignment)
 	{
-	case ETextAlignment::TOPLEFT:     return Rect(pos.topLeft(), textSizeComputed);
-	case ETextAlignment::TOPCENTER:   return Rect(pos.topLeft(), textSizeComputed);
-	case ETextAlignment::CENTER:      return Rect(pos.topLeft() + textOffset / 2, textSizeComputed);
-	case ETextAlignment::CENTERLEFT:  return Rect(pos.topLeft() + Point(0, textOffset.y / 2), textSizeComputed);
-	case ETextAlignment::CENTERRIGHT: return Rect(pos.topLeft() + Point(textOffset.x, textOffset.y / 2), textSizeComputed);
-	case ETextAlignment::BOTTOMRIGHT: return Rect(pos.topLeft() + textOffset, textSizeComputed);
+	case ETextAlignment::TOPLEFT:      return Rect(pos.topLeft(), textSizeComputed);
+	case ETextAlignment::TOPCENTER:    return Rect(pos.topLeft(), textSizeComputed);
+	case ETextAlignment::CENTER:       return Rect(pos.topLeft() + textOffset / 2, textSizeComputed);
+	case ETextAlignment::CENTERLEFT:   return Rect(pos.topLeft() + Point(0, textOffset.y / 2), textSizeComputed);
+	case ETextAlignment::CENTERRIGHT:  return Rect(pos.topLeft() + Point(textOffset.x, textOffset.y / 2), textSizeComputed);
+	case ETextAlignment::BOTTOMRIGHT:  return Rect(pos.topLeft() + textOffset, textSizeComputed);
+	case ETextAlignment::BOTTOMCENTER: return Rect(pos.topLeft() + Point(textOffset.x / 2, textOffset.y), textSizeComputed);
 	}
 	assert(0);
 	return Rect();