Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added dynamic interface option #9413

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions src/fheroes2/dialog/dialog_interface_settings.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2023 - 2024 *
* Copyright (C) 2023 - 2025 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
Expand Down Expand Up @@ -63,18 +63,28 @@ namespace
void drawInterfaceType( const fheroes2::Rect & optionRoi )
{
const Settings & conf = Settings::Get();
const bool isEvilInterface = conf.isEvilInterfaceEnabled();
const fheroes2::Sprite & interfaceThemeIcon = fheroes2::AGG::GetICN( ICN::SPANEL, isEvilInterface ? 17 : 16 );
const InterfaceType interfaceType = conf.getInterfaceType();

const fheroes2::Sprite * interfaceThemeIcon;
std::string value;
if ( isEvilInterface ) {
value = _( "Evil" );
}
else {
switch ( interfaceType ) {
case DYNAMIC:
interfaceThemeIcon = &fheroes2::AGG::GetICN( ICN::SPANEL, 15 );
felix642 marked this conversation as resolved.
Show resolved Hide resolved
value = _( "Dynamic" );
break;
case GOOD:
interfaceThemeIcon = &fheroes2::AGG::GetICN( ICN::SPANEL, 16 );
value = _( "Good" );
break;
case EVIL:
interfaceThemeIcon = &fheroes2::AGG::GetICN( ICN::SPANEL, 17 );
value = _( "Evil" );
break;
default:
assert( 0 );
}

fheroes2::drawOption( optionRoi, interfaceThemeIcon, _( "Interface Type" ), std::move( value ), fheroes2::UiOptionTextWidth::TWO_ELEMENTS_ROW );
fheroes2::drawOption( optionRoi, *interfaceThemeIcon, _( "Interface Type" ), std::move( value ), fheroes2::UiOptionTextWidth::TWO_ELEMENTS_ROW );
}

void drawInterfacePresence( const fheroes2::Rect & optionRoi )
Expand Down Expand Up @@ -287,7 +297,7 @@ namespace fheroes2
windowType = showConfigurationWindow( saveConfiguration );
break;
case SelectedWindow::InterfaceType:
conf.setEvilInterface( !conf.isEvilInterfaceEnabled() );
conf.setInterfaceType( static_cast<InterfaceType>( ( conf.getInterfaceType() + 1 ) % ( InterfaceType::DYNAMIC + 1 ) ) );
felix642 marked this conversation as resolved.
Show resolved Hide resolved
updateUI();
saveConfiguration = true;

Expand Down
4 changes: 2 additions & 2 deletions src/fheroes2/game/game_campaign.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2020 - 2024 *
* Copyright (C) 2020 - 2025 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
Expand Down Expand Up @@ -1307,7 +1307,7 @@ fheroes2::GameMode Game::SelectCampaignScenario( const fheroes2::GameMode prevMo
const std::vector<Campaign::ScenarioData> & scenarios = campaignData.getAllScenarios();
const Campaign::ScenarioData & scenario = scenarios[currentScenarioInfoId.scenarioId];

const fheroes2::GameInterfaceTypeRestorer gameInterfaceRestorer( chosenCampaignID != Campaign::ROLAND_CAMPAIGN );
const fheroes2::GameInterfaceTypeRestorer gameInterfaceRestorer( chosenCampaignID == Campaign::ROLAND_CAMPAIGN ? InterfaceType::GOOD : InterfaceType::EVIL );

if ( !allowToRestart ) {
playCurrentScenarioVideo();
Expand Down
11 changes: 8 additions & 3 deletions src/fheroes2/game/game_startgame.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2019 - 2024 *
* Copyright (C) 2019 - 2025 *
* *
* Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 *
* Copyright (C) 2009 by Andrey Afletdinov <[email protected]> *
Expand Down Expand Up @@ -784,6 +784,13 @@ fheroes2::GameMode Interface::AdventureMap::StartGame()
// Reset environment sounds and music theme at the beginning of the human turn
AudioManager::ResetAudio();

conf.SetCurrentColor( playerColor );
if ( conf.getInterfaceType() == InterfaceType::DYNAMIC ) {
reset();
redraw( Interface::REDRAW_RADAR );
redraw( Interface::REDRAW_ALL & ( ~Interface::REDRAW_RADAR ) );
}
felix642 marked this conversation as resolved.
Show resolved Hide resolved

if ( isHotSeatGame ) {
_iconsPanel.hideIcons( ICON_ANY );
_statusPanel.Reset();
Expand All @@ -804,8 +811,6 @@ fheroes2::GameMode Interface::AdventureMap::StartGame()
Game::DialogPlayers( playerColor, "", _( "%{color} player's turn." ) );
}

conf.SetCurrentColor( playerColor );

kingdom.ActionBeforeTurn();

_iconsPanel.showIcons( ICON_ANY );
Expand Down
16 changes: 8 additions & 8 deletions src/fheroes2/gui/ui_tool.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2020 - 2024 *
* Copyright (C) 2020 - 2025 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
Expand Down Expand Up @@ -296,19 +296,19 @@ namespace fheroes2
Display::instance().changePalette( palette );
}

GameInterfaceTypeRestorer::GameInterfaceTypeRestorer( const bool isEvilInterface_ )
: isEvilInterface( isEvilInterface_ )
, isOriginalEvilInterface( Settings::Get().isEvilInterfaceEnabled() )
GameInterfaceTypeRestorer::GameInterfaceTypeRestorer( const InterfaceType interfaceType_ )
: interfaceType( interfaceType_ )
, originalInterfaceType( Settings::Get().getInterfaceType() )
{
if ( isEvilInterface != isOriginalEvilInterface ) {
Settings::Get().setEvilInterface( isEvilInterface );
if ( interfaceType != originalInterfaceType ) {
Settings::Get().setInterfaceType( interfaceType_ );
}
}

GameInterfaceTypeRestorer::~GameInterfaceTypeRestorer()
{
if ( isEvilInterface != isOriginalEvilInterface ) {
Settings::Get().setEvilInterface( isOriginalEvilInterface );
if ( interfaceType != originalInterfaceType ) {
Settings::Get().setInterfaceType( originalInterfaceType );
}
}

Expand Down
9 changes: 5 additions & 4 deletions src/fheroes2/gui/ui_tool.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2020 - 2024 *
* Copyright (C) 2020 - 2025 *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
Expand Down Expand Up @@ -31,6 +31,7 @@

#include "image.h"
#include "math_base.h"
#include "settings.h"
#include "timing.h"
#include "ui_base.h"
#include "ui_text.h"
Expand Down Expand Up @@ -174,16 +175,16 @@ namespace fheroes2
struct GameInterfaceTypeRestorer
{
GameInterfaceTypeRestorer() = delete;
explicit GameInterfaceTypeRestorer( const bool isEvilInterface_ );
explicit GameInterfaceTypeRestorer( const InterfaceType interfaceType_ );

GameInterfaceTypeRestorer( const GameInterfaceTypeRestorer & ) = delete;

~GameInterfaceTypeRestorer();

GameInterfaceTypeRestorer & operator=( const GameInterfaceTypeRestorer & ) = delete;

const bool isEvilInterface;
const bool isOriginalEvilInterface;
const InterfaceType interfaceType;
const InterfaceType originalInterfaceType;
};

// Fade display image colors to grayscale part of default game palette.
Expand Down
81 changes: 65 additions & 16 deletions src/fheroes2/system/settings.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/***************************************************************************
* fheroes2: https://github.com/ihhub/fheroes2 *
* Copyright (C) 2019 - 2024 *
* Copyright (C) 2019 - 2025 *
* *
* Free Heroes2 Engine: http://sourceforge.net/projects/fheroes2 *
* Copyright (C) 2009 by Andrey Afletdinov <[email protected]> *
Expand Down Expand Up @@ -36,6 +36,7 @@
#include "game.h"
#include "game_io.h"
#include "logging.h"
#include "race.h"
#include "render_processor.h"
#include "save_format_version.h"
#include "screen.h"
Expand Down Expand Up @@ -235,8 +236,17 @@ bool Settings::Read( const std::string & filePath )
setBattleShowTurnOrder( config.StrParams( "battle turn order" ) == "on" );
}

if ( config.Exists( "use evil interface" ) ) {
setEvilInterface( config.StrParams( "use evil interface" ) == "on" );
Comment on lines -238 to -239
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we are breaking the existing settings players set. We should read the value of the previous setting.

if ( config.Exists( "interface type" ) ) {
const std::string interfaceType = config.StrParams( "interface type" );
if ( interfaceType == "Good" ) {
setInterfaceType( InterfaceType::GOOD );
}
else if ( interfaceType == "Evil" ) {
setInterfaceType( InterfaceType::EVIL );
}
else {
setInterfaceType( InterfaceType::DYNAMIC );
}
Districh-ru marked this conversation as resolved.
Show resolved Hide resolved
}

if ( config.Exists( "hide interface" ) ) {
Expand Down Expand Up @@ -432,8 +442,20 @@ std::string Settings::String() const
os << std::endl << "# show turn order during battle: on/off" << std::endl;
os << "battle turn order = " << ( _gameOptions.Modes( GAME_BATTLE_SHOW_TURN_ORDER ) ? "on" : "off" ) << std::endl;

os << std::endl << "# use evil interface style: on/off" << std::endl;
os << "use evil interface = " << ( _gameOptions.Modes( GAME_EVIL_INTERFACE ) ? "on" : "off" ) << std::endl;
os << std::endl << "# interface type (Good/Evil/Dynamic)" << std::endl;
switch ( _interfaceType ) {
case GOOD:
os << "interface type = Good" << std::endl;
break;
case EVIL:
os << "interface type = Evil" << std::endl;
break;
case DYNAMIC:
os << "interface type = Dynamic" << std::endl;
Comment on lines +449 to +455
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

None of settings have values starting from a capital letter. Please keep it the same way,.

break;
default:
assert( 0 );
}

os << std::endl << "# hide interface elements on the adventure map: on/off" << std::endl;
os << "hide interface = " << ( _gameOptions.Modes( GAME_HIDE_INTERFACE ) ? "on" : "off" ) << std::endl;
Expand Down Expand Up @@ -816,16 +838,6 @@ void Settings::setHideInterface( const bool enable )
}
}

void Settings::setEvilInterface( const bool enable )
{
if ( enable ) {
_gameOptions.SetModes( GAME_EVIL_INTERFACE );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GAME_EVIL_INTERFACE must be renamed into UNUSED_GAME_EVIL_INTERFACE as we are no longer supporting it.

}
else {
_gameOptions.ResetModes( GAME_EVIL_INTERFACE );
}
}

void Settings::setScreenScalingTypeNearest( const bool enable )
{
if ( enable ) {
Expand Down Expand Up @@ -883,9 +895,46 @@ bool Settings::isHideInterfaceEnabled() const
return _gameOptions.Modes( GAME_HIDE_INTERFACE );
}

void Settings::setInterfaceType( InterfaceType type )
{
assert( type >= InterfaceType::GOOD && type <= InterfaceType::DYNAMIC );
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of avoid this assertion we simply can remove InterfaceType::COUNT from the enumeration.

_interfaceType = type;
}

InterfaceType Settings::getInterfaceType() const
{
return _interfaceType;
}

bool Settings::isEvilInterfaceEnabled() const
{
return _gameOptions.Modes( GAME_EVIL_INTERFACE );
switch ( _interfaceType ) {
case InterfaceType::GOOD:
return false;
case InterfaceType::EVIL:
return true;
case InterfaceType::DYNAMIC: {
Player * player = Settings::Get().GetPlayers().GetCurrent();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method is not static. We should use its own methods within the body.

if ( !player )
return false;
Comment on lines +919 to +920
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it even possible?

Also, please parenthesis for this if-body.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be related to my last comment where the current player might not be set at the start of the game. I'll remove this check if I update the code once I find a way to only draw the interface once at the beginning of the game.


if ( player->isControlHuman() ) {
const int race = player->GetRace();
return race == Race::WRLK || race == Race::NECR || race == Race::BARB;
felix642 marked this conversation as resolved.
Show resolved Hide resolved
}

// Keep the UI of the last player during the AI turn
for ( auto iter = Settings::Get().GetPlayers().rbegin(); iter < Settings::Get().GetPlayers().rend(); ++iter ) {
if ( *iter && ( *iter )->isControlHuman() ) {
const int race = ( *iter )->GetRace();
return race == Race::WRLK || race == Race::NECR || race == Race::BARB;
}
}
return false;
}
default:
assert( 0 );
}
}

bool Settings::isEditorAnimationEnabled() const
Expand Down
12 changes: 11 additions & 1 deletion src/fheroes2/system/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ enum class ZoomLevel : uint8_t
ZoomLevel3 = 3, // Max zoom, but should only exists for debug builds
};

enum InterfaceType : uint8_t
{
GOOD = 0,
EVIL = 1,
DYNAMIC = 2,
};

class Settings
{
public:
Expand Down Expand Up @@ -191,6 +198,9 @@ class Settings
bool isHideInterfaceEnabled() const;
bool isEvilInterfaceEnabled() const;

void setInterfaceType( InterfaceType type );
InterfaceType getInterfaceType() const;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This method should be inlined.


bool isEditorAnimationEnabled() const;
bool isEditorPassabilityEnabled() const;

Expand Down Expand Up @@ -252,7 +262,6 @@ class Settings
void setAutoSaveAtBeginningOfTurn( const bool enable );
void setBattleDamageInfo( const bool enable );
void setHideInterface( const bool enable );
void setEvilInterface( const bool enable );
void setScreenScalingTypeNearest( const bool enable );

void SetSoundVolume( int v );
Expand Down Expand Up @@ -379,6 +388,7 @@ class Settings
int ai_speed;
int scroll_speed;
int battle_speed;
InterfaceType _interfaceType;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This member doesn't have default value.


int game_type;
ZoomLevel _viewWorldZoomLevel{ ZoomLevel::ZoomLevel1 };
Expand Down
Loading