From 6ec0fd6589042356e75dee3267097221bbb69054 Mon Sep 17 00:00:00 2001 From: lethosor Date: Tue, 3 Jun 2014 18:29:13 -0400 Subject: [PATCH] New tweak: confirm-embark Adds a confirmation when selecting [e]mbark on the "prepare carefully" screen. Suggested in multiple threads on forums. --- plugins/tweak.cpp | 95 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 90 insertions(+), 5 deletions(-) diff --git a/plugins/tweak.cpp b/plugins/tweak.cpp index d74ef0767..2136fff58 100644 --- a/plugins/tweak.cpp +++ b/plugins/tweak.cpp @@ -52,6 +52,7 @@ #include "df/reaction.h" #include "df/reaction_reagent_itemst.h" #include "df/reaction_reagent_flags.h" +#include "df/viewscreen_setupdwarfgamest.h" #include "df/viewscreen_layer_assigntradest.h" #include "df/viewscreen_tradegoodsst.h" #include "df/viewscreen_layer_militaryst.h" @@ -120,6 +121,8 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector \n" @@ -331,6 +334,83 @@ struct readable_build_plate_hook : df::viewscreen_dwarfmodest IMPLEMENT_VMETHOD_INTERPOSE(readable_build_plate_hook, render); +enum confirm_embark_states +{ + ECS_INACTIVE = 0, + ECS_CONFIRM, + ECS_ACCEPTED +}; +static confirm_embark_states confirm_embark_state = ECS_INACTIVE; + +struct confirm_embark_hook : df::viewscreen_setupdwarfgamest +{ + typedef df::viewscreen_setupdwarfgamest interpose_base; + + DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) + { + bool intercept = false; + df::viewscreen * top = Gui::getCurViewscreen(); + VIRTUAL_CAST_VAR(screen, df::viewscreen_setupdwarfgamest, top); + if (screen) + { + if (screen->anon_14 == 0) // Advanced embark screen + { + if (confirm_embark_state == ECS_INACTIVE) + { + if (input->count(df::interface_key::SETUP_EMBARK)) + { + confirm_embark_state = ECS_CONFIRM; + intercept = true; + } + } + else if (confirm_embark_state == ECS_CONFIRM) + { + intercept = true; + if (input->count(df::interface_key::MENU_CONFIRM)) + confirm_embark_state = ECS_ACCEPTED; + else if (input->size()) + confirm_embark_state = ECS_INACTIVE; + } + } + } + + if (!intercept) + INTERPOSE_NEXT(feed)(input); + } + + DEFINE_VMETHOD_INTERPOSE(void, render, ()) + { + INTERPOSE_NEXT(render)(); + df::viewscreen * top = Gui::getCurViewscreen(); + VIRTUAL_CAST_VAR(screen, df::viewscreen_setupdwarfgamest, top); + auto dim = Screen::getWindowSize(); + Screen::Pen pen(' ', COLOR_WHITE, COLOR_BLACK); + if (confirm_embark_state != ECS_INACTIVE) + { + Screen::fillRect(Screen::Pen(' ', COLOR_BLACK, COLOR_BLACK), 0, 0, dim.x - 1, dim.y - 1); + } + if (confirm_embark_state == ECS_CONFIRM) + { + Screen::paintString(pen, 2, 2, "Really embark?"); + Screen::paintString(Screen::Pen(' ', COLOR_LIGHTGREEN), + 2, 4, Screen::getKeyDisplay(df::interface_key::MENU_CONFIRM)); + Screen::paintString(pen, 3, 4, ": Confirm, Other: Cancel"); + Screen::paintString(pen, dim.x - 10, dim.y - 1, "DFHack"); + } + else if (confirm_embark_state == ECS_ACCEPTED) + { + Screen::paintString(pen, 2, 2, "Embarking..."); + std::set input; + input.insert(df::interface_key::SETUP_EMBARK); + screen->feed(&input); + confirm_embark_state = ECS_INACTIVE; + } + } +}; + +IMPLEMENT_VMETHOD_INTERPOSE(confirm_embark_hook, feed); +IMPLEMENT_VMETHOD_INTERPOSE(confirm_embark_hook, render); + struct stable_temp_hook : df::item_actual { typedef df::item_actual interpose_base; @@ -1150,7 +1230,7 @@ static command_result tweak(color_ostream &out, vector ¶meters) df::unit *unit = getSelectedUnit(out, true); if (!unit) return CR_FAILURE; - + if(unit->race != df::global::ui->race_id) { out << "Selected unit does not belong to your race!" << endl; @@ -1161,15 +1241,15 @@ static command_result tweak(color_ostream &out, vector ¶meters) // see http://dffd.wimbli.com/file.php?id=6139 for a save if (unit->flags2.bits.resident) unit->flags2.bits.resident = 0; - + // case #2: migrants who have the merchant flag // happens on almost all maps after a few migrant waves if(unit->flags1.bits.merchant) unit->flags1.bits.merchant = 0; - // this one is a cheat, but bugged migrants usually have the same civ_id + // this one is a cheat, but bugged migrants usually have the same civ_id // so it should not be triggered in most cases - // if it happens that the player has 'foreign' units of the same race + // if it happens that the player has 'foreign' units of the same race // (vanilla df: dwarves not from mountainhome) on his map, just grab them if(unit->civ_id != df::global::ui->civ_id) unit->civ_id = df::global::ui->civ_id; @@ -1216,6 +1296,11 @@ static command_result tweak(color_ostream &out, vector ¶meters) enable_hook(out, INTERPOSE_HOOK(readable_build_plate_hook, render), parameters); } + else if (cmd == "confirm-embark") + { + enable_hook(out, INTERPOSE_HOOK(confirm_embark_hook, feed), parameters); + enable_hook(out, INTERPOSE_HOOK(confirm_embark_hook, render), parameters); + } else if (cmd == "stable-temp") { enable_hook(out, INTERPOSE_HOOK(stable_temp_hook, adjustTemperature), parameters); @@ -1280,7 +1365,7 @@ static command_result tweak(color_ostream &out, vector ¶meters) enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_shoes_hook, incWearTimer), parameters); enable_hook(out, INTERPOSE_HOOK(adamantine_cloth_wear_pants_hook, incWearTimer), parameters); } - else + else return CR_WRONG_USAGE; return CR_OK;