Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
c1fd654
Quick monster upgrade in towns
a1exsh Aug 22, 2021
b0cf669
Apply suggestions from code review
a1exsh Aug 22, 2021
fc115cf
Update src/fheroes2/castle/buildinginfo.h
a1exsh Aug 22, 2021
d7eca3c
fix formatting after suggestions from clang-tidy
a1exsh Aug 22, 2021
bcb27a8
one more
a1exsh Aug 22, 2021
ee1c4b7
fix implicit bool cast
a1exsh Aug 23, 2021
d892003
resize upgrade button for mini sprite display
a1exsh Aug 25, 2021
986791f
draw upgrade button when heroes are meeting each other
a1exsh Aug 25, 2021
35c2306
constify
a1exsh Aug 25, 2021
f01da55
return sprite by ref
a1exsh Aug 25, 2021
509a806
use lambda to initialize miniUpButton
a1exsh Aug 25, 2021
786d326
address comments, simplify some parts
a1exsh Aug 25, 2021
40f9096
extend active area of the button and make the left margin smaller
a1exsh Aug 25, 2021
afc6506
rename constant in camelCase
a1exsh Aug 26, 2021
5fbe9a0
Merge branch 'master' into quick-monster-upgrade
a1exsh Aug 27, 2021
be65b5c
Merge branch 'master' into quick-monster-upgrade
a1exsh Aug 29, 2021
59858d2
Add missing const which is present in source file
ihhub Sep 2, 2021
a081d34
Address comments from review
a1exsh Sep 2, 2021
d5aebc7
use a proper button icon
a1exsh Sep 7, 2021
47673b6
draw pressed and released states for the upgrade button
a1exsh Sep 8, 2021
18ae48c
fix missing override
a1exsh Sep 8, 2021
b4b3fc5
s/normal/pressed/
a1exsh Sep 9, 2021
cb413f1
fix parameter names
a1exsh Sep 10, 2021
97683ef
Merge branch 'master' of https://github.com/ihhub/fheroes2 into quick…
a1exsh Dec 20, 2021
5c8725b
fix compilation after merge
a1exsh Dec 20, 2021
1576369
remove shadow: it should be done differently
a1exsh Dec 20, 2021
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
128 changes: 116 additions & 12 deletions src/fheroes2/army/army_bar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@
#include "dialog_selectitems.h"
#include "game.h"
#include "icn.h"
#include "image_tool.h"
#include "race.h"
#include "screen.h"
#include "text.h"
#include "tools.h"
#include "translations.h"
Expand All @@ -37,6 +39,8 @@

namespace
{
const int32_t upgradeButtonMargin = 2;

void RedistributeArmy( ArmyTroop & troopFrom, ArmyTroop & troopTarget, Army * armyTarget )
{
const Army * armyFrom = troopFrom.GetArmy();
Expand Down Expand Up @@ -155,6 +159,44 @@ namespace

return false;
}

fheroes2::Sprite DrawUpgradeButton( const bool pressed )
{
const fheroes2::Sprite & original = fheroes2::AGG::GetICN( ICN::LISTBOX, pressed ? 4 : 3 );

fheroes2::Sprite result( original.width() - 4, original.height() - 3 );
const fheroes2::Point offset = pressed ? fheroes2::Point( 1, 3 ) : fheroes2::Point( 2, 2 );

fheroes2::Copy( original, offset.x, offset.y, result, 0, 0, result.width(), result.height() );
// remove black background
fheroes2::AddTransparency( result, 36 );

return result;
}

fheroes2::Sprite DrawMiniButton( const fheroes2::Sprite & original )
{
fheroes2::Sprite result( original.width() / 2, original.height() / 2 );
fheroes2::Resize( original, 0, 0, original.width(), original.height(), result, 0, 0, result.width(), result.height(), true );
return result;
}

const fheroes2::Sprite & GetUpgradeButton( const bool useMiniIcon, const bool pressed = false )
{
static const fheroes2::Sprite & btnReleased = DrawUpgradeButton( false );
static const fheroes2::Sprite & btnPressed = DrawUpgradeButton( true );
if ( useMiniIcon ) {
static const fheroes2::Sprite & btnReleasedMini = DrawMiniButton( btnReleased );
static const fheroes2::Sprite & btnPressedMini = DrawMiniButton( btnPressed );
return pressed ? btnPressedMini : btnReleasedMini;
}
return pressed ? btnPressed : btnReleased;
}

fheroes2::Rect getUpgradeButtonPos( const fheroes2::Sprite & upButton, const fheroes2::Rect & itemPos )
{
return { itemPos.x, itemPos.y, upButton.width() + 2 * upgradeButtonMargin, upButton.height() + 2 * upgradeButtonMargin };
}
}

