Finalizes spectate update

- Fixes for state transitions that were found broken. eg. plugin disabled -> enable auto-unpause feature -> enable plugin (auto-unpause will not truly be enabled; similar transitions were broken)
- Adds a commented out lock for if the pause code is ever adopted into the core API, as to enable many mods to use the `World::SetPauseState()` without walking over each other, and in the case of `reveal hell` also be able to avoid needing to set the state every tick in onupdate
- Revises the usage docs with `enable|disable|set` syntax
develop
Josh Cooper 2022-10-14 17:02:43 -07:00
parent 736313d16b
commit 45ac340f37
3 changed files with 37 additions and 32 deletions

@ -11,7 +11,8 @@ Usage
::
enable spectate
spectate <option> <value>
spectate set tick-threshold <value>
spectate enable|disable <feature>
When enabled, the plugin will automatically switch which dwarf is being

@ -49,6 +49,19 @@ namespace DFHack {
bool isOnlyLocked() const override; // returns true if locked and no other instance is locked
void reportLocks(color_ostream &out) override;
};
// non-blocking lock resource used in conjunction with the pause set state function in World
// todo: integrate with World::SetPauseState
// class PauseStateLock : public Lock
// {
// static std::unordered_set<Lock*> locks;
// public:
// explicit PauseStateLock(const char* name): Lock(name) { locks.emplace(this); }
// ~PauseStateLock() override { locks.erase(this); }
// bool isAnyLocked() const override; // returns true if any instance of PlayerLock is locked
// bool isOnlyLocked() const override; // returns true if locked and no other instance is locked
// void reportLocks(color_ostream &out) override;
// };
}
namespace World {
bool DisableAnnouncementPausing(); // disable announcement pausing if all locks are open

@ -136,7 +136,6 @@ DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) {
EM::registerListener(EventType::TICK, ticking, plugin_self);
EM::registerListener(EventType::JOB_STARTED, start, plugin_self);
EM::registerListener(EventType::JOB_COMPLETED, complete, plugin_self);
out.print("running: spectate auto-unpause %d\n", unpause_enabled);
enabled = true; // enable_auto_unpause won't do anything without this set now
enable_auto_unpause(out, unpause_enabled);
} else if (!enable && enabled) {
@ -191,6 +190,7 @@ DFhackCExport command_result plugin_onupdate(color_ostream &out) {
// dismiss announcement popup(s)
Gui::getCurViewscreen(true)->feed_key(interface_key::CLOSE_MEGA_ANNOUNCEMENT);
if (World::ReadPauseState()) {
// WARNING: This has a possibility of conflicting with `reveal hell` - if Hermes himself runs `reveal hell` on precisely the right moment that is
World::SetPauseState(false);
}
}
@ -257,37 +257,28 @@ void enable_auto_unpause(color_ostream &out, bool state) {
command_result spectate (color_ostream &out, std::vector <std::string> & parameters) {
if (!parameters.empty()) {
if (parameters.size() % 2 != 0) {
return DFHack::CR_WRONG_USAGE;
}
for (size_t i = 0; i + 1 < parameters.size(); i += 2) {
if (parameters[i] == "auto-unpause") {
if (parameters[i + 1] == "0") {
enable_auto_unpause(out, false);
} else if (parameters[i + 1] == "1") {
enable_auto_unpause(out, true);
} else {
return DFHack::CR_WRONG_USAGE;
}
} else if (parameters[i] == "auto-disengage") {
if (parameters[i + 1] == "0") {
disengage_enabled = false;
} else if (parameters[i + 1] == "1") {
disengage_enabled = true;
} else {
return DFHack::CR_WRONG_USAGE;
}
} else if (parameters[i] == "focus-jobs") {
if (parameters[i + 1] == "0") {
focus_jobs_enabled = false;
} else if (parameters[i + 1] == "1") {
focus_jobs_enabled = true;
if (parameters.size() >= 2 && parameters.size() <= 3) {
bool state;
bool set = false;
if (parameters[0] == "enable") {
state = true;
} else if (parameters[0] == "disable") {
state = false;
} else if (parameters[0] == "set") {
set = true;
} else {
return DFHack::CR_WRONG_USAGE;
}
} else if (parameters[i] == "tick-threshold") {
auto &arg = parameters[1];
if(arg == "auto-unpause"){
enable_auto_unpause(out, state);
} else if (arg == "auto-disengage") {
disengage_enabled = state;
} else if (arg == "focus-jobs") {
focus_jobs_enabled = state;
} else if (arg == "tick-threshold" && set && parameters.size() == 3) {
try {
tick_threshold = std::stol(parameters[i + 1]);
tick_threshold = std::stol(parameters[2]);
} catch (const std::exception &e) {
out.printerr("%s\n", e.what());
}