static bool isOptionEnabled(unsigned flag) { return config.isValid() && (config.ival(0) & flag) != 0; }
static int dfhack_persistent_save(lua_State *state) { CoreSuspender suspend; lua_settop(state, 2); luaL_checktype(state, 1, LUA_TTABLE); bool add = lua_toboolean(state, 2); lua_getfield(state, 1, "key"); const char *str = lua_tostring(state, -1); if (!str) luaL_argerror(state, 1, "no key field"); lua_settop(state, 1); // Retrieve existing or create a new entry PersistentDataItem ref; bool added = false; if (add) { ref = World::AddPersistentData(str); added = true; } else if (lua_getmetatable(state, 1)) { if (!lua_rawequal(state, -1, lua_upvalueindex(1))) return luaL_argerror(state, 1, "invalid table type"); lua_pop(state, 1); ref = persistent_by_struct(state, 1); } else { ref = World::GetPersistentData(str); } // Auto-add if not found if (!ref.isValid()) { ref = World::AddPersistentData(str); if (!ref.isValid()) luaL_error(state, "cannot create persistent entry"); added = true; } // Copy data from lua to C++ memory lua_getfield(state, 1, "value"); if (const char *str = lua_tostring(state, -1)) ref.val() = str; lua_pop(state, 1); lua_getfield(state, 1, "ints"); if (lua_istable(state, -1)) { for (int i = 0; i < PersistentDataItem::NumInts; i++) { lua_rawgeti(state, -1, i+1); if (lua_isnumber(state, -1)) ref.ival(i) = lua_tointeger(state, -1); lua_pop(state, 1); } } lua_pop(state, 1); // Reinitialize lua from C++ and return read_persistent(state, ref, false); lua_pushboolean(state, added); return 2; }
/** * Initialize the plugin labor lists */ static void init_state() { // This obtains the persistent data from the world save file config = World::GetPersistentData("autohauler/config"); // Check to ensure that the persistent data item actually exists and that // the first item in the array of ints isn't -1 (implies disabled) if (config.isValid() && config.ival(0) == -1) config.ival(0) = 0; // Check to see if the plugin is enabled in the persistent data, if so then // enable the local flag for autohauler being enabled enable_autohauler = isOptionEnabled(CF_ENABLED); // If autohauler is not enabled then it's pretty pointless to do the rest if (!enable_autohauler) return; // First get the frame skip from persistent data, or create the item // if not present auto cfg_frameskip = World::GetPersistentData("autohauler/frameskip"); if (cfg_frameskip.isValid()) { frame_skip = cfg_frameskip.ival(0); } else { // Add to persistent data then get it to assert it's actually there cfg_frameskip = World::AddPersistentData("autohauler/frameskip"); cfg_frameskip.ival(0) = DEFAULT_FRAME_SKIP; frame_skip = cfg_frameskip.ival(0); } /* Here we are going to populate the labor list by loading persistent data * from the world save */ // This is a vector of all the persistent data items from config std::vector<PersistentDataItem> items; // This populates the aforementioned vector World::GetPersistentData(&items, "autohauler/labors/", true); // Resize the list of current labor treatments to size of list of default // labor treatments labor_infos.resize(ARRAY_COUNT(default_labor_infos)); // For every persistent data item... for (auto p = items.begin(); p != items.end(); p++) { // Load as a string the key associated with the persistent data item string key = p->key(); // Translate the string into a labor defined by global dfhack constants df::unit_labor labor = (df::unit_labor) atoi(key.substr(strlen("autohauler/labors/")).c_str()); // Ensure that the labor is defined in the existing list if (labor >= 0 && labor <= labor_infos.size()) { // Link the labor treatment with the associated persistent data item labor_infos[labor].set_config(*p); // Set the number of dwarves associated with labor to zero labor_infos[labor].active_dwarfs = 0; } } // Add default labors for those not in save for (int i = 0; i < ARRAY_COUNT(default_labor_infos); i++) { // Determine if the labor is already present. If so, exit the for loop if (labor_infos[i].config.isValid()) continue; // Not sure of the mechanics, but it seems to give an output stream // giving a string for the new persistent data item std::stringstream name; name << "autohauler/labors/" << i; // Add a new persistent data item as it is not currently in the save labor_infos[i].set_config(World::AddPersistentData(name.str())); // Set the active counter to zero labor_infos[i].active_dwarfs = 0; // Reset labor to default treatment reset_labor((df::unit_labor) i); } }