ArmyBar::ArmyBar( Army * ptr, bool mini, bool ro, bool change /* false */ )
Expand Down Expand Up @@ -199,6 +241,38 @@ bool ArmyBar::isValid() const
return _army != nullptr;
}

fheroes2::Rect ArmyBar::GetUpgradeButtonPos( const fheroes2::Rect & itemPos ) const
{
return getUpgradeButtonPos( GetUpgradeButton( use_mini_sprite ), itemPos );
}

void ArmyBar::DrawUpgadeButton( const bool pressed, const fheroes2::Rect & pos, fheroes2::Image & outputImage ) const
{
const fheroes2::Sprite & upgradeButton = GetUpgradeButton( use_mini_sprite, pressed );
const fheroes2::Rect upButtonPos = getUpgradeButtonPos( upgradeButton, pos );
fheroes2::Blit( upgradeButton, outputImage, upButtonPos.x + upgradeButtonMargin, upButtonPos.y + upgradeButtonMargin );
}

bool ArmyBar::CanUpgradeNow( const ArmyTroop & troop ) const
{
const Castle * castle = _army->inCastle();
return troop.isAllowUpgrade() && castle && castle->GetRace() == troop.GetRace() && castle->isBuild( troop.GetUpgrade().GetDwelling() );
}

bool ArmyBar::CanAffordUpgrade( const ArmyTroop & troop ) const
{
return world.GetKingdom( _army->GetColor() ).AllowPayment( troop.GetUpgradeCost() );
}

void ArmyBar::UpgradeTroop( ArmyTroop & troop )
{
assert( CanUpgradeNow( troop ) );
assert( CanAffordUpgrade( troop ) );

world.GetKingdom( _army->GetColor() ).OddFundsResource( troop.GetUpgradeCost() );
troop.Upgrade();
}

