command_result outsideOnly(color_ostream& out, vector<string>& parameters) { int32_t status = 2; for ( size_t a = 0; a < parameters.size(); a++ ) { if ( parameters[a] == "clear" ) { registeredBuildings.clear(); } else if ( parameters[a] == "outside" ) { status = OUTSIDE_ONLY; } else if ( parameters[a] == "inside" ) { status = INSIDE_ONLY; } else if ( parameters[a] == "either" ) { status = EITHER; } else if ( parameters[a] == "checkEvery" ) { if (a+1 >= parameters.size()) { out.printerr("You must specify how often to check.\n"); return CR_WRONG_USAGE; } checkEvery = atoi(parameters[a].c_str()); } else { if ( status == 2 ) { out.printerr("Error: you need to tell outsideOnly whether the building is inside only, outside-only or either.\n"); return CR_WRONG_USAGE; } registeredBuildings[parameters[a]] = status; } } out.print("outsideOnly is %s\n", enabled ? "enabled" : "disabled"); if ( enabled ) { } return CR_OK; }
command_result infiniteSky (color_ostream &out, std::vector <std::string> & parameters) { if ( parameters.size() > 1 ) return CR_WRONG_USAGE; if ( parameters.size() == 0 ) { out.print("Construction monitoring is %s.\n", enabled ? "enabled" : "disabled"); return CR_OK; } if (parameters[0] == "enable") { enabled = true; out.print("Construction monitoring enabled.\n"); return CR_OK; } if (parameters[0] == "disable") { enabled = false; out.print("Construction monitoring disabled.\n"); constructionSize = 0; return CR_OK; } int32_t howMany = 0; howMany = atoi(parameters[0].c_str()); out.print("InfiniteSky: creating %d new z-level%s of sky.\n", howMany, howMany == 1 ? "" : "s" ); doInfiniteSky(out, howMany); return CR_OK; }
command_result follow (color_ostream &out, std::vector <std::string> & parameters) { // HOTKEY COMMAND: CORE ALREADY SUSPENDED if (!parameters.empty()) return CR_WRONG_USAGE; if (followedUnit) { out.print("No longer following previously selected unit.\n"); followedUnit = 0; } followedUnit = Gui::getSelectedUnit(out); if (followedUnit) { is_enabled = true; std::ostringstream ss; ss << "Unpause to begin following " << df::global::world->raws.creatures.all[followedUnit->race]->name[0]; if (followedUnit->name.has_name) ss << " " << followedUnit->name.first_name; ss << ". Simply manually move the view to break the following.\n"; out.print(ss.str().c_str()); } else followedUnit = 0; is_enabled = (followedUnit != NULL); return CR_OK; }
static void print_job(color_ostream &out, ProtectedJob *pj) { if (!pj) return; df::job *job = pj->isLive() ? pj->actual_job : pj->job_copy; Job::printJobDetails(out, job); if (job->job_type == job_type::MeltMetalObject && isOptionEnabled(CF_AUTOMELT)) { if (meltable_count <= 0) out.color(COLOR_CYAN); else if (pj->want_resumed && !pj->isActuallyResumed()) out.color(COLOR_YELLOW); else out.color(COLOR_GREEN); out << " Meltable: " << meltable_count << " objects." << endl; out.reset_color(); } for (size_t i = 0; i < pj->constraints.size(); i++) print_constraint(out, pj->constraints[i], true, " "); }
command_result lair(color_ostream &out, std::vector<std::string> & params) { state do_what = LAIR_SET; for(auto iter = params.begin(); iter != params.end(); iter++) { if(*iter == "reset") do_what = LAIR_RESET; } CoreSuspender lock; if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } uint32_t x_max,y_max,z_max; Maps::getSize(x_max,y_max,z_max); for (size_t i = 0; i < world->map.map_blocks.size(); i++) { df::map_block *block = world->map.map_blocks[i]; DFHack::occupancies40d & occupancies = block->occupancy; // for each tile in block for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++) { // set to revealed occupancies[x][y].bits.monster_lair = (do_what == LAIR_SET); } } if(do_what == LAIR_SET) out.print("Map marked as lair.\n"); else out.print("Map no longer marked as lair.\n"); return CR_OK; }
void outputHex(uint8_t *buf,uint8_t *lbuf,size_t len,size_t start,color_ostream &con,vector<t_memrange> & ranges) { const size_t page_size=16; for(size_t i=0;i<len;i+=page_size) { //con.gotoxy(1,i/page_size+1); con.print("0x%08X ",i+start); for(size_t j=0;(j<page_size) && (i+j<len);j++) { if(j%4==0) { con.reset_color(); if(isAddr((uint32_t *)(buf+j+i),ranges)) con.color(COLOR_LIGHTRED); //coloring in the middle does not work //TODO make something better? } if(lbuf[j+i]!=buf[j+i]) con.print("*%02X",buf[j+i]); //if modfied show a star else con.print(" %02X",buf[j+i]); } con.reset_color(); con.print(" | "); for(size_t j=0;(j<page_size) && (i+j<len);j++) if((buf[j+i]>31)&&(buf[j+i]<128)) //only printable ascii con.print("%c",buf[j+i]); else con.print("."); //con.print("\n"); } con.print("\n"); }
// dump some chain/restraint info void chainInfo(color_ostream & out, df::building* building, bool list_refs = false) { if(!isChain(building)) return; string name; building->getName(&name); out.print("Building %i - \"%s\" - type %s (%i)", building->id, name.c_str(), ENUM_KEY_STR(building_type, building->getType()).c_str(), building->getType()); out.print("\n"); df::building_chainst* chain = (df::building_chainst*) building; if(chain->assigned) { out << "assigned: "; unitInfo(out, chain->assigned, true); } if(chain->chained) { out << "chained: "; unitInfo(out, chain->chained, true); } }
command_result wagonshot (color_ostream &out, vector <string> & parameters) { CoreSuspender suspend; int32_t cursorX, cursorY, cursorZ; Gui::getCursorCoords(cursorX,cursorY,cursorZ); if(cursorX == -30000) { out.printerr("No cursor; place cursor over creature to murder.\n"); } else { for(size_t i = 0; i < world->units.all.size(); i++) { df::unit * unit = world->units.all[i]; if(unit->pos.x == cursorX && unit->pos.y == cursorY && unit->pos.z == cursorZ) { if (parameters.size() == 1 && (parameters[0] == "--kill" || parameters[0] == "-k")) { unit->flags3.bits.scuttle = 1; //out.print("Boom! Wagonshot!\n"); continue; } else { out.print("'wagonshot --kill' short and sweet\n(or 'wagonshot -k' even shorter). No condiments needed. That's what the wagon provides.\nNow show me where we drop the wagon.\n"); break; } } } } return CR_OK; }
void DFHack::Lua::InvokeEvent(color_ostream &out, lua_State *state, void *key, int num_args) { AssertCoreSuspend(state); int base = lua_gettop(state) - num_args; if (!lua_checkstack(state, num_args+4)) { out.printerr("Stack overflow in Lua::InvokeEvent"); lua_settop(state, base); return; } lua_rawgetp(state, LUA_REGISTRYINDEX, key); if (!lua_istable(state, -1)) { if (!lua_isnil(state, -1)) out.printerr("Invalid event object in Lua::InvokeEvent"); lua_settop(state, base); return; } lua_insert(state, base+1); color_ostream *cur_out = Lua::GetOutput(state); set_dfhack_output(state, &out); dfhack_event_invoke(state, base, true); set_dfhack_output(state, cur_out); }
command_result combatLog (color_ostream &out, vector <string> & parameters) { std::vector<df::report*> combatLog; int unitReportCounter=0; out.print("\n\nall units : %d.\n",world->units.all.size()); for (size_t i = 0; i < world->units.all.size(); i++) { df::unit *unit=world->units.all[i]; std::vector<int32_t> reportUnit=unit->reports.log[0];// reports ? if( reportUnit.size()>0) { if(unit->name.has_name) out.print("%s aka. %s is fighting.\n",unit->name.first_name.c_str(),unit->name.nickname.c_str()); else out.print("No name - display race & sex.\n"); for (size_t j = 0; j < reportUnit.size(); j++) { int32_t refReport = reportUnit.at(j); combatLog.push_back(world->status.reports[relateReport(refReport,world->status.reports)]); }//end loop reportUnit printReport(out,combatLog); combatLog.clear(); }//end if }//end for return CR_OK; }
// dump some zone info void zoneInfo(color_ostream & out, df::building* building, bool verbose = false) { if(building->getType()!= building_type::Civzone) return; if(building->getSubtype() != civzone_type::ActivityZone) return; string name; building->getName(&name); out.print("Building %i - \"%s\" - type %s (%i)", building->id, name.c_str(), ENUM_KEY_STR(building_type, building->getType()).c_str(), building->getType()); out.print(", subtype %s (%i)", ENUM_KEY_STR(civzone_type, (df::civzone_type)building->getSubtype()).c_str(), building->getSubtype()); out.print("\n"); df::building_civzonest * civ = (df::building_civzonest *) building; if(civ->zone_flags.bits.active) out << "active"; else out << "not active"; if(civ->zone_flags.bits.pen_pasture) out << ", pen/pasture"; else if (civ->zone_flags.bits.pit_pond && civ->pit_flags==0) out << ", pit"; else return; out << endl; out << "x1:" <<building->x1 << " x2:" <<building->x2 << " y1:" <<building->y1 << " y2:" <<building->y2 << " z:" <<building->z << endl; int32_t creaturecount = civ->assigned_creature.size(); out << "Creatures in this zone: " << creaturecount << endl; for(size_t c = 0; c < creaturecount; c++) { int32_t cindex = civ->assigned_creature.at(c); // print list of all units assigned to that zone for(size_t i = 0; i < world->units.all.size(); i++) { df::unit * creature = world->units.all[i]; if(creature->id != cindex) continue; unitInfo(out, creature, verbose); } } }
bool Plugin::unload(color_ostream &con) { // get the mutex access->lock(); // if we are actually loaded if(state == PS_LOADED) { EventManager::unregisterAll(this); // notify the plugin about an attempt to shutdown if (plugin_onstatechange && plugin_onstatechange(con, SC_BEGIN_UNLOAD) != CR_OK) { con.printerr("Plugin %s has refused to be unloaded.\n", name.c_str()); access->unlock(); return false; } // wait for all calls to finish access->wait(); state = PS_UNLOADING; access->unlock(); // enter suspend CoreSuspender suspend; access->lock(); // notify plugin about shutdown, if it has a shutdown function command_result cr = CR_OK; if(plugin_shutdown) cr = plugin_shutdown(con); // cleanup... plugin_is_enabled = 0; plugin_onupdate = 0; reset_lua(); parent->unregisterCommands(this); commands.clear(); if(cr == CR_OK) { ClosePlugin(plugin_lib); state = PS_UNLOADED; access->unlock(); return true; } else { con.printerr("Plugin %s has failed to shutdown!\n",name.c_str()); state = PS_BROKEN; access->unlock(); return false; } } else if(state == PS_UNLOADED) { access->unlock(); return true; } access->unlock(); return false; }
command_result petcapRemover (color_ostream &out, std::vector <std::string> & parameters) { CoreSuspender suspend; for ( size_t a = 0; a < parameters.size(); a++ ) { if ( parameters[a] == "every" ) { if ( a+1 >= parameters.size() ) return CR_WRONG_USAGE; int32_t old = howOften; howOften = atoi(parameters[a+1].c_str()); if (howOften < -1) { howOften = old; return CR_WRONG_USAGE; } a++; continue; } else if ( parameters[a] == "cap" ) { if ( a+1 >= parameters.size() ) return CR_WRONG_USAGE; int32_t old = popcap; popcap = atoi(parameters[a+1].c_str()); if ( popcap < 0 ) { popcap = old; return CR_WRONG_USAGE; } a++; continue; } else if ( parameters[a] == "pregtime" ) { if ( a+1 >= parameters.size() ) return CR_WRONG_USAGE; int32_t old = pregtime; pregtime = atoi(parameters[a+1].c_str()); if ( pregtime <= 0 ) { pregtime = old; return CR_WRONG_USAGE; } a++; continue; } out.print("%s, line %d: invalid argument: %s\n", __FILE__, __LINE__, parameters[a].c_str()); return CR_WRONG_USAGE; } if ( howOften < 0 ) { is_enabled = false; return CR_OK; } is_enabled = true; EventManager::unregisterAll(plugin_self); EventManager::EventHandler handle(tickHandler, howOften); EventManager::registerTick(handle, howOften, plugin_self); out.print("petcapRemover: howOften = every %d ticks, popcap per species = %d, preg time = %d ticks.\n", howOften, popcap, pregtime); return CR_OK; }
command_result unreveal(color_ostream &out, vector<string> & params) { auto & con = out; for(size_t i = 0; i < params.size();i++) { if(params[i] == "help" || params[i] == "?") { out.print("Reverts the previous reveal operation, hiding the map again.\n"); return CR_OK; } } if(!revealed) { con.printerr("There's nothing to revert!\n"); return CR_FAILURE; } CoreSuspender suspend; World *World = Core::getInstance().getWorld(); if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } t_gamemodes gm; World->ReadGameMode(gm); if(gm.g_mode != GAMEMODE_DWARF) { con.printerr("Only in fortress mode.\n"); return CR_FAILURE; } // Sanity check: map size uint32_t x_max_b, y_max_b, z_max_b; Maps::getSize(x_max_b,y_max_b,z_max_b); if(x_max != x_max_b || y_max != y_max_b || z_max != z_max_b) { con.printerr("The map is not of the same size...\n"); return CR_FAILURE; } for(size_t i = 0; i < hidesaved.size();i++) { hideblock & hb = hidesaved[i]; df::map_block * b = Maps::getBlockAbs(hb.c.x,hb.c.y,hb.c.z); for (uint32_t x = 0; x < 16;x++) for (uint32_t y = 0; y < 16;y++) { b->designation[x][y].bits.hidden = hb.hiddens[x][y]; } } // give back memory. hidesaved.clear(); revealed = NOT_REVEALED; con.print("Map hidden!\n"); return CR_OK; }
command_result df_grow (color_ostream &out, vector <string> & parameters) { for(size_t i = 0; i < parameters.size();i++) { if(parameters[i] == "help" || parameters[i] == "?") { out.print("This command turns all living saplings into full-grown trees.\n"); return CR_OK; } } CoreSuspender suspend; if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } MapExtras::MapCache map; int32_t x,y,z; if(Gui::getCursorCoords(x,y,z)) { vector<df::plant *> * alltrees; if(Maps::ReadVegetation(x/16,y/16,z,alltrees)) { for(size_t i = 0 ; i < alltrees->size(); i++) { df::plant * tree = alltrees->at(i); if(tree->pos.x == x && tree->pos.y == y && tree->pos.z == z) { if(tileShape(map.tiletypeAt(DFCoord(x,y,z))) == tiletype_shape::SAPLING && tileSpecial(map.tiletypeAt(DFCoord(x,y,z))) != tiletype_special::DEAD) { tree->grow_counter = Vegetation::sapling_to_tree_threshold; } break; } } } } else { int grown = 0; for(size_t i = 0 ; i < world->plants.all.size(); i++) { df::plant *p = world->plants.all[i]; df::tiletype ttype = map.tiletypeAt(df::coord(p->pos.x,p->pos.y,p->pos.z)); if(!p->flags.bits.is_shrub && tileShape(ttype) == tiletype_shape::SAPLING && tileSpecial(ttype) != tiletype_special::DEAD) { p->grow_counter = Vegetation::sapling_to_tree_threshold; } } } return CR_OK; }
static command_result fastdwarf (color_ostream &out, vector <string> & parameters) { if (parameters.size() > 2) return CR_WRONG_USAGE; if ((parameters.size() == 1) || (parameters.size() == 2)) { if (parameters.size() == 2) { if (parameters[1] == "0") enable_teledwarf = false; else if (parameters[1] == "1") enable_teledwarf = true; else return CR_WRONG_USAGE; } else enable_teledwarf = false; if (parameters[0] == "0") { enable_fastdwarf = false; if (debug_turbospeed) *debug_turbospeed = false; } else if (parameters[0] == "1") { enable_fastdwarf = true; if (debug_turbospeed) *debug_turbospeed = false; } else if (parameters[0] == "2") { if (debug_turbospeed) { enable_fastdwarf = false; *debug_turbospeed = true; } else { out.print("Speed level 2 not available.\n"); return CR_FAILURE; } } else return CR_WRONG_USAGE; } active = enable_fastdwarf || enable_teledwarf; out.print("Current state: fast = %d, teleport = %d.\n", (debug_turbospeed && *debug_turbospeed) ? 2 : (enable_fastdwarf ? 1 : 0), enable_teledwarf ? 1 : 0); return CR_OK; }
static bool recover_job(color_ostream &out, ProtectedJob *pj) { if (pj->isLive()) return true; // Check that the building exists pj->holder = df::building::find(pj->building_id); if (!pj->holder) { out.printerr("Forgetting job %d (%s): holder building lost.\n", pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type).c_str()); forget_job(out, pj); return true; } // Check its state and postpone or cancel if invalid if (pj->holder->jobs.size() >= 10) { out.printerr("Forgetting job %d (%s): holder building has too many jobs.\n", pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type).c_str()); forget_job(out, pj); return true; } if (!pj->holder->jobs.empty()) { df::job_type ftype = pj->holder->jobs[0]->job_type; if (ftype == job_type::DestroyBuilding) return false; if (ENUM_ATTR(job_type,type,ftype) == job_type_class::StrangeMood) return false; } // Create and link in the actual job structure df::job *recovered = Job::cloneJobStruct(pj->job_copy); if (!Job::linkIntoWorld(recovered, false)) // reuse same id { Job::deleteJobStruct(recovered); out.printerr("Inconsistency: job %d (%s) already in list.\n", pj->id, ENUM_KEY_STR(job_type, pj->job_copy->job_type).c_str()); return true; } pj->holder->jobs.push_back(recovered); // Done pj->recover(recovered); return true; }
static command_result rename(color_ostream &out, vector <string> ¶meters) { CoreSuspender suspend; string cmd; if (!parameters.empty()) cmd = parameters[0]; if (cmd == "hotkey") { if (parameters.size() != 3) return CR_WRONG_USAGE; int id = atoi(parameters[1].c_str()); if (id < 1 || id > 16) { out.printerr("Invalid hotkey index\n"); return CR_WRONG_USAGE; } ui->main.hotkeys[id-1].name = parameters[2]; } else if (cmd == "unit") { if (parameters.size() != 2) return CR_WRONG_USAGE; df::unit *unit = Gui::getSelectedUnit(out, true); if (!unit) return CR_WRONG_USAGE; Units::setNickname(unit, parameters[1]); } else if (cmd == "unit-profession") { if (parameters.size() != 2) return CR_WRONG_USAGE; df::unit *unit = Gui::getSelectedUnit(out, true); if (!unit) return CR_WRONG_USAGE; unit->custom_profession = parameters[1]; } else { if (!parameters.empty() && cmd != "?") out.printerr("Invalid command: %s\n", cmd.c_str()); return CR_WRONG_USAGE; } return CR_OK; }
command_result cmd_fix_unit_occupancy (color_ostream &out, std::vector <std::string> & parameters) { CoreSuspender suspend; uo_opts opts; bool ok = true; if (parameters.size() >= 1 && (parameters[0] == "-i" || parameters[0].find("interval") != std::string::npos)) { if (parameters.size() >= 2) { int new_interval = atoi(parameters[1].c_str()); if (new_interval < 100) { out.printerr("Invalid interval - minimum is 100 ticks\n"); return CR_WRONG_USAGE; } run_interval = new_interval; if (!is_enabled) out << "note: Plugin not enabled (use `enable fix-unit-occupancy` to enable)" << endl; return CR_OK; } else return CR_WRONG_USAGE; } for (auto opt = parameters.begin(); opt != parameters.end(); ++opt) { if (*opt == "-n" || opt->find("dry") != std::string::npos) opts.dry_run = true; else if (*opt == "-h" || opt->find("cursor") != std::string::npos || opt->find("here") != std::string::npos) opts.use_cursor = true; else if (opt->find("enable") != std::string::npos) plugin_enable(out, true); else if (opt->find("disable") != std::string::npos) plugin_enable(out, false); else { out.printerr("Unknown parameter: %s\n", opt->c_str()); ok = false; } } if (!ok) return CR_WRONG_USAGE; unsigned count = fix_unit_occupancy(out, opts); if (!count) out << "No occupancy issues found." << endl; return CR_OK; }
static void enable_hook(color_ostream &out, VMethodInterposeLinkBase &hook, vector <string> ¶meters) { if (vector_get(parameters, 1) == "disable") { hook.remove(); out.print("Disabled tweak %s (%s)\n", parameters[0].c_str(), hook.name()); } else { if (hook.apply()) out.print("Enabled tweak %s (%s)\n", parameters[0].c_str(), hook.name()); else out.printerr("Could not activate tweak %s (%s)\n", parameters[0].c_str(), hook.name()); } }
DFhackCExport command_result plugin_init(color_ostream &out, vector <PluginCommand> &commands) { auto dflags = init->display.flag; if (dflags.is_set(init_display_flags::TEXT)) { out.color(COLOR_RED); out << "Error: For Webfort, PRINT_MODE needs to not be TEXT" << std::endl; out.color(COLOR_RESET); return CR_OK; } s_hdl = new WFServer(out); hook(); return CR_OK; }
void printReportDebug(color_ostream &out,df::report *report) { out.print(report->text.c_str()); out.print("\n Type : %d - ", report->type); out.print("Flags.whole : %d - ",report->flags.whole); out.print("Flags.bits, announcement : %d - continuation : %d - unconscious : %d - ",report->flags.bits.announcement,report->flags.bits.continuation, report->flags.bits.unconscious); out.print("Color : %d -",report->color); out.print((report->bright?"Bright - ":"Not bright - ")); out.print("Id : %d - ", report->id); out.print("Date : %d/%d .",report->year,report->time); out.print("\n"); }
command_result df_cleanconst(color_ostream &out, vector <string> & parameters) { CoreSuspender suspend; if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } size_t numItems = world->items.all.size(); int cleaned_total = 0; // proceed with the cleanup operation for (size_t i = 0; i < numItems; i++) { df::item *item = world->items.all[i]; // only process items marked as "in construction" if (!item->flags.bits.construction) continue; df::coord pos(item->pos.x, item->pos.y, item->pos.z); df::construction *cons = df::construction::find(pos); if (!cons) { out.printerr("Item at %i,%i,%i marked as construction but no construction is present!\n", pos.x, pos.y, pos.z); continue; } // if the construction is already labeled as "no build item", then leave it alone if (cons->flags.bits.no_build_item) continue; // only destroy the item if the construction claims to be made of the exact same thing if (item->getType() != cons->item_type || item->getSubtype() != cons->item_subtype || item->getMaterial() != cons->mat_type || item->getMaterialIndex() != cons->mat_index) continue; item->flags.bits.garbage_collect = 1; cons->flags.bits.no_build_item = 1; cleaned_total++; } out.print("Done. %d construction items cleaned up.\n", cleaned_total); return CR_OK; }
command_result cmd_3dveins(color_ostream &con, std::vector<std::string> & parameters) { bool verbose = false; for (size_t i = 0; i < parameters.size(); i++) { if (parameters[i] == "verbose") verbose = true; else return CR_WRONG_USAGE; } CoreSuspender suspend; if (!Maps::IsValid()) { con.printerr("Map is not available!\n"); return CR_FAILURE; } if (*gametype != game_type::DWARF_MAIN && *gametype != game_type::DWARF_RECLAIM) { con.printerr("Must be used in fortress mode!\n"); return CR_FAILURE; } VeinGenerator generator(con); con.print("Collecting statistics...\n"); if (!generator.init_biomes()) return CR_FAILURE; if (!generator.scan_tiles()) return CR_FAILURE; con.print("Generating veins...\n"); if (!generator.form_veins()) return CR_FAILURE; if (!generator.place_veins(verbose)) return CR_FAILURE; con.print("Writing tiles...\n"); generator.write_tiles(); return CR_OK; }
command_result cleanitems (color_ostream &out) { // Invoked from clean(), already suspended int cleaned_items = 0, cleaned_total = 0; for (size_t i = 0; i < world->items.all.size(); i++) { // currently, all item classes extend item_actual, so this should be safe df::item_actual *item = (df::item_actual *)world->items.all[i]; if (item->contaminants && item->contaminants->size()) { std::vector<df::spatter*> saved; for (size_t j = 0; j < item->contaminants->size(); j++) { auto obj = (*item->contaminants)[j]; if (obj->flags.whole & 0x8000) // DFHack-generated contaminant saved.push_back(obj); else delete obj; } cleaned_items++; cleaned_total += item->contaminants->size() - saved.size(); item->contaminants->swap(saved); } } if (cleaned_total) out.print("Removed %d contaminants from %d items.\n", cleaned_total, cleaned_items); return CR_OK; }
command_result df_grow (color_ostream &out, vector <string> & parameters) { for(size_t i = 0; i < parameters.size();i++) { if(parameters[i] == "help" || parameters[i] == "?") { out << "Usage:\n" "This command turns all living saplings on the map into full-grown trees.\n" "With active cursor, work on the targetted one only.\n"; return CR_OK; } } CoreSuspender suspend; if (!Maps::IsValid()) { out.printerr("Map is not available!\n"); return CR_FAILURE; } MapExtras::MapCache map; int32_t x,y,z; if(Gui::getCursorCoords(x,y,z)) { auto block = Maps::getTileBlock(x,y,z); stl::vector<df::plant *> *alltrees = &world->plants.all; if(alltrees) { for(size_t i = 0 ; i < alltrees->size(); i++) { df::plant * tree = alltrees->at(i); if(tree->pos.x == x && tree->pos.y == y && tree->pos.z == z) { if(tileShape(map.tiletypeAt(DFCoord(x,y,z))) == tiletype_shape::SAPLING && tileSpecial(map.tiletypeAt(DFCoord(x,y,z))) != tiletype_special::DEAD) { tree->grow_counter = sapling_to_tree_threshold; } break; } } } } else { int grown = 0; for(size_t i = 0 ; i < world->plants.all.size(); i++) { df::plant *p = world->plants.all[i]; df::tiletype ttype = map.tiletypeAt(df::coord(p->pos.x,p->pos.y,p->pos.z)); bool is_shrub = p->flags >= plant_flags::shrub_forest; if(!is_shrub && tileShape(ttype) == tiletype_shape::SAPLING && tileSpecial(ttype) != tiletype_special::DEAD) { p->grow_counter = sapling_to_tree_threshold; } } } return CR_OK; }
static void start_protect(color_ostream &out) { check_lost_jobs(out, 0); if (!known_jobs.empty()) out.print("Protecting %d jobs.\n", known_jobs.size()); }
command_result colormods (color_ostream &out, vector <string> & parameters) { CoreSuspender suspend; auto & vec = df::global::world->raws.creatures.alphabetic; for(int i = 0; i < vec.size();i++) { df::creature_raw* rawlion = vec[i]; df::caste_raw * caste = rawlion->caste[0]; out.print("%s\nCaste addr 0x%x\n",rawlion->creature_id.c_str(), &caste->color_modifiers); for(int j = 0; j < caste->color_modifiers.size();j++) { out.print("mod %d: 0x%x\n", j, caste->color_modifiers[j]); } } return CR_OK; }
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); }
void buildingCreated(color_ostream& out, void* data) { int32_t id = (int32_t)data; df::building* building = df::building::find(id); if ( building == NULL ) return; if ( building->getCustomType() < 0 ) return; //check if it was created inside or outside df::coord pos(building->centerx,building->centery,building->z); df::tile_designation* des = Maps::getTileDesignation(pos); bool outside = des->bits.outside; df::building_def* def = df::global::world->raws.buildings.all[building->getCustomType()]; int32_t type = registeredBuildings[def->code]; if ( type == EITHER ) { registeredBuildings.erase(def->code); } else if ( type == OUTSIDE_ONLY ) { if ( outside ) return; Buildings::deconstruct(building); } else if ( type == INSIDE_ONLY ) { if ( !outside ) return; Buildings::deconstruct(building); } else { if ( DFHack::Once::doOnce("outsideOnly invalid setting") ) { out.print("Error: outsideOnly: building has invalid setting: %s %d\n", def->code.c_str(), type); } } }