1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-11-25 22:42:04 +02:00

tab support for battle mode

This commit is contained in:
Laserlicht
2025-11-06 20:43:25 +01:00
parent fd81dcaff0
commit 45aeba74c3
9 changed files with 55 additions and 65 deletions

View File

@@ -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",

View File

@@ -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",

View File

@@ -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);
}

View File

@@ -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"));
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(29, 174), AnimationPath::builtin("GSPButtonClear"), CButton::tooltip(), [this](){
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();

View File

@@ -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);
};

View File

@@ -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;

View File

@@ -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);

View File

@@ -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)

View File

@@ -357,6 +357,7 @@ Rect CMultiLineLabel::getTextLocation()
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();