From 24fe4da6bab74979718daa334248bc5863683cf2 Mon Sep 17 00:00:00 2001 From: Josh Cooper Date: Sun, 28 Aug 2022 18:11:50 -0700 Subject: [PATCH] Replaces spectate:auto-unpause with pausing API in World module --- plugins/spectate.cpp | 98 ++++++++++++++++++++++++++++++-------------- 1 file changed, 68 insertions(+), 30 deletions(-) diff --git a/plugins/spectate.cpp b/plugins/spectate.cpp index 3e745d6cd..b61d2d7fb 100644 --- a/plugins/spectate.cpp +++ b/plugins/spectate.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -16,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -47,6 +46,8 @@ REQUIRE_GLOBAL(d_init); // todo: implement as user configurable variables #define tick_span 50 #define base 0.99 +Pausing::AnnouncementLock* pause_lock = nullptr; +bool lock_collision = false; command_result spectate (color_ostream &out, std::vector & parameters); @@ -63,39 +64,28 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector follow_unit = our_dorf->id; - const int16_t &x = our_dorf->pos.x; - const int16_t &y = our_dorf->pos.y; - const int16_t &z = our_dorf->pos.z; - Gui::setViewCoords(x, y, z); - } -} - -void unpause(color_ostream &out) { - if (!world) return; - while (!world->status.popups.empty()) { - // dismiss announcement(s) - Gui::getCurViewscreen(true)->feed_key(interface_key::CLOSE_MEGA_ANNOUNCEMENT); - } - if (*pause_state) { - // unpause the game - Gui::getCurViewscreen(true)->feed_key(interface_key::D_PAUSE); - } - refresh_camera(out); -} - DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) { - if (enabled) { + if (enabled && world) { switch (event) { + case SC_WORLD_LOADED: + case SC_MAP_LOADED: + if (dismiss_pause_events && World::ReadPauseState()) { + *df::global::debug_nopause = false; + } + break; case SC_PAUSED: - if(dismiss_pause_events && !world->status.popups.empty()){ - unpause(out); - out.print("spectate: May the deities bless your dwarves.\n"); + if(dismiss_pause_events){ + if (our_dorf) { + df::global::ui->follow_unit = our_dorf->id; + const int16_t &x = our_dorf->pos.x; + const int16_t &y = our_dorf->pos.y; + const int16_t &z = our_dorf->pos.z; + Gui::setViewCoords(x, y, z); + } } break; case SC_UNPAUSED: @@ -112,9 +102,33 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan } DFhackCExport command_result plugin_shutdown (color_ostream &out) { + World::ReleasePauseLock(pause_lock); return CR_OK; } +DFhackCExport command_result plugin_onupdate(color_ostream &out) { + if (lock_collision) { + if (dismiss_pause_events) { + // player asked for auto-unpause enabled + World::SaveAnnouncementSettings(); + if (World::DisableAnnouncementPausing()){ + // now that we've got what we want, we can lock it down + lock_collision = false; + pause_lock->lock(); + } + } else { + if (World::RestoreAnnouncementSettings()) { + lock_collision = false; + } + } + } + while (dismiss_pause_events && !world->status.popups.empty()) { + // dismiss announcement popup(s) + Gui::getCurViewscreen(true)->feed_key(interface_key::CLOSE_MEGA_ANNOUNCEMENT); + } + return DFHack::CR_OK; +} + void onTick(color_ostream& out, void* tick); void onJobStart(color_ostream &out, void* job); void onJobCompletion(color_ostream &out, void* job); @@ -152,7 +166,31 @@ command_result spectate (color_ostream &out, std::vector & paramet out.print("todo?\n"); // todo: adventure as deity? } else if (parameters[0] == "auto-unpause") { dismiss_pause_events = !dismiss_pause_events; - out.print(dismiss_pause_events ? "auto-unpause: on\n" : "auto-unpause: off\n"); + + // update the announcement settings if we can + if (dismiss_pause_events) { + if (World::SaveAnnouncementSettings()) { + World::DisableAnnouncementPausing(); + pause_lock->lock(); + } else { + lock_collision = true; + } + } else { + pause_lock->unlock(); + if (!World::RestoreAnnouncementSettings()) { + // this in theory shouldn't happen, if others use the lock like we do in spectate + lock_collision = true; + } + } + + // report to the user how things went + if (!lock_collision){ + out.print(dismiss_pause_events ? "auto-unpause: on\n" : "auto-unpause: off\n"); + } else { + out.print("auto-unpause: must wait for another Pausing::AnnouncementLock to be lifted.\n"); + } + + // probably a typo if (parameters.size() == 2) { out.print("If you want additional options open an issue on github, or mention it on discord.\n"); return DFHack::CR_WRONG_USAGE;