bool World::DeletePersistentData(const PersistentDataItem &item) { int id = item.raw_id(); if (id > -100) return false; if (!BuildPersistentCache()) return false; stl::vector<df::historical_figure*> &hfvec = df::historical_figure::get_vector(); auto eqrange = persistent_index.equal_range(item.key()); for (auto it2 = eqrange.first; it2 != eqrange.second; ) { auto it = it2; ++it2; if (it->second != -id) continue; persistent_index.erase(it); int idx = binsearch_index(hfvec, id); if (idx >= 0) { delete hfvec[idx]; hfvec.erase(hfvec.begin()+idx); } return true; } return false; }
static void init_state(color_ostream &out) { auto pworld = Core::getInstance().getWorld(); config = pworld->GetPersistentData("workflow/config"); if (config.isValid() && config.ival(0) == -1) config.ival(0) = 0; enabled = isOptionEnabled(CF_ENABLED); // Parse constraints std::vector<PersistentDataItem> items; pworld->GetPersistentData(&items, "workflow/constraints"); for (int i = items.size()-1; i >= 0; i--) { if (get_constraint(out, items[i].val(), &items[i])) continue; out.printerr("Lost constraint %s\n", items[i].val().c_str()); pworld->DeletePersistentData(items[i]); } last_tick_frame_count = world->frame_counter; last_frame_count = world->frame_counter; if (!enabled) return; start_protect(out); }
static int read_persistent(lua_State *state, PersistentDataItem ref, bool create) { if (!ref.isValid()) { lua_pushnil(state); lua_pushstring(state, "entry not found"); return 2; } if (create) lua_createtable(state, 0, 4); lua_pushvalue(state, lua_upvalueindex(1)); lua_setmetatable(state, -2); lua_pushinteger(state, ref.entry_id()); lua_setfield(state, -2, "entry_id"); lua_pushstring(state, ref.key().c_str()); lua_setfield(state, -2, "key"); lua_pushstring(state, ref.val().c_str()); lua_setfield(state, -2, "value"); lua_createtable(state, PersistentDataItem::NumInts, 0); for (int i = 0; i < PersistentDataItem::NumInts; i++) { lua_pushinteger(state, ref.ival(i)); lua_rawseti(state, -2, i+1); } lua_setfield(state, -2, "ints"); return 1; }
static void init_state() { config = World::GetPersistentData("autolabor/config"); if (config.isValid() && config.ival(0) == -1) config.ival(0) = 0; enable_autolabor = isOptionEnabled(CF_ENABLED); if (!enable_autolabor) return; auto cfg_haulpct = World::GetPersistentData("autolabor/haulpct"); if (cfg_haulpct.isValid()) { hauler_pct = cfg_haulpct.ival(0); } else { hauler_pct = 33; } // Load labors from save labor_infos.resize(ARRAY_COUNT(default_labor_infos)); std::vector<PersistentDataItem> items; World::GetPersistentData(&items, "autolabor/labors/", true); for (auto p = items.begin(); p != items.end(); p++) { string key = p->key(); df::unit_labor labor = (df::unit_labor) atoi(key.substr(strlen("autolabor/labors/")).c_str()); if (labor >= 0 && labor <= labor_infos.size()) { labor_infos[labor].config = *p; labor_infos[labor].is_exclusive = default_labor_infos[labor].is_exclusive; 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++) { if (labor_infos[i].config.isValid()) continue; std::stringstream name; name << "autolabor/labors/" << i; labor_infos[i].config = World::AddPersistentData(name.str()); labor_infos[i].is_exclusive = default_labor_infos[i].is_exclusive; labor_infos[i].active_dwarfs = 0; reset_labor((df::unit_labor) i); } generate_labor_to_skill_map(); }
static void setOptionEnabled(ConfigFlags flag, bool on) { if (!config.isValid()) return; if (on) config.ival(0) |= flag; else config.ival(0) &= ~flag; }
static void enable_plugin(Core *c) { if (!config.isValid()) { config = c->getWorld()->AddPersistentData("workflow/config"); config.ival(0) = 0; } setOptionEnabled(CF_ENABLED, true); enabled = true; c->con << "Enabling the plugin." << endl; start_protect(c); }
PersistentDataItem World::GetPersistentData(const std::string &key, bool *added) { if (added) *added = false; PersistentDataItem rv = GetPersistentData(key); if (!rv.isValid()) { if (added) *added = true; rv = AddPersistentData(key); } return rv; }
static void enable_plugin(color_ostream &out) { auto pworld = Core::getInstance().getWorld(); if (!config.isValid()) { config = pworld->AddPersistentData("workflow/config"); config.ival(0) = 0; } setOptionEnabled(CF_ENABLED, true); enabled = true; out << "Enabling the plugin." << endl; start_protect(out); }
bool World::deletePersistentTilemask(const PersistentDataItem &item, df::map_block *block) { if (!block) return false; int id = item.raw_id(); if (id > -100) return false; bool found = false; for (int i = block->block_events.size()-1; i >= 0; i--) { auto ev = block->block_events[i]; if (ev->getType() != block_square_event_type::world_construction) continue; auto wcsev = strict_virtual_cast<df::block_square_event_world_constructionst>(ev); if (!wcsev || wcsev->construction_id != id) continue; delete wcsev; vector_erase_at(block->block_events, i); found = true; } return found; }
static void init_state() { auto pworld = Core::getInstance().getWorld(); config = pworld->GetPersistentData("autolabor/config"); if (config.isValid() && config.ival(0) == -1) config.ival(0) = 0; enable_autolabor = isOptionEnabled(CF_ENABLED); if (!enable_autolabor) return; // Load labors from save labor_infos.resize(ARRAY_COUNT(default_labor_infos)); std::vector<PersistentDataItem> items; pworld->GetPersistentData(&items, "autolabor/labors/", true); for (auto p = items.begin(); p != items.end(); p++) { string key = p->key(); df::enums::unit_labor::unit_labor labor = (df::enums::unit_labor::unit_labor) atoi(key.substr(strlen("autolabor/labors/")).c_str()); if (labor >= 0 && labor <= labor_infos.size()) { labor_infos[labor].config = *p; labor_infos[labor].is_exclusive = default_labor_infos[labor].is_exclusive; 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++) { if (labor_infos[i].config.isValid()) continue; std::stringstream name; name << "autolabor/labors/" << i; labor_infos[i].config = pworld->AddPersistentData(name.str()); labor_infos[i].is_exclusive = default_labor_infos[i].is_exclusive; labor_infos[i].active_dwarfs = 0; reset_labor((df::enums::unit_labor::unit_labor) i); } }
static void enable_plugin(color_ostream &out) { auto pworld = Core::getInstance().getWorld(); if (!config.isValid()) { config = pworld->AddPersistentData("autolabor/config"); config.ival(0) = 0; } setOptionEnabled(CF_ENABLED, true); enable_autolabor = true; out << "Enabling the plugin." << endl; cleanup_state(); init_state(); }
static PersistentDataItem persistent_by_struct(lua_State *state, int idx) { lua_getfield(state, idx, "entry_id"); int id = lua_tointeger(state, -1); lua_pop(state, 1); PersistentDataItem ref = Core::getInstance().getWorld()->GetPersistentData(id); if (ref.isValid()) { lua_getfield(state, idx, "key"); const char *str = lua_tostring(state, -1); if (!str || str != ref.key()) luaL_argerror(state, idx, "inconsistent id and key"); lua_pop(state, 1); } return ref; }
/** * Call this method to enable the plugin. */ static void enable_plugin(color_ostream &out) { // If there is no config persistent item, make one if (!config.isValid()) { config = World::AddPersistentData("autohauler/config"); config.ival(0) = 0; } // I think this is already done in init_state(), but it can't hurt setOptionEnabled(CF_ENABLED, true); enable_autohauler = true; // Output to console that the plugin is enabled out << "Enabling the plugin." << endl; // Disable autohauler and clear the labor list cleanup_state(); // Initialize the plugin init_state(); }
void set_mode(labor_mode mode) { config.ival(0) = mode; }
labor_mode mode() { return (labor_mode) config.ival(0); }
void set_minimum_dwarfs(int minimum_dwarfs) { config.ival(1) = minimum_dwarfs; }
int minimum_dwarfs() { return config.ival(1); }
void init(const std::string &str) { config.val() = str; config.ival(2) = 0; }
static bool isOptionEnabled(unsigned flag) { return config.isValid() && (config.ival(0) & flag) != 0; }
bool goalByCount() { return config.ival(2) & 1; }
int maximum_dwarfs() { return config.ival(2); }
int goalGap() { int gcnt = std::max(1, goalCount()/2); return std::min(gcnt, config.ival(1) <= 0 ? 5 : config.ival(1)); }
void setGoalGap(int v) { config.ival(1) = v; }
void setGoalCount(int v) { config.ival(0) = v; }
int goalCount() { return config.ival(0); }
int talent_pool() { return config.ival(3); }
void set_talent_pool(int talent_pool) { config.ival(3) = talent_pool; }
void setGoalByCount(bool v) { if (v) config.ival(2) |= 1; else config.ival(2) &= ~1; }
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 = Core::getInstance().getWorld()->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 = Core::getInstance().getWorld()->GetPersistentData(str); } // Auto-add if not found if (!ref.isValid()) { ref = Core::getInstance().getWorld()->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; }
void set_maximum_dwarfs(int maximum_dwarfs) { config.ival(2) = maximum_dwarfs; }