Пример #1
0
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);
}
Пример #2
0
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;
}
Пример #3
0
command_result spotclean (color_ostream &out, vector <string> & parameters)
{
    // HOTKEY COMMAND: CORE ALREADY SUSPENDED
    if (cursor->x == -30000)
    {
        out.printerr("The cursor is not active.\n");
        return CR_WRONG_USAGE;
    }
    if (!Maps::IsValid())
    {
        out.printerr("Map is not available.\n");
        return CR_FAILURE;
    }
    df::map_block *block = Maps::getTileBlock(cursor->x, cursor->y, cursor->z);
    if (block == NULL)
    {
        out.printerr("Invalid map block selected!\n");
        return CR_FAILURE;
    }

    for (size_t i = 0; i < block->block_events.size(); i++)
    {
        df::block_square_event *evt = block->block_events[i];
        if (evt->getType() != block_square_event_type::material_spatter)
            continue;
        // type verified - recast to subclass
        df::block_square_event_material_spatterst *spatter = (df::block_square_event_material_spatterst *)evt;
        spatter->amount[cursor->x % 16][cursor->y % 16] = 0;
    }
    return CR_OK;
}
Пример #4
0
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;
}
Пример #5
0
static command_result rename(color_ostream &out, vector <string> &parameters)
{
    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;
}
Пример #6
0
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;
}
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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;
}
Пример #11
0
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;
}
Пример #12
0
command_result df_immolate (color_ostream &out, vector <string> & parameters, do_what what)
{
    bool shrubs = false, trees = false, help = false;
    if (getoptions(parameters, shrubs, trees, help) && !help)
    {
        return immolations(out, what, shrubs, trees);
    }

    string mode;
    if (what == do_immolate)
        mode = "Set plants on fire";
    else
        mode = "Kill plants";

    if (!help)
        out.printerr("Invalid parameter!\n");

    out << "Usage:\n" <<
        mode << " (under cursor, 'shrubs', 'trees' or 'all').\n"
        "Without any options, this command acts on the plant under the cursor.\n"
        "Options:\n"
        "shrubs   - affect all shrubs\n"
        "trees    - affect all trees\n"
        "all      - affect all plants\n";

    return CR_OK;
}
Пример #13
0
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;
}
Пример #14
0
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);
}
Пример #15
0
bool read_order(color_ostream &out, lua_State *L, std::vector<unsigned> *order, size_t size)
{
    std::vector<char> found;

    Lua::StackUnwinder frame(L, 1);

    if (!lua_istable(L, -1))
    {
        out.printerr("Not a table returned as ordering.\n");
        return false;
    }

    if (lua_rawlen(L, -1) != size)
    {
        out.printerr("Invalid ordering size: expected %d, actual %d\n", size, lua_rawlen(L, -1));
        return false;
    }

    order->clear();
    order->resize(size);
    found.resize(size);

    for (size_t i = 1; i <= size; i++)
    {
        lua_rawgeti(L, frame[1], i);
        int v = lua_tointeger(L, -1);
        lua_pop(L, 1);

        if (v < 1 || size_t(v) > size)
        {
            out.printerr("Order value out of range: %d\n", v);
            return false;
        }

        if (found[v-1])
        {
            out.printerr("Duplicate order value: %d\n", v);
            return false;
        }

        found[v-1] = 1;
        (*order)[i-1] = v-1;
    }

    return true;
}
Пример #16
0
command_result misery(color_ostream &out, vector<string>& parameters) {
    if ( !world || !world->map.block_index ) {
        out.printerr("misery can only be enabled in fortress mode with a fully-loaded game.\n");
        return CR_FAILURE;
    }
    
    if ( parameters.size() < 1 || parameters.size() > 2 ) {
        return CR_WRONG_USAGE;
    }
    
    if ( parameters[0] == "disable" ) {
        if ( parameters.size() > 1 ) {
            return CR_WRONG_USAGE;
        }
        factor = 1;
        is_enabled = false;
        return CR_OK;
    } else if ( parameters[0] == "enable" ) {
        is_enabled = true;
        factor = 2;
        if ( parameters.size() == 2 ) {
            int a = atoi(parameters[1].c_str());
            if ( a <= 1 ) {
                out.printerr("Second argument must be a positive integer.\n");
                return CR_WRONG_USAGE;
            }
            factor = a;
        }
    } else if ( parameters[0] == "clear" ) {
        for ( size_t a = 0; a < fakeThoughts.size(); a++ ) {
            int dorfIndex = fakeThoughts[a].first;
            int thoughtIndex = fakeThoughts[a].second;
            world->units.all[dorfIndex]->status.recent_events[thoughtIndex]->age = 1000000;
        }
        fakeThoughts.clear();
    } else {
        int a = atoi(parameters[0].c_str());
        if ( a < 1 ) {
            return CR_WRONG_USAGE;
        }
        factor = a;
        is_enabled = factor > 1;
    }
    
    return CR_OK;
}
Пример #17
0
command_result reveal(color_ostream &out, vector<string> & params)
{
    bool pause = true;
    for(size_t i = 0; i < params.size();i++)
    {
        if(params[i] == "help" || params[i] == "?")
            return CR_WRONG_USAGE;
    }
    auto & con = out;
    if(revealed != NOT_REVEALED)
    {
        con.printerr("Map is already revealed or this is a different map.\n");
        return CR_FAILURE;
    }

    CoreSuspender suspend;

    if (!Maps::IsValid())
    {
        out.printerr("Map is not available!\n");
        return CR_FAILURE;
    }
    t_gamemodes gm;
    World::ReadGameMode(gm);
    if(gm.g_mode == game_mode::ADVENTURE)
    {
        revealAdventure(out);
        return CR_OK;
    }
    if(gm.g_mode != game_mode::DWARF)
    {
        con.printerr("Only in fortress mode.\n");
        return CR_FAILURE;
    }

    Maps::getSize(x_max,y_max,z_max);
    hidesaved.reserve(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];
        hideblock hb;
        hb.c = block->map_pos;
        designations40d & designations = block->designation;
        // for each tile in block
        for (uint32_t x = 0; x < 16; x++) for (uint32_t y = 0; y < 16; y++)
        {
            // save hidden state of tile
            hb.hiddens[x][y] = designations[x][y].bits.hidden;
            // set to revealed
            designations[x][y].bits.hidden = 0;
        }
        hidesaved.push_back(hb);
    }
    revealed = REVEALED;
    con.print("Map revealed.\n");
    con.print("Run 'unreveal' to revert to previous state.\n");
    return CR_OK;
}
Пример #18
0
/**
 * Initialize the plugin
 */
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
    // This seems to verify that the default labor list and the current labor
    // list are the same size
    if(ARRAY_COUNT(default_labor_infos) != ENUM_LAST_ITEM(unit_labor) + 1)
    {
        out.printerr("autohauler: labor size mismatch\n");
        return CR_FAILURE;
    }

    // Essentially an introduction dumped to the console
    commands.push_back(PluginCommand(
        "autohauler", "Automatically manage hauling labors.",
        autohauler, false, /* true means that the command can't be used from non-interactive user interface */
        // Extended help string. Used by CR_WRONG_USAGE and the help command:
        "  autohauler enable\n"
        "  autohauler disable\n"
        "    Enables or disables the plugin.\n"
        "  autohauler <labor> haulers\n"
        "    Set a labor to be handled by hauler dwarves.\n"
        "  autohauler <labor> allow\n"
        "    Allow hauling if a specific labor is enabled.\n"
        "  autohauler <labor> forbid\n"
        "    Forbid hauling if a specific labor is enabled.\n"
        "  autohauler <labor> reset\n"
        "    Return a labor to the default handling.\n"
        "  autohauler reset-all\n"
        "    Return all labors to the default handling.\n"
        "  autohauler frameskip <int>\n"
        "    Set the number of frames between runs of autohauler.\n"
        "  autohauler list\n"
        "    List current status of all labors.\n"
        "  autohauler status\n"
        "    Show basic status information.\n"
        "  autohauler debug\n"
        "    In the next cycle, will output the state of every dwarf.\n"
        "Function:\n"
        "  When enabled, autohauler periodically checks your dwarves and assigns\n"
        "  hauling jobs to idle dwarves while removing them from busy dwarves.\n"
        "  This plugin, in contrast to autolabor, is explicitly designed to be\n"
        "  used alongside Dwarf Therapist.\n"
        "  Warning: autohauler will override any manual changes you make to\n"
        "  hauling labors while it is enabled...but why would you make them?\n"
        "Examples:\n"
        "  autohauler HAUL_STONE haulers\n"
        "    Set stone hauling as a hauling labor.\n"
        "  autohauler BOWYER allow\n"
        "    Allow hauling when the bowyer labor is enabled.\n"
        "  autohauler MINE forbid\n"
        "    Forbid hauling while the mining labor is disabled."
    ));

    // Initialize plugin labor lists
    init_state();

    return CR_OK;
}
Пример #19
0
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;
}
Пример #20
0
static bool ParseSpec(color_ostream &out, lua_State *L, const char *type, vector<string> &params)
{
    if (!parse_ordering_spec(out, L, type, params))
    {
        out.printerr("Invalid ordering specification for %s.\n", type);
        return false;
    }

    return true;
}
Пример #21
0
void DFHack::Lua::Core::Reset(color_ostream &out, const char *where)
{
    int top = lua_gettop(State);

    if (top != 0)
    {
        out.printerr("Common lua context stack top left at %d after %s.\n", top, where);
        lua_settop(State, 0);
    }
}
Пример #22
0
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;
}
Пример #23
0
static void enable_plugin(color_ostream &out)
{
    auto entry = World::GetPersistentData("fix-armory/enabled", NULL);
    if (!entry.isValid())
    {
        out.printerr("Could not save the status.\n");
        return;
    }

    enable_hooks(out, true);
}
Пример #24
0
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
{
    if (!gps || !INTERPOSE_HOOK(hotkeys_hook, feed).apply() || !INTERPOSE_HOOK(hotkeys_hook, render).apply())
        out.printerr("Could not insert hotkeys hooks!\n");

    commands.push_back(
        PluginCommand(
        "hotkeys", "List all keybindings active in current mode",
        hotkeys_cmd, false, ""));

    return CR_OK;
}
Пример #25
0
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] == "?")
            return CR_WRONG_USAGE;
    }
    if(!revealed)
    {
        con.printerr("There's nothing to revert!\n");
        return CR_FAILURE;
    }
    CoreSuspender suspend;

    if (!Maps::IsValid())
    {
        out.printerr("Map is not available!\n");
        return CR_FAILURE;
    }
    t_gamemodes gm;
    World::ReadGameMode(gm);
    if(gm.g_mode != game_mode::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::getTileBlock(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;
    is_active = nopause_state || (revealed == REVEALED);
    con.print("Map hidden!\n");
    return CR_OK;
}
Пример #26
0
bool bodySwap(color_ostream &out, df::unit *player)
{
    if (!player)
    {
        out.printerr("Unit to swap is NULL\n");
        return false;
    }

    auto &vec = world->units.active;

    int idx = linear_index(vec, player);
    if (idx < 0)
    {
        out.printerr("Unit to swap not found: %d\n", player->id);
        return false;
    }

    if (idx != 0)
        std::swap(vec[0], vec[idx]);

    return true;
}
Пример #27
0
command_result df_changevein (color_ostream &out, vector <string> & parameters)
{
    if (parameters.size() != 1)
        return CR_WRONG_USAGE;

    CoreSuspender suspend;

    if (!Maps::IsValid())
    {
        out.printerr("Map is not available!\n");
        return CR_FAILURE;
    }
    if (!cursor || cursor->x == -30000)
    {
        out.printerr("No cursor detected - please place the cursor over a mineral vein.\n");
        return CR_FAILURE;
    }

    MaterialInfo mi;
    if (!mi.findInorganic(parameters[0]))
    {
        out.printerr("No such material!\n");
        return CR_FAILURE;
    }
    if (mi.inorganic->material.flags.is_set(material_flags::IS_METAL) ||
        mi.inorganic->material.flags.is_set(material_flags::NO_STONE_STOCKPILE) ||
        mi.inorganic->flags.is_set(inorganic_flags::SOIL_ANY))
    {
        out.printerr("Invalid material - you must select a type of stone or gem\n");
        return CR_FAILURE;
    }

    df::map_block *block = Maps::getBlockAbs(cursor->x, cursor->y, cursor->z);
    if (!block)
    {
        out.printerr("Invalid tile selected.\n");
        return CR_FAILURE;
    }
    df::block_square_event_mineralst *mineral = NULL;
    int tx = cursor->x % 16, ty = cursor->y % 16;
    for (size_t j = 0; j < block->block_events.size(); j++)
    {
        df::block_square_event *evt = block->block_events[j];
        if (evt->getType() != block_square_event_type::mineral)
            continue;
        mineral = (df::block_square_event_mineralst *)evt;
        if (mineral->getassignment(tx, ty))
            break;
        mineral = NULL;
    }
    if (!mineral)
    {
        out.printerr("Selected tile does not contain a mineral vein.\n");
        return CR_FAILURE;
    }
    mineral->inorganic_mat = mi.index;

    return CR_OK;
}
Пример #28
0
command_result df_extirpate (color_ostream &out, vector <string> & parameters)
{
    bool shrubs = false, trees = false, help = false;
    if(getoptions(parameters,shrubs,trees, help))
    {
        return immolations(out,do_extirpate,shrubs,trees, help);
    }
    else
    {
        out.printerr("Invalid parameter!\n");
        return CR_FAILURE;
    }
}
Пример #29
0
DFhackCExport command_result plugin_onupdate(color_ostream &out)
{
    if (running)
    {
        // reduce processing rate
        static int counter = 0;
        if (++counter < 500)
            return CR_OK;
        counter = 0;

        t_gamemodes gm;
        World::ReadGameMode(gm);// FIXME: check return value
        // if game mode isn't fortress mode
        if(gm.g_mode != game_mode::DWARF || 
            !(gm.g_type == game_type::DWARF_MAIN || gm.g_type == game_type::DWARF_RECLAIM))
        {
            // stop running.
            running = false;
            out.printerr("seedwatch deactivated due to game mode switch\n");
            return CR_OK;
        }
        // this is dwarf mode, continue
        map<t_materialSubtype, unsigned int> seedCount; // the number of seeds

        // count all seeds and plants by RAW material
        for(size_t i = 0; i < world->items.other[items_other_id::ANY_GOOD_FOOD].size(); ++i)
        {
            df::item * item = world->items.other[items_other_id::ANY_GOOD_FOOD][i];
            if (item->getType() != item_type::SEEDS)
                continue;
            t_materialSubtype plant = item->getMatgloss();
            if(!ignoreSeeds(item->flags)) ++seedCount[plant];
        }

        map<t_materialSubtype, unsigned int> watchMap;
        Kitchen::fillWatchMap(watchMap);
        for(auto i = watchMap.begin(); i != watchMap.end(); ++i)
        {
            if(seedCount[i->first] <= i->second)
            {
                Kitchen::denyPlantSeedCookery(i->first);
            }
            else if(i->second + buffer < seedCount[i->first])
            {
                Kitchen::allowPlantSeedCookery(i->first);
            }
        }
    }
    return CR_OK;
}
Пример #30
0
DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
{
    if (!Core::getInstance().isWorldLoaded()) {
        out.printerr("World is not loaded: please load a game first.\n");
        return CR_FAILURE;
    }

    if (enable)
        enable_plugin(out);
    else
        disable_plugin(out);

    return CR_OK;
}