diff --git a/library/Core.cpp b/library/Core.cpp index 8adbf3742..0a7cbefd4 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -609,6 +609,7 @@ Core::Core() HotkeyCond = 0; misc_data_mutex=0; last_world_data_ptr = NULL; + last_local_map_ptr = NULL; top_viewscreen = NULL; screen_window = NULL; server = NULL; @@ -869,16 +870,41 @@ int Core::Update() // detect if the game was loaded or unloaded in the meantime void *new_wdata = NULL; - if (df::global::world) { + void *new_mapdata = NULL; + if (df::global::world) + { df::world_data *wdata = df::global::world->world_data; // when the game is unloaded, world_data isn't deleted, but its contents are if (wdata && !wdata->sites.empty()) new_wdata = wdata; + new_mapdata = df::global::world->map.block_index; } - - if (new_wdata != last_world_data_ptr) { + // if the world changes + if (new_wdata != last_world_data_ptr) + { + // we check for map change too + bool mapchange = new_mapdata != last_local_map_ptr; + // and if the world is going away, we report the map change first + if(!new_wdata && mapchange) + { + last_local_map_ptr = new_mapdata; + plug_mgr->OnStateChange(out, new_mapdata ? SC_MAP_LOADED : SC_MAP_UNLOADED); + } + // and if the world is appearing, we report map change after that + plug_mgr->OnStateChange(out, new_wdata ? SC_WORLD_LOADED : SC_WORLD_UNLOADED); + if(new_wdata && mapchange) + { + last_local_map_ptr = new_mapdata; + plug_mgr->OnStateChange(out, new_mapdata ? SC_MAP_LOADED : SC_MAP_UNLOADED); + } + // update tracking variable last_world_data_ptr = new_wdata; - plug_mgr->OnStateChange(out, new_wdata ? SC_GAME_LOADED : SC_GAME_UNLOADED); + } + // otherwise just check for map change... + else if (new_mapdata != last_local_map_ptr) + { + last_local_map_ptr = new_mapdata; + plug_mgr->OnStateChange(out, new_mapdata ? SC_MAP_LOADED : SC_MAP_UNLOADED); } // detect if the viewscreen changed diff --git a/library/include/Core.h b/library/include/Core.h index f73ab08e8..290a324b9 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -126,6 +126,7 @@ namespace DFHack std::vector ListKeyBindings(std::string keyspec); bool isWorldLoaded() { return (last_world_data_ptr != NULL); } + bool isMapLoaded() { return (last_local_map_ptr != NULL && last_world_data_ptr != NULL); } static df::viewscreen *getTopViewscreen() { return getInstance().top_viewscreen; } @@ -194,7 +195,10 @@ namespace DFHack int UnicodeAwareSym(const SDL::KeyboardEvent& ke); bool SelectHotkey(int key, int modifiers); - void *last_world_data_ptr; // for state change tracking + // for state change tracking + void *last_world_data_ptr; + // for state change tracking + void *last_local_map_ptr; df::viewscreen *top_viewscreen; // Very important! bool started; diff --git a/library/include/PluginManager.h b/library/include/PluginManager.h index 86f7a4b2f..8f02099be 100644 --- a/library/include/PluginManager.h +++ b/library/include/PluginManager.h @@ -52,8 +52,10 @@ namespace DFHack enum state_change_event { - SC_GAME_LOADED, - SC_GAME_UNLOADED, + SC_WORLD_LOADED, + SC_WORLD_UNLOADED, + SC_MAP_LOADED, + SC_MAP_UNLOADED, SC_VIEWSCREEN_CHANGED }; struct DFHACK_EXPORT PluginCommand diff --git a/plugins/advtools.cpp b/plugins/advtools.cpp index f88ba6f59..4fc1b4e5d 100644 --- a/plugins/advtools.cpp +++ b/plugins/advtools.cpp @@ -101,8 +101,8 @@ static bool in_transient_swap = false; DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) { switch (event) { - case SC_GAME_LOADED: - case SC_GAME_UNLOADED: + case SC_WORLD_LOADED: + case SC_WORLD_UNLOADED: in_transient_swap = false; break; default: diff --git a/plugins/devel/kittens.cpp b/plugins/devel/kittens.cpp index 67e7ca03a..5dbadcc72 100644 --- a/plugins/devel/kittens.cpp +++ b/plugins/devel/kittens.cpp @@ -22,6 +22,7 @@ bool final_flag = true; bool timering = false; bool trackmenu_flg = false; bool trackpos_flg = false; +bool statetrack = false; int32_t last_designation[3] = {-30000, -30000, -30000}; int32_t last_mouse[2] = {-1, -1}; uint32_t last_menu = 0; @@ -31,6 +32,7 @@ command_result kittens (color_ostream &out, vector & parameters); command_result ktimer (color_ostream &out, vector & parameters); command_result trackmenu (color_ostream &out, vector & parameters); command_result trackpos (color_ostream &out, vector & parameters); +command_result trackstate (color_ostream &out, vector & parameters); command_result colormods (color_ostream &out, vector & parameters); command_result zoom (color_ostream &out, vector & parameters); @@ -42,6 +44,7 @@ DFhackCExport command_result plugin_init ( color_ostream &out, std::vector & parameters) return CR_OK; } +command_result trackstate ( color_ostream& out, vector< string >& parameters ) +{ + statetrack = !statetrack; + return CR_OK; +} + command_result colormods (color_ostream &out, vector & parameters) { CoreSuspender suspend; diff --git a/plugins/follow.cpp b/plugins/follow.cpp index b383d95ce..96693df8d 100644 --- a/plugins/follow.cpp +++ b/plugins/follow.cpp @@ -48,8 +48,8 @@ DFhackCExport command_result plugin_shutdown ( color_ostream &out ) DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event) { switch (event) { - case SC_GAME_LOADED: - case SC_GAME_UNLOADED: //Make sure our plugin's variables are clean + case SC_MAP_LOADED: + case SC_MAP_UNLOADED: //Make sure our plugin's variables are clean followedUnit = 0; prevX=prevY=prevZ = -1; prevMenuWidth = 0; diff --git a/plugins/seedwatch.cpp b/plugins/seedwatch.cpp index 77d25cf68..b6097f628 100755 --- a/plugins/seedwatch.cpp +++ b/plugins/seedwatch.cpp @@ -272,8 +272,8 @@ DFhackCExport command_result plugin_init(color_ostream &out, vector