diff --git a/changelog.md b/changelog.md index 5ffd04127c6..b0d2de61832 100644 --- a/changelog.md +++ b/changelog.md @@ -13,6 +13,7 @@ ### Units ### User interface ### WML Engine + * `[unit]dismissable` and `[unit]block_dismiss_message` keys added that allow marking an unit as dismissable, and what message to show if user clicks `Dismiss` button in Unit Recall dialog. ### Miscellaneous and Bug Fixes ## Version 1.19.9 diff --git a/data/schema/units/single.cfg b/data/schema/units/single.cfg index 6451ea6c4b5..67cdf575d64 100644 --- a/data/schema/units/single.cfg +++ b/data/schema/units/single.cfg @@ -12,6 +12,8 @@ {SIMPLE_KEY female_name t_string} {DEFAULT_KEY unrenamable s_bool no} {DEFAULT_KEY canrecruit s_bool no} + {DEFAULT_KEY dismissable s_bool yes} + {SIMPLE_KEY block_dismiss_message t_string} {SIMPLE_KEY extra_recruit string_list} {SIMPLE_KEY level s_int} {SIMPLE_KEY upkeep upkeep} diff --git a/data/test/scenarios/manual_tests/scenario-test.cfg b/data/test/scenarios/manual_tests/scenario-test.cfg index 90372afa68c..a6d4bc4f523 100644 --- a/data/test/scenarios/manual_tests/scenario-test.cfg +++ b/data/test/scenarios/manual_tests/scenario-test.cfg @@ -3433,6 +3433,8 @@ For game purposes, the races group into factions; for example, orcs often cooper side=1 x,y="recall","recall" type=Ancient Wose + dismissable=false + block_dismiss_message= _ "This Wose is so dedicated they refuse to leave your side." [/unit] [unit] diff --git a/src/gui/dialogs/units_dialog.cpp b/src/gui/dialogs/units_dialog.cpp index b61190ad7f6..8acb63ef4e6 100644 --- a/src/gui/dialogs/units_dialog.cpp +++ b/src/gui/dialogs/units_dialog.cpp @@ -22,6 +22,7 @@ #include "gettext.hpp" #include "gui/dialogs/edit_text.hpp" #include "gui/dialogs/message.hpp" +#include "gui/dialogs/transient_message.hpp" #include "gui/widgets/listbox.hpp" #include "gui/widgets/button.hpp" #include "gui/widgets/label.hpp" @@ -248,6 +249,11 @@ void units_dialog::dismiss_unit(std::vector& unit_list, const te const unit& u = *unit_list[selected_index_].get(); + if(!u.dismissable()) { + gui2::show_transient_message("", u.block_dismiss_message()); + return; + } + // If the unit is of level > 1, or is close to advancing, we warn the player about it std::stringstream message; if(u.loyal()) { diff --git a/src/units/unit.cpp b/src/units/unit.cpp index b86013f1eb3..9e5bad1d0ef 100644 --- a/src/units/unit.cpp +++ b/src/units/unit.cpp @@ -116,6 +116,8 @@ namespace "experience", "resting", "unrenamable", + "dismissable", + "block_dismiss_message", "alignment", "canrecruit", "extra_recruit", @@ -270,6 +272,8 @@ unit::unit(const unit& o) , flag_rgb_(o.flag_rgb_) , image_mods_(o.image_mods_) , unrenamable_(o.unrenamable_) + , dismissable_(o.dismissable_) + , dismiss_message_(o.dismiss_message_) , side_(o.side_) , gender_(o.gender_) , formula_man_(new unit_formula_manager(o.formula_manager())) @@ -350,6 +354,8 @@ unit::unit(unit_ctor_t) , flag_rgb_() , image_mods_() , unrenamable_(false) + , dismissable_(true) + , dismiss_message_(_("This unit cannot be dismissed.")) , side_(0) , gender_(unit_race::NUM_GENDERS) , formula_man_(new unit_formula_manager()) @@ -710,6 +716,15 @@ void unit::init(const config& cfg, bool use_traits, const vconfig* vcfg) resting_ = cfg["resting"].to_bool(); unrenamable_ = cfg["unrenamable"].to_bool(); + // leader units can't be dismissed by default + dismissable_ = cfg["dismissable"].to_bool(!canrecruit_); + if(canrecruit_) { + dismiss_message_ = _ ("This unit is a leader and cannot be dismissed."); + } + if(!cfg["block_dismiss_message"].blank()) { + dismiss_message_ = cfg["block_dismiss_message"].t_str(); + } + // We need to check to make sure that the cfg is not blank and if it // isn't pull that value otherwise it goes with the default of -1. if(!cfg["recall_cost"].blank()) { @@ -1637,6 +1652,8 @@ void unit::write(config& cfg, bool write_all) const } cfg["flag_rgb"] = flag_rgb_; cfg["unrenamable"] = unrenamable_; + cfg["dismissable"] = dismissable_; + cfg["block_dismiss_message"] = dismiss_message_; cfg["attacks_left"] = attacks_left_; if(write_all || get_attr_changed(UA_MAX_AP)) { diff --git a/src/units/unit.hpp b/src/units/unit.hpp index b48bf84d614..dd0a3931a23 100644 --- a/src/units/unit.hpp +++ b/src/units/unit.hpp @@ -446,6 +446,22 @@ public: unrenamable_ = unrenamable; } + /** + * Whether this unit can be dismissed. + * + * This flag is used by the Unit Recall dialog. + */ + bool dismissable() const + { + return dismissable_; + } + + /** A message of why this unit cannot be dismissed. */ + t_string block_dismiss_message() const + { + return dismiss_message_; + } + /** A detailed description of this unit. */ t_string unit_description() const { @@ -2020,6 +2036,8 @@ private: std::string image_mods_; bool unrenamable_; + bool dismissable_; + t_string dismiss_message_; int side_;