Replaces spectate:auto-unpause with pausing API in World module

develop
Josh Cooper 2022-08-28 18:11:50 -07:00
parent 4fd6c52687
commit 24fe4da6ba
1 changed files with 68 additions and 30 deletions

@ -7,6 +7,7 @@
#include <Console.h>
#include <Export.h>
#include <PluginManager.h>
#include <modules/World.h>
#include <modules/EventManager.h>
#include <modules/Job.h>
#include <modules/Units.h>
@ -16,8 +17,6 @@
#include <df/global_objects.h>
#include <df/world.h>
#include <df/viewscreen.h>
#include <df/ui.h>
#include <df/interface_key.h>
#include <map>
#include <set>
@ -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 <std::string> & parameters);
@ -63,39 +64,28 @@ DFhackCExport command_result plugin_init (color_ostream &out, std::vector <Plugi
" spectate auto-unpause\n"
" toggle auto-dismissal of game pause events. e.g. a siege event pause\n"
"\n"));
pause_lock = World::AcquireAnnouncementPauseLock("spectate");
return CR_OK;
}
void refresh_camera(color_ostream &out) {
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);
}
}
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 <std::string> & 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;