void ArmyBar::SetBackground( const fheroes2::Size & sz, const uint8_t fillColor )
{
if ( use_mini_sprite ) {
Expand Down Expand Up @@ -274,6 +348,10 @@ void ArmyBar::RedrawItem( ArmyTroop & troop, const fheroes2::Rect & pos, bool se
fheroes2::Blit( spmonh, dstsf, pos.x + spmonh.x(), pos.y + spmonh.y() );
}

if ( CanUpgradeNow( troop ) ) {
DrawUpgadeButton( false, pos, dstsf );
}

if ( use_mini_sprite ) {
text.Blit( pos.x + pos.width - text.w() - 3, pos.y + pos.height - text.h(), dstsf );
}
Expand All @@ -300,7 +378,7 @@ void ArmyBar::Redraw( fheroes2::Image & dstsf )
Interface::ItemsActionBar<ArmyTroop>::Redraw( dstsf );
}

bool ArmyBar::ActionBarCursor( ArmyTroop & troop )
bool ArmyBar::ActionBarCursor( const fheroes2::Point & cursor, ArmyTroop & troop, const fheroes2::Rect & pos )
{
if ( troop.isValid() && !read_only && LocalEvent::Get().MouseClickMiddle() ) {
RedistributeTroopByOne( troop, _army );
Expand Down Expand Up @@ -334,8 +412,14 @@ bool ArmyBar::ActionBarCursor( ArmyTroop & troop )
}
}
else if ( troop.isValid() ) {
msg = _( "Select %{name}" );
StringReplace( msg, "%{name}", troop.GetName() );
if ( CanUpgradeNow( troop ) && ( GetUpgradeButtonPos( pos ) & cursor ) ) {
msg = _( "Upgrade %{name}" );
StringReplace( msg, "%{name}", troop.GetName() );
}
else {
msg = _( "Select %{name}" );
StringReplace( msg, "%{name}", troop.GetName() );
}
}

return false;
Expand Down Expand Up @@ -368,8 +452,15 @@ bool ArmyBar::ActionBarCursor( ArmyTroop & destTroop, ArmyTroop & selectedTroop
return false;
}

bool ArmyBar::ActionBarLeftMouseSingleClick( ArmyTroop & troop )
bool ArmyBar::ActionBarLeftMouseSingleClick( const fheroes2::Point & cursor, ArmyTroop & troop, const fheroes2::Rect & pos )
{
if ( !read_only ) {
// redraw upgrade button as released
if ( CanUpgradeNow( troop ) ) {
DrawUpgadeButton( false, pos, fheroes2::Display::instance() );
}
}

if ( isSelected() ) {
if ( read_only ) {
return false; // reset cursor
Expand Down Expand Up @@ -410,6 +501,13 @@ bool ArmyBar::ActionBarLeftMouseSingleClick( ArmyTroop & troop )
else if ( troop.isValid() ) {
if ( !read_only ) // select
{
if ( CanUpgradeNow( troop ) && ( GetUpgradeButtonPos( pos ) & cursor ) ) {
if ( Dialog::YES == Dialog::TroopUpgrade( troop, !CanAffordUpgrade( troop ) ) ) {
UpgradeTroop( troop );
}
return false;
}

if ( IsSplitHotkeyUsed( troop, _army ) )
return false;

Expand Down Expand Up @@ -515,7 +613,7 @@ bool ArmyBar::ActionBarLeftMouseSingleClick( ArmyTroop & destTroop, ArmyTroop &
return false; // reset cursor
}

bool ArmyBar::ActionBarLeftMouseDoubleClick( ArmyTroop & troop )
bool ArmyBar::ActionBarLeftMouseDoubleClick( const fheroes2::Point & /*cursor*/, ArmyTroop & troop, const fheroes2::Rect & /*pos*/ )
{
if ( troop.isValid() && !read_only && IsSplitHotkeyUsed( troop, _army ) ) {
ResetSelected();
Expand All @@ -527,21 +625,17 @@ bool ArmyBar::ActionBarLeftMouseDoubleClick( ArmyTroop & troop )

if ( &troop == troop2 ) {
int flags = ( read_only || _army->SaveLastTroop() ? Dialog::READONLY | Dialog::BUTTONS : Dialog::BUTTONS );
const Castle * castle = _army->inCastle();

if ( troop.isAllowUpgrade() &&
// allow upgrade
castle && castle->GetRace() == troop.GetRace() && castle->isBuild( troop.GetUpgrade().GetDwelling() ) ) {
if ( CanUpgradeNow( troop ) ) {
flags |= Dialog::UPGRADE;

if ( !world.GetKingdom( _army->GetColor() ).AllowPayment( troop.GetUpgradeCost() ) )
if ( !CanAffordUpgrade( troop ) )
flags |= Dialog::UPGRADE_DISABLE;
}

switch ( Dialog::ArmyInfo( troop, flags ) ) {
case Dialog::UPGRADE:
world.GetKingdom( _army->GetColor() ).OddFundsResource( troop.GetUpgradeCost() );
troop.Upgrade();
UpgradeTroop( troop );
break;

case Dialog::DISMISS:
Expand All @@ -558,6 +652,16 @@ bool ArmyBar::ActionBarLeftMouseDoubleClick( ArmyTroop & troop )
return true;
}

bool ArmyBar::ActionBarLeftMouseHold( const fheroes2::Point & cursor, ArmyTroop & troop, const fheroes2::Rect & pos )
{
if ( !read_only ) {
if ( CanUpgradeNow( troop ) && ( GetUpgradeButtonPos( pos ) & cursor ) ) {
DrawUpgadeButton( true, pos, fheroes2::Display::instance() );
}
}
return false;
}

bool ArmyBar::ActionBarLeftMouseRelease( ArmyTroop & troop )
{
if ( !read_only ) {
Expand Down
14 changes: 11 additions & 3 deletions src/fheroes2/army/army_bar.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,19 +42,27 @@ class ArmyBar : public Interface::ItemsActionBar<ArmyTroop>

bool isValid( void ) const;

fheroes2::Rect GetUpgradeButtonPos( const fheroes2::Rect & itemPos ) const;
void DrawUpgadeButton( const bool pressed, const fheroes2::Rect & pos, fheroes2::Image & outputImage ) const;

bool CanUpgradeNow( const ArmyTroop & troop ) const;
bool CanAffordUpgrade( const ArmyTroop & troop ) const;
void UpgradeTroop( ArmyTroop & troop );

void ResetSelected( void );
void Redraw( fheroes2::Image & dstsf = fheroes2::Display::instance() );

bool ActionBarLeftMouseSingleClick( ArmyTroop & troop ) override;
bool ActionBarLeftMouseSingleClick( const fheroes2::Point & cursor, ArmyTroop & troop, const fheroes2::Rect & pos ) override;
bool ActionBarLeftMouseSingleClick( ArmyTroop & destTroop, ArmyTroop & selectedTroop ) override;
bool ActionBarLeftMouseDoubleClick( ArmyTroop & troop ) override;
bool ActionBarLeftMouseDoubleClick( const fheroes2::Point & /*cursor*/, ArmyTroop & troop, const fheroes2::Rect & /*pos*/ ) override;
bool ActionBarLeftMouseRelease( ArmyTroop & troop ) override;
bool ActionBarLeftMouseHold( const fheroes2::Point & cursor, ArmyTroop & troop, const fheroes2::Rect & pos ) override;
bool ActionBarLeftMouseRelease( ArmyTroop & destTroop, ArmyTroop & troop ) override;
bool ActionBarRightMouseHold( ArmyTroop & troop ) override;
bool ActionBarRightMouseSingleClick( ArmyTroop & troop ) override;
bool ActionBarRightMouseSingleClick( ArmyTroop & destTroop, ArmyTroop & selectedTroop ) override;

bool ActionBarCursor( ArmyTroop & ) override;
bool ActionBarCursor( const fheroes2::Point & cursor, ArmyTroop & troop, const fheroes2::Rect & pos ) override;
bool ActionBarCursor( ArmyTroop &, ArmyTroop & ) override;

bool QueueEventProcessing( std::string * = nullptr );
Expand Down
2 changes: 1 addition & 1 deletion src/fheroes2/castle/buildinginfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -728,7 +728,7 @@ void DwellingsBar::RedrawItem( DwellingItem & dwl, const fheroes2::Rect & pos, f
fheroes2::Blit( fheroes2::AGG::GetICN( ICN::CSLMARKER, 0 ), dstsf, pos.x + pos.width - 10, pos.y + 4 );
}

bool DwellingsBar::ActionBarLeftMouseSingleClick( DwellingItem & dwl )
bool DwellingsBar::ActionBarLeftMouseSingleClick( const fheroes2::Point & /*unused*/, DwellingItem & dwl, const fheroes2::Rect & /*unused*/ )
{
if ( castle.isBuild( dwl.type ) ) {
castle.RecruitMonster( Dialog::RecruitMonster( dwl.mons, castle.getMonstersInDwelling( dwl.type ), true, 0 ) );
Expand Down
2 changes: 1 addition & 1 deletion src/fheroes2/castle/buildinginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class DwellingsBar : public Interface::ItemsBar<DwellingItem>
void RedrawBackground( const fheroes2::Rect &, fheroes2::Image & ) override;
void RedrawItem( DwellingItem &, const fheroes2::Rect &, fheroes2::Image & ) override;

bool ActionBarLeftMouseSingleClick( DwellingItem & dwelling ) override;
bool ActionBarLeftMouseSingleClick( const fheroes2::Point & /*unused*/, DwellingItem & dwl, const fheroes2::Rect & /*unused*/ ) override;
bool ActionBarRightMouseHold( DwellingItem & dwelling ) override;

protected:
Expand Down
6 changes: 6 additions & 0 deletions src/fheroes2/castle/castle_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -765,6 +765,12 @@ Castle::CastleDialogReturnValue Castle::OpenDialog( const bool readOnly, const b
BuyBuilding( build );
if ( BUILD_CAPTAIN == build )
RedrawIcons( *this, heroes, cur_pt );

// may render new quick upgrade possibilities
topArmyBar.Redraw();
if ( bottomArmyBar.isValid() && alphaHero >= 255 )
bottomArmyBar.Redraw();

fheroes2::drawCastleName( *this, display, cur_pt );
fheroes2::drawResourcePanel( GetKingdom().GetFunds(), display, cur_pt );
display.render();
Expand Down
1 change: 1 addition & 0 deletions src/fheroes2/dialog/dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ namespace Dialog
Troop RecruitMonster( const Monster & monster0, u32 available, const bool allowDowngradedMonster, const int32_t windowOffsetY );
void DwellingInfo( const Monster &, u32 available );
bool SetGuardian( Heroes &, Troop &, CapturedObject &, bool readonly );
int TroopUpgrade( const Troop & troop, const bool cannotAfford );
int ArmyInfo( const Troop & troop, int flags, bool isReflected = false );
int ArmyJoinFree( const Troop &, Heroes & );
int ArmyJoinWithCost( const Troop &, u32 join, u32 gold, Heroes & );
Expand Down
29 changes: 15 additions & 14 deletions src/fheroes2/dialog/dialog_armyinfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,17 @@ void DrawMonsterInfo( const fheroes2::Point & dst, const Troop & troop );
void DrawMonster( fheroes2::RandomMonsterAnimation & monsterAnimation, const Troop & troop, const fheroes2::Point & offset, bool isReflected, bool isAnimated,
const fheroes2::Rect & roi );

int Dialog::TroopUpgrade( const Troop & troop, const bool cannotAfford )
{
const payment_t cost = troop.GetUpgradeCost();

if ( cannotAfford ) {
return Dialog::ResourceInfo( "", _( "You can't afford to upgrade your troops!" ), cost, Dialog::OK );
}

return Dialog::ResourceInfo( "", _( "Your troops can be upgraded, but it will cost you dearly. Do you wish to upgrade them?" ), cost, Dialog::YES | Dialog::NO );
}

int Dialog::ArmyInfo( const Troop & troop, int flags, bool isReflected )
{
// The active size of the window is 520 by 256 pixels
Expand Down Expand Up @@ -216,20 +227,10 @@ int Dialog::ArmyInfo( const Troop & troop, int flags, bool isReflected )

// upgrade
if ( buttonUpgrade.isEnabled() && ( le.MouseClickLeft( buttonUpgrade.area() ) || Game::HotKeyPressEvent( Game::EVENT_UPGRADE_TROOP ) ) ) {
if ( UPGRADE_DISABLE & flags ) {
const std::string msg( _( "You can't afford to upgrade your troops!" ) );
if ( Dialog::YES == Dialog::ResourceInfo( "", msg, troop.GetUpgradeCost(), Dialog::OK ) ) {
result = Dialog::UPGRADE;
break;
}
}
else {
const std::string msg = _( "Your troops can be upgraded, but it will cost you dearly. Do you wish to upgrade them?" );

if ( Dialog::YES == Dialog::ResourceInfo( "", msg, troop.GetUpgradeCost(), Dialog::YES | Dialog::NO ) ) {
result = Dialog::UPGRADE;
break;
}
const bool cannotAfford = UPGRADE_DISABLE == ( UPGRADE_DISABLE & flags );
if ( Dialog::YES == Dialog::TroopUpgrade( troop, cannotAfford ) ) {
result = Dialog::UPGRADE;
break;
}
}
// dismiss
Expand Down
Loading