Refactor debug mode unit creation.
The goal is to merge three code paths so they are easier to update. When GUI2 is ready, it might make sense to merge choose_unit_2() into menu_handler::create_unit().
This commit is contained in:
parent
da968a4a34
commit
e99cc26bba
2 changed files with 164 additions and 136 deletions
|
@ -903,139 +903,170 @@ unit_map::iterator menu_handler::current_unit()
|
|||
}
|
||||
}
|
||||
|
||||
void menu_handler::create_unit_2(mouse_handler& mousehandler)
|
||||
{
|
||||
assert(gui_ != NULL);
|
||||
//
|
||||
// The unit creation dialog makes sure unit types
|
||||
// are properly cached.
|
||||
//
|
||||
gui2::tunit_create create_dlg;
|
||||
create_dlg.show(gui_->video());
|
||||
namespace { // Helpers for create_unit()
|
||||
/// Allows a function to return both a type and a gender.
|
||||
typedef std::pair<const unit_type *, unit_race::GENDER> type_and_gender;
|
||||
|
||||
if(create_dlg.no_choice()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string& ut_id = create_dlg.choice();
|
||||
const unit_type *utp = unit_types.find(ut_id);
|
||||
if (!utp) {
|
||||
ERR_NG << "Create unit dialog returned nonexistent or unusable unit_type id '" << ut_id << "'.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
const unit_type &ut = *utp;
|
||||
|
||||
unit_race::GENDER gender = create_dlg.gender();
|
||||
|
||||
// Do not try to set bad genders, may mess up l10n
|
||||
// FIXME: is this actually necessary?
|
||||
if(ut.genders().end() == std::find(ut.genders().begin(), ut.genders().end(), gender)) {
|
||||
gender = ut.genders().front();
|
||||
}
|
||||
|
||||
unit chosen(ut, 1, true, gender);
|
||||
chosen.new_turn();
|
||||
|
||||
const map_location& loc = mousehandler.get_last_hex();
|
||||
units_.replace(loc, chosen);
|
||||
|
||||
if(map_.is_village(loc)) {
|
||||
actions::get_village(loc, chosen.side());
|
||||
}
|
||||
|
||||
gui_->invalidate(loc);
|
||||
gui_->invalidate_unit();
|
||||
}
|
||||
|
||||
void menu_handler::create_unit(mouse_handler& mousehandler)
|
||||
{
|
||||
if(gui2::new_widgets) {
|
||||
create_unit_2(mousehandler);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> options;
|
||||
static int last_selection = -1;
|
||||
static bool random_gender = false;
|
||||
std::vector<const unit_type*> unit_choices;
|
||||
const std::string heading = std::string(1,HEADING_PREFIX) +
|
||||
_("Race") + COLUMN_SEPARATOR +
|
||||
_("Type");
|
||||
options.push_back(heading);
|
||||
|
||||
BOOST_FOREACH(const unit_type_data::unit_type_map::value_type &i, unit_types.types())
|
||||
/**
|
||||
* Allows the user to select a type of unit, using GUI2.
|
||||
* (Intended for use when a unit is created in debug mode via hotkey or
|
||||
* context menu.)
|
||||
* @returns the selected type and gender. If this is canceled, the
|
||||
* returned type is NULL.
|
||||
*
|
||||
* @todo Replace choose_unit() when complete.
|
||||
*/
|
||||
type_and_gender choose_unit_2(game_display& gui)
|
||||
{
|
||||
std::stringstream row;
|
||||
//
|
||||
// The unit creation dialog makes sure unit types
|
||||
// are properly cached.
|
||||
//
|
||||
gui2::tunit_create create_dlg;
|
||||
create_dlg.show(gui.video());
|
||||
|
||||
// Make sure the unit type was built for the data we need.
|
||||
unit_types.build_unit_type(i.second, unit_type::HELP_INDEX);
|
||||
|
||||
row << i.second.race()->plural_name() << COLUMN_SEPARATOR;
|
||||
row << i.second.type_name() << COLUMN_SEPARATOR;
|
||||
|
||||
options.push_back(row.str());
|
||||
unit_choices.push_back(&i.second);
|
||||
}
|
||||
|
||||
int choice = 0;
|
||||
bool random_gender_choice = random_gender;
|
||||
{
|
||||
gui::dialog umenu(*gui_, _("Create Unit (Debug!)"), "", gui::OK_CANCEL);
|
||||
|
||||
umenu.add_option(
|
||||
(formatter()<<_("Gender: ")<<_("gender^Random")).str(),
|
||||
random_gender_choice,
|
||||
gui::dialog::BUTTON_EXTRA
|
||||
);
|
||||
|
||||
gui::menu::basic_sorter sorter;
|
||||
sorter.set_alpha_sort(0).set_alpha_sort(1);
|
||||
umenu.set_menu(options, &sorter);
|
||||
|
||||
gui::filter_textbox* filter = new gui::filter_textbox(gui_->video(),
|
||||
_("Filter: "), options, options, 1, umenu, 200);
|
||||
umenu.set_textbox(filter);
|
||||
|
||||
//sort by race then by type name
|
||||
umenu.get_menu().sort_by(1);
|
||||
umenu.get_menu().sort_by(0);
|
||||
if (last_selection >= 0)
|
||||
umenu.get_menu().move_selection(last_selection);
|
||||
else
|
||||
umenu.get_menu().reset_selection();
|
||||
|
||||
dialogs::unit_types_preview_pane unit_preview(unit_choices, filter, 1, dialogs::unit_types_preview_pane::SHOW_ALL);
|
||||
umenu.add_pane(&unit_preview);
|
||||
unit_preview.set_selection(umenu.get_menu().selection());
|
||||
|
||||
choice = umenu.show();
|
||||
choice = filter->get_index(choice);
|
||||
random_gender_choice = umenu.option_checked(0);
|
||||
}
|
||||
|
||||
if (size_t(choice) < unit_choices.size()) {
|
||||
last_selection = choice;
|
||||
random_gender = random_gender_choice;
|
||||
|
||||
const unit_type& type = *unit_choices[choice];
|
||||
const unit_race::GENDER gender = random_gender ? unit_race::NUM_GENDERS :
|
||||
type.genders().front();
|
||||
|
||||
unit chosen(type, 1, true, gender);
|
||||
chosen.new_turn();
|
||||
|
||||
const map_location loc = mousehandler.get_last_hex();
|
||||
units_.replace(loc, chosen);
|
||||
unit_display::unit_recruited(loc);
|
||||
|
||||
if(map_.is_village(loc)) {
|
||||
actions::get_village(loc, chosen.side());
|
||||
if(create_dlg.no_choice()) {
|
||||
return type_and_gender(NULL, unit_race::NUM_GENDERS);
|
||||
}
|
||||
|
||||
gui_->invalidate(loc);
|
||||
gui_->invalidate_unit();
|
||||
const std::string& ut_id = create_dlg.choice();
|
||||
const unit_type *utp = unit_types.find(ut_id);
|
||||
if (!utp) {
|
||||
ERR_NG << "Create unit dialog returned nonexistent or unusable unit_type id '" << ut_id << "'.\n";
|
||||
return type_and_gender(NULL, unit_race::NUM_GENDERS);
|
||||
}
|
||||
const unit_type &ut = *utp;
|
||||
|
||||
unit_race::GENDER gender = create_dlg.gender();
|
||||
// Do not try to set bad genders, may mess up l10n
|
||||
/// @todo Is this actually necessary?
|
||||
/// (Maybe create_dlg can enforce proper gender selection?)
|
||||
if(ut.genders().end() == std::find(ut.genders().begin(), ut.genders().end(), gender)) {
|
||||
gender = ut.genders().front();
|
||||
}
|
||||
|
||||
return type_and_gender(utp, gender);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows the user to select a type of unit.
|
||||
* (Intended for use when a unit is created in debug mode via hotkey or
|
||||
* context menu.)
|
||||
* @returns the selected type and gender. If this is canceled, the
|
||||
* returned type is NULL.
|
||||
*/
|
||||
type_and_gender choose_unit(game_display& gui)
|
||||
{
|
||||
std::vector<std::string> options;
|
||||
static int last_selection = -1;
|
||||
static bool random_gender = false;
|
||||
std::vector<const unit_type*> unit_choices;
|
||||
const std::string heading = std::string(1,HEADING_PREFIX) +
|
||||
_("Race") + COLUMN_SEPARATOR +
|
||||
_("Type");
|
||||
options.push_back(heading);
|
||||
|
||||
BOOST_FOREACH(const unit_type_data::unit_type_map::value_type &i, unit_types.types())
|
||||
{
|
||||
std::stringstream row;
|
||||
|
||||
// Make sure the unit type was built for the data we need.
|
||||
unit_types.build_unit_type(i.second, unit_type::HELP_INDEX);
|
||||
|
||||
row << i.second.race()->plural_name() << COLUMN_SEPARATOR;
|
||||
row << i.second.type_name() << COLUMN_SEPARATOR;
|
||||
|
||||
options.push_back(row.str());
|
||||
unit_choices.push_back(&i.second);
|
||||
}
|
||||
|
||||
int choice = 0;
|
||||
bool random_gender_choice = random_gender;
|
||||
{
|
||||
gui::dialog umenu(gui, _("Create Unit (Debug!)"), "", gui::OK_CANCEL);
|
||||
|
||||
umenu.add_option(
|
||||
(formatter()<<_("Gender: ")<<_("gender^Random")).str(),
|
||||
random_gender_choice,
|
||||
gui::dialog::BUTTON_EXTRA
|
||||
);
|
||||
|
||||
gui::menu::basic_sorter sorter;
|
||||
sorter.set_alpha_sort(0).set_alpha_sort(1);
|
||||
umenu.set_menu(options, &sorter);
|
||||
|
||||
gui::filter_textbox* filter = new gui::filter_textbox(gui.video(),
|
||||
_("Filter: "), options, options, 1, umenu, 200);
|
||||
umenu.set_textbox(filter);
|
||||
|
||||
//sort by race then by type name
|
||||
umenu.get_menu().sort_by(1);
|
||||
umenu.get_menu().sort_by(0);
|
||||
if (last_selection >= 0)
|
||||
umenu.get_menu().move_selection(last_selection);
|
||||
else
|
||||
umenu.get_menu().reset_selection();
|
||||
|
||||
dialogs::unit_types_preview_pane unit_preview(unit_choices, filter, 1, dialogs::unit_types_preview_pane::SHOW_ALL);
|
||||
umenu.add_pane(&unit_preview);
|
||||
unit_preview.set_selection(umenu.get_menu().selection());
|
||||
|
||||
choice = umenu.show();
|
||||
choice = filter->get_index(choice);
|
||||
random_gender_choice = umenu.option_checked(0);
|
||||
}
|
||||
|
||||
if (size_t(choice) < unit_choices.size()) {
|
||||
last_selection = choice;
|
||||
random_gender = random_gender_choice;
|
||||
|
||||
return type_and_gender(unit_choices[choice],
|
||||
random_gender ? unit_race::NUM_GENDERS :
|
||||
unit_choices[choice]->genders().front());
|
||||
}
|
||||
else
|
||||
return type_and_gender(NULL, unit_race::NUM_GENDERS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a unit and places it on the board.
|
||||
* (Intended for use with any units created via debug mode.)
|
||||
*/
|
||||
void create_and_place(game_display& gui, const gamemap & map, unit_map & units,
|
||||
const map_location & loc, const unit_type & u_type,
|
||||
unit_race::GENDER gender = unit_race::NUM_GENDERS)
|
||||
{
|
||||
// Create the unit.
|
||||
unit created(u_type, 1, true, gender);
|
||||
created.new_turn();
|
||||
|
||||
// Add the unit to the board.
|
||||
std::pair<unit_map::iterator, bool> add_result =
|
||||
units.replace(loc, created);
|
||||
gui.invalidate_unit();
|
||||
unit_display::unit_recruited(loc);
|
||||
|
||||
if ( map.is_village(loc) )
|
||||
actions::get_village(loc, created.side());
|
||||
}
|
||||
|
||||
}// Anonymous namespace
|
||||
|
||||
|
||||
/**
|
||||
* Creates a unit (in debug mode via hotkey or context menu).
|
||||
*/
|
||||
void menu_handler::create_unit(mouse_handler& mousehandler)
|
||||
{
|
||||
assert(gui_ != NULL);
|
||||
|
||||
// Let the user select the kind of unit to create.
|
||||
type_and_gender selection = gui2::new_widgets ? choose_unit_2(*gui_) :
|
||||
choose_unit(*gui_);
|
||||
if ( selection.first != NULL )
|
||||
// Make it so.
|
||||
create_and_place(*gui_, map_, units_, mousehandler.get_last_hex(),
|
||||
*selection.first, selection.second);
|
||||
}
|
||||
|
||||
void menu_handler::change_side(mouse_handler& mousehandler)
|
||||
|
@ -3049,6 +3080,9 @@ void console_handler::do_undiscover() {
|
|||
preferences::encountered_units().clear();
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Implements the (debug mode) console command that creates a unit.
|
||||
*/
|
||||
void console_handler::do_create() {
|
||||
const mouse_handler& mousehandler = resources::controller->get_mouse_handler_base();
|
||||
const map_location &loc = mousehandler.get_last_hex();
|
||||
|
@ -3059,14 +3093,9 @@ void console_handler::do_create() {
|
|||
return;
|
||||
}
|
||||
|
||||
menu_handler_.units_.erase(loc);
|
||||
|
||||
unit created(*ut, 1, true);
|
||||
created.new_turn();
|
||||
|
||||
menu_handler_.units_.add(loc, created);
|
||||
menu_handler_.gui_->invalidate(loc);
|
||||
menu_handler_.gui_->invalidate_unit();
|
||||
// Create the unit.
|
||||
create_and_place(*menu_handler_.gui_, menu_handler_.map_,
|
||||
menu_handler_.units_, loc, *ut);
|
||||
} else {
|
||||
command_failed(_("Invalid location"));
|
||||
}
|
||||
|
|
|
@ -65,7 +65,6 @@ public:
|
|||
void unit_description();
|
||||
void rename_unit();
|
||||
void create_unit(mouse_handler& mousehandler);
|
||||
void create_unit_2(mouse_handler& mousehandler); // TODO: replace create_unit when complete
|
||||
void change_side(mouse_handler& mousehandler);
|
||||
void kill_unit(mouse_handler& mousehandler);
|
||||
void label_terrain(mouse_handler& mousehandler, bool team_only);
|
||||
|
|
Loading…
Add table
Reference in a new issue