Example #1
0
void printHelp(color_ostream &out) // prints help
{
    out.print(
        "Watches the numbers of seeds available and enables/disables seed and plant cooking.\n"
        "Each plant type can be assigned a limit. If their number falls below,\n"
        "the plants and seeds of that type will be excluded from cookery.\n"
        "If the number rises above the limit + %i, then cooking will be allowed.\n", buffer
        );
    out.printerr(
        "The plugin needs a fortress to be loaded and will deactivate automatically otherwise.\n"
        "You have to reactivate with 'seedwatch start' after you load the game.\n"
        );
    out.print(
        "Options:\n"
        "seedwatch all   - Adds all plants from the abbreviation list to the watch list.\n"
        "seedwatch start - Start watching.\n"
        "seedwatch stop  - Stop watching.\n"
        "seedwatch info  - Display whether seedwatch is watching, and the watch list.\n"
        "seedwatch clear - Clears the watch list.\n\n"
        );
    if(!abbreviations.empty())
    {
        out.print("You can use these abbreviations for the plant tokens:\n");
        for(map<string, string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
        {
            out.print("%s -> %s\n", i->first.c_str(), i->second.c_str());
        }
    }
    out.print(
        "Examples:\n"
        "seedwatch MUSHROOM_HELMET_PLUMP 30\n"
        "  add MUSHROOM_HELMET_PLUMP to the watch list, limit = 30\n"
        "seedwatch MUSHROOM_HELMET_PLUMP\n"
        "  removes MUSHROOM_HELMET_PLUMP from the watch list.\n"
        "seedwatch ph 30\n"
        "  is the same as 'seedwatch MUSHROOM_HELMET_PLUMP 30'\n"
        "seedwatch all 30\n"
        "  adds all plants from the abbreviation list to the watch list, the limit being 30.\n"
        );
};
Example #2
0
command_result df_flows (color_ostream &out, vector <string> & parameters)
{
    CoreSuspender suspend;

    int flow1 = 0, flow2 = 0, flowboth = 0, water = 0, magma = 0;
    out.print("Counting flows and liquids ...\n");

    for (size_t i = 0; i < world->map.map_blocks.size(); i++)
    {
        df::map_block *cur = world->map.map_blocks[i];
        if (cur->flags.bits.update_liquid)
            flow1++;
        if (cur->flags.bits.update_liquid_twice)
            flow2++;
        if (cur->flags.bits.update_liquid && cur->flags.bits.update_liquid_twice)
            flowboth++;
        for (int x = 0; x < 16; x++)
        {
            for (int y = 0; y < 16; y++)
            {
                // only count tiles with actual liquid in them
                if (cur->designation[x][y].bits.flow_size == 0)
                    continue;
                if (cur->designation[x][y].bits.liquid_type == tile_liquid::Magma)
                    magma++;
                if (cur->designation[x][y].bits.liquid_type == tile_liquid::Water)
                    water++;
            }
        }
    }

    out.print("Blocks with liquid_1=true: %d\n", flow1);
    out.print("Blocks with liquid_2=true: %d\n", flow2);
    out.print("Blocks with both:          %d\n", flowboth);
    out.print("Water tiles:               %d\n", water);
    out.print("Magma tiles:               %d\n", magma);
    return CR_OK;
}
Example #3
0
static void world_specific_hooks(color_ostream &out,bool enable)
{
    if(enable && find_reactions(out))
    {
        out.print("Detected reaction hooks - enabling plugin.\n");
        INTERPOSE_HOOK(product_hook, produce).apply(true);
    }
    else
    {
       INTERPOSE_HOOK(product_hook, produce).apply(false);
        reactions.clear();
        products.clear();
    }
}
Example #4
0
static command_result df_rubyload(color_ostream &out, std::vector <std::string> & parameters)
{
    if (parameters.size() == 1 && (parameters[0] == "help" || parameters[0] == "?"))
    {
        out.print("This command loads the ruby script whose path is given as parameter, and run it.\n");
        return CR_OK;
    }

    std::string cmd = "load '";
    cmd += parameters[0];       // TODO escape singlequotes
    cmd += "'";

    return plugin_eval_rb(cmd);
}
Example #5
0
command_result df_liquids_here (color_ostream &out, vector <string> & parameters)
{
    for(size_t i = 0; i < parameters.size();i++)
    {
        if(parameters[i] == "help" || parameters[i] == "?")
            return CR_WRONG_USAGE;
    }

    out.print("Run liquids-here with these parameters: ");
    print_prompt(out, cur_mode);
    out << endl;

    return df_liquids_execute(out);
}
Example #6
0
static void setJobResumed(color_ostream &out, ProtectedJob *pj, bool goal)
{
    bool current = pj->isResumed();

    pj->set_resumed(goal);

    if (goal != current)
    {
        out.print("%s %s%s\n",
                     (goal ? "Resuming" : "Suspending"),
                     shortJobDescription(pj->actual_job).c_str(),
                     (!goal || pj->isActuallyResumed() ? "" : " (delayed)"));
    }
}
Example #7
0
// dump some cage info
void cageInfo(color_ostream & out, df::building* building, bool verbose = false)
{
    if(!isCage(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");

	out << "x:"  << building->x1
		<< " y:" << building->y1
		<< " z:" << building->z
		<< endl;

    df::building_cagest * cage = (df::building_cagest*) building;
    int32_t creaturecount = cage->assigned_creature.size();
    out << "Creatures in this cage: " << creaturecount << endl;
    for(size_t c = 0; c < creaturecount; c++)
    {
        int32_t cindex = cage->assigned_creature.at(c);

        // print list of all units assigned to that cage
        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);
        }
    }
}
Example #8
0
void doInfiniteSky(color_ostream& out, int32_t howMany) {
    CoreSuspender suspend;
    int32_t x_count_block = world->map.x_count_block;
    int32_t y_count_block = world->map.y_count_block;
    for ( int32_t count = 0; count < howMany; count++ ) {
        //change the size of the pointer stuff
        int32_t z_count_block = world->map.z_count_block;
        df::map_block**** block_index = world->map.block_index;
        for ( int32_t a = 0; a < x_count_block; a++ ) {
            for ( int32_t b = 0; b < y_count_block; b++ ) {
                df::map_block** blockColumn = new df::map_block*[z_count_block+1];
                memcpy(blockColumn, block_index[a][b], z_count_block*sizeof(df::map_block*));
                blockColumn[z_count_block] = NULL;
                delete[] block_index[a][b];
                block_index[a][b] = blockColumn;

                //deal with map_block_column stuff even though it'd probably be fine
                df::map_block_column* column = world->map.column_index[a][b];
                if ( !column ) {
                    out.print("%s, line %d: column is null (%d, %d).\n", __FILE__, __LINE__, a, b);
                    continue;
                }
                df::map_block_column::T_unmined_glyphs* glyphs = new df::map_block_column::T_unmined_glyphs;
                glyphs->x[0] = 0;
                glyphs->x[1] = 1;
                glyphs->x[2] = 2;
                glyphs->x[3] = 3;
                glyphs->y[0] = 0;
                glyphs->y[1] = 0;
                glyphs->y[2] = 0;
                glyphs->y[3] = 0;
                glyphs->tile[0] = 'e';
                glyphs->tile[1] = 'x';
                glyphs->tile[2] = 'p';
                glyphs->tile[3] = '^';
                column->unmined_glyphs.push_back(glyphs);
            }
        }
        df::z_level_flags* flags = new df::z_level_flags[z_count_block+1];
        memcpy(flags, world->map_extras.z_level_flags, z_count_block*sizeof(df::z_level_flags));
        flags[z_count_block].whole = 0;
        flags[z_count_block].bits.update = 1;
        world->map.z_count_block++;
        world->map.z_count++;
        delete[] world->map_extras.z_level_flags;
        world->map_extras.z_level_flags = flags;
    }
    
}
Example #9
0
DFhackCExport command_result workNow(color_ostream& out, vector<string>& parameters) {
    if ( parameters.size() == 0 ) {
        out.print("workNow status = %d\n", mode);
        return CR_OK;
    }
    if ( parameters.size() > 1 ) {
        return CR_WRONG_USAGE;
    }
    int32_t a = atoi(parameters[0].c_str());
    
    if (a < 0 || a > 2)
        return CR_WRONG_USAGE;

    if ( a == 2 && mode != 2 ) {
        EventManager::registerListener(EventManager::EventType::JOB_COMPLETED, handler, plugin_self);
    } else if ( mode == 2 && a != 2 ) {
        EventManager::unregister(EventManager::EventType::JOB_COMPLETED, handler, plugin_self);
    }

    mode = a;
    out.print("workNow status = %d\n", mode);

    return CR_OK;
}
Example #10
0
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)
    {
        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;
    return CR_OK;
}
Example #11
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;
}
Example #12
0
void revealAdventure(color_ostream &out)
{
    for (size_t i = 0; i < world->map.map_blocks.size(); i++)
    {
        df::map_block *block = world->map.map_blocks[i];
        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++)
        {
            // set to revealed
            designations[x][y].bits.hidden = 0;
            // and visible
            designations[x][y].bits.pile = 1;
        }
    }
    out.print("Local map revealed.\n");
}
Example #13
0
void describeTile(color_ostream &out, df::tiletype tiletype)
{
    out.print("%d", tiletype);
    if(tileName(tiletype))
        out.print(" = %s",tileName(tiletype));
    out.print("\n");

    df::tiletype_shape shape = tileShape(tiletype);
    df::tiletype_material material = tileMaterial(tiletype);
    df::tiletype_special special = tileSpecial(tiletype);
    df::tiletype_variant variant = tileVariant(tiletype);
    out.print("%-10s: %4d %s\n","Class"    ,shape,
              ENUM_KEY_STR(tiletype_shape, shape).c_str());
    out.print("%-10s: %4d %s\n","Material" ,
              material, ENUM_KEY_STR(tiletype_material, material).c_str());
    out.print("%-10s: %4d %s\n","Special"  ,
              special, ENUM_KEY_STR(tiletype_special, special).c_str());
    out.print("%-10s: %4d %s\n"   ,"Variant"  ,
              variant, ENUM_KEY_STR(tiletype_variant, variant).c_str());
    out.print("%-10s: %s\n"    ,"Direction",
              tileDirection(tiletype).getStr());
    out.print("\n");
}
Example #14
0
command_result ktimer (color_ostream &out, vector <string> & parameters)
{
    if(timering)
    {
        timering = false;
        return CR_OK;
    }
    uint64_t timestart = GetTimeMs64();
    {
        CoreSuspender suspend;
    }
    uint64_t timeend = GetTimeMs64();
    out.print("Time to suspend = %d ms\n",timeend - timestart);
    // harmless potential data race here...
    timeLast = timeend;
    timering = true;
    return CR_OK;
}
Example #15
0
command_result revtoggle (color_ostream &out, vector<string> & params)
{
    for(size_t i = 0; i < params.size();i++)
    {
        if(params[i] == "help" || params[i] == "?")
        {
            out.print("Toggles between reveal and unreveal.\nCurrently it: ");
            break;
        }
    }
    if(revealed)
    {
        return unreveal(out,params);
    }
    else
    {
        return reveal(out,params);
    }
}
Example #16
0
File: ruby.cpp Project: Reag/dfhack
static command_result df_rubyeval(color_ostream &out, std::vector <std::string> & parameters)
{
    if (parameters.size() == 1 && (parameters[0] == "help" || parameters[0] == "?"))
    {
        out.print("This command executes an arbitrary ruby statement.\n");
        return CR_OK;
    }

    // reconstruct the text from dfhack console line
    std::string full = "";

    for (unsigned i=0 ; i<parameters.size() ; ++i) {
        full += parameters[i];
        if (i != parameters.size()-1)
            full += " ";
    }

    return plugin_eval_ruby(out, full.c_str());
}
Example #17
0
command_result df_cprobe (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 probe.\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)
            {
                out.print("Creature %d, race %d (%x), civ %d (%x)\n", unit->id, unit->race, unit->race, unit->civ_id, unit->civ_id);
                
                for(size_t j=0; j<unit->inventory.size(); j++)
                {
                    df::unit_inventory_item* inv_item = unit->inventory[j];
                    df::item* item = inv_item->item;
                    if(inv_item->mode == df::unit_inventory_item::T_mode::Worn)
                    {
                        out << "   wears item: #" << item->id;
                        if(item->flags.bits.owned)
                            out << " (owned)";
                        else
                            out << " (not owned)";
                        if(item->getEffectiveArmorLevel() != 0)
                            out << ", armor";
                        out << endl;
                    }
                }
                
                // don't leave loop, there may be more than 1 creature at the cursor position
                //break;
            }
        }
    }
    return CR_OK;
}
Example #18
0
command_result df_liquids_here (color_ostream &out, vector <string> & parameters)
{
    for(size_t i = 0; i < parameters.size();i++)
    {
        if(parameters[i] == "help" || parameters[i] == "?")
        {
            out << "This command is supposed to be mapped to a hotkey." << endl;
            out << "It will use the current/last parameters set in liquids." << endl;
            return CR_OK;
        }
    }

    out.print("Run liquids-here with these parameters: ");
    out << "[" << mode << ":" << brushname;
    if (brushname == "range")
        out << "(w" << width << ":h" << height << ":z" << z_levels << ")";
    out << ":" << amount << ":" << flowmode << ":" << setmode << "]\n";

    return df_liquids_execute(out);
}
Example #19
0
command_result cleanunits (color_ostream &out)
{
    // Invoked from clean(), already suspended
    int cleaned_units = 0, cleaned_total = 0;
    for (size_t i = 0; i < world->units.all.size(); i++)
    {
        df::unit *unit = world->units.all[i];
        if (unit->body.spatters.size())
        {
            for (size_t j = 0; j < unit->body.spatters.size(); j++)
                delete unit->body.spatters[j];
            cleaned_units++;
            cleaned_total += unit->body.spatters.size();
            unit->body.spatters.clear();
        }
    }
    if (cleaned_total)
        out.print("Removed %d contaminants from %d creatures.\n", cleaned_total, cleaned_units);
    return CR_OK;
}
Example #20
0
// A command! It sits around and looks pretty. And it's nice and friendly.
command_result skeleton (color_ostream &out, std::vector <std::string> & parameters)
{
    // It's nice to print a help message you get invalid options
    // from the user instead of just acting strange.
    // This can be achieved by adding the extended help string to the
    // PluginCommand registration as show above, and then returning
    // CR_WRONG_USAGE from the function. The same string will also
    // be used by 'help your-command'.
    if (!parameters.empty())
        return CR_WRONG_USAGE;
    // Commands are called from threads other than the DF one.
    // Suspend this thread until DF has time for us. If you
    // use CoreSuspender, it'll automatically resume DF when
    // execution leaves the current scope.
    CoreSuspender suspend;
    // Actually do something here. Yay.
    out.print("Hello! I do nothing, remember?\n");
    // Give control back to DF.
    return CR_OK;
}
Example #21
0
void revealAdventure(color_ostream &out)
{
    for (size_t i = 0; i < world->map.map_blocks.size(); i++)
    {
        df::map_block *block = world->map.map_blocks[i];
        // in 'no-hell'/'safe' mode, don't reveal blocks with hell and adamantine
        if (!isSafe(block->map_pos))
            continue;
        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++)
        {
            // set to revealed
            designations[x][y].bits.hidden = 0;
            // and visible
            designations[x][y].bits.pile = 1;
        }
    }
    out.print("Local map revealed.\n");
}
Example #22
0
static command_result df_rubyeval(color_ostream &out, std::vector <std::string> & parameters)
{
    command_result ret;

    if (parameters.size() == 1 && (parameters[0] == "help" || parameters[0] == "?"))
    {
        out.print("This command executes an arbitrary ruby statement.\n");
        return CR_OK;
    }

    std::string full = "";

    for (unsigned i=0 ; i<parameters.size() ; ++i) {
        full += parameters[i];
        if (i != parameters.size()-1)
            full += " ";
    }

    return plugin_eval_rb(full);
}
Example #23
0
command_result cleanplants (color_ostream &out)
{
    // Invoked from clean(), already suspended
    int cleaned_plants = 0, cleaned_total = 0;
    for (size_t i = 0; i < world->plants.all.size(); i++)
    {
        df::plant *plant = world->plants.all[i];

        if (plant->contaminants.size())
        {
            for (size_t j = 0; j < plant->contaminants.size(); j++)
                delete plant->contaminants[j];
            cleaned_plants++;
            cleaned_total += plant->contaminants.size();
            plant->contaminants.clear();
        }
    }
    if (cleaned_total)
        out.print("Removed %d contaminants from %d plants.\n", cleaned_total, cleaned_plants);
    return CR_OK;
}
Example #24
0
void checkBuildings(color_ostream& out, void* data) {
    if ( !enabled )
        return;
    
    std::vector<df::building*>& buildings = df::global::world->buildings.all;
    for ( size_t a = 0; a < buildings.size(); a++ ) {
        df::building* building = buildings[a];
        if ( building == NULL )
            continue;
        if ( building->getCustomType() < 0 )
            continue;
        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 )
                continue;
            destroy(building);
        } else if ( type == INSIDE_ONLY ) {
            if ( !outside )
                continue;
            destroy(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);
            }
        }
    }
    
    if ( checkEvery < 0 )
        return;
    EventManager::EventHandler timeHandler(checkBuildings,-1);
    EventManager::registerTick(timeHandler, checkEvery, plugin_self);
}
Example #25
0
command_result revforget(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("Forget the current reveal data, allowing to use reveal again.\n");
            return CR_OK;
        }
    }
    if(!revealed)
    {
        con.printerr("There's nothing to forget!\n");
        return CR_FAILURE;
    }
    // give back memory.
    hidesaved.clear();
    revealed = NOT_REVEALED;
    con.print("Reveal data forgotten!\n");
    return CR_OK;
}
Example #26
0
DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event)
{
    switch (event) {
    case SC_WORLD_LOADED:
        if (find_reactions(out))
        {
            out.print("Detected spatter add reactions - enabling plugin.\n");
            enable_hooks(true);
        }
        else
            enable_hooks(false);
        break;
    case SC_WORLD_UNLOADED:
        enable_hooks(false);
        reactions.clear();
        products.clear();
        break;
    default:
        break;
    }

    return CR_OK;
}
Example #27
0
command_result trackmenu (color_ostream &out, vector <string> & parameters)
{
    if(trackmenu_flg)
    {
        trackmenu_flg = false;
        return CR_OK;
    }
    else
    {
        if(df::global::ui)
        {
            trackmenu_flg = true;
            last_menu = df::global::ui->main.mode;
            out.print("Menu: %d\n",last_menu);
            return CR_OK;
        }
        else
        {
            out.printerr("Can't read menu state\n");
            return CR_FAILURE;
        }
    }
}
Example #28
0
command_result df_createitem (color_ostream &out, vector <string> & parameters)
{
    string item_str, material_str;
    df::item_type item_type = item_type::NONE;
    int16_t item_subtype = -1;
    int16_t mat_type = -1;
    int32_t mat_index = -1;
    int count = 1;
    bool move_to_cursor = false;

    if (parameters.size() == 1)
    {
        if (parameters[0] == "floor")
        {
            dest_container = -1;
            dest_building = -1;
            out.print("Items created will be placed on the floor.\n");
            return CR_OK;
        }
        else if (parameters[0] == "item")
        {
            dest_building = -1;
            df::item *item = Gui::getSelectedItem(out);
            if (!item)
            {
                out.printerr("You must select a container!\n");
                return CR_FAILURE;
            }
            switch (item->getType())
            {
            case item_type::FLASK:
            case item_type::BARREL:
            case item_type::BUCKET:
            case item_type::ANIMALTRAP:
            case item_type::BOX:
            case item_type::BIN:
            case item_type::BACKPACK:
            case item_type::QUIVER:
                break;
            case item_type::TOOL:
                if (item->hasToolUse(tool_uses::LIQUID_CONTAINER))
                    break;
                if (item->hasToolUse(tool_uses::FOOD_STORAGE))
                    break;
                if (item->hasToolUse(tool_uses::SMALL_OBJECT_STORAGE))
                    break;
                if (item->hasToolUse(tool_uses::TRACK_CART))
                    break;
            default:
                out.printerr("The selected item cannot be used for item storage!\n");
                return CR_FAILURE;
            }
            dest_container = item->id;
            string name;
            item->getItemDescription(&name, 0);
            out.print("Items created will be placed inside %s.\n", name.c_str());
            return CR_OK;
        }
        else if (parameters[0] == "building")
        {
            dest_container = -1;
            df::building *building = Gui::getSelectedBuilding(out);
            if (!building)
            {
                out.printerr("You must select a building!\n");
                return CR_FAILURE;
            }
            switch (building->getType())
            {
            case building_type::Coffin:
            case building_type::Furnace:
            case building_type::TradeDepot:
            case building_type::Shop:
            case building_type::Box:
            case building_type::Weaponrack:
            case building_type::Armorstand:
            case building_type::Workshop:
            case building_type::Cabinet:
            case building_type::SiegeEngine:
            case building_type::Trap:
            case building_type::AnimalTrap:
            case building_type::Cage:
            case building_type::Wagon:
            case building_type::NestBox:
            case building_type::Hive:
                break;
            default:
                out.printerr("The selected building cannot be used for item storage!\n");
                return CR_FAILURE;
            }
            if (building->getBuildStage() != building->getMaxBuildStage())
            {
                out.printerr("The selected building has not yet been fully constructed!\n");
                return CR_FAILURE;
            }
            dest_building = building->id;
            string name;
            building->getName(&name);
            out.print("Items created will be placed inside %s.\n", name.c_str());
            return CR_OK;
        }
        else
            return CR_WRONG_USAGE;
    }

    if ((parameters.size() < 2) || (parameters.size() > 3))
        return CR_WRONG_USAGE;

    item_str = parameters[0];
    material_str = parameters[1];

    if (parameters.size() == 3)
    {
        stringstream ss(parameters[2]);
        ss >> count;
        if (count < 1)
        {
            out.printerr("You cannot produce less than one item!\n");
            return CR_FAILURE;
        }
    }
Example #29
0
command_result changelayer (color_ostream &out, std::vector <std::string> & parameters)
{
    CoreSuspender suspend; 

    string material;
    bool force = false;
    bool all_biomes = false;
    bool all_layers = false;
    bool verbose = false;
    warned = false;

    for(size_t i = 0; i < parameters.size();i++)
    {
        if(parameters[i] == "help" || parameters[i] == "?")
        {
            out.print(changelayer_help.c_str());
            return CR_OK;
        }
        if(parameters[i] == "trouble")
        {
            out.print(changelayer_trouble.c_str());
            return CR_OK;
        }
        if(parameters[i] == "force")
            force = true;
        if(parameters[i] == "all_biomes")
            all_biomes = true;
        if(parameters[i] == "all_layers")
            all_layers = true;
        if(parameters[i] == "verbose")
            verbose = true;
    }

    if (!Maps::IsValid())
    {
        out.printerr("Map is not available!\n");
        return CR_FAILURE;
    }

    if (parameters.empty())
    {
        out.printerr("You need to specify a material!\n");
        return CR_WRONG_USAGE;
    }

    material = parameters[0];

    MaterialInfo mat_new;
    if (!mat_new.findInorganic(material))
    {
        out.printerr("No such material!\n");
        return CR_FAILURE;
    }

    // check if specified material is stone or gem or soil
    if (mat_new.inorganic->material.flags.is_set(material_flags::IS_METAL) ||
        mat_new.inorganic->material.flags.is_set(material_flags::NO_STONE_STOCKPILE))
    {
        out.printerr("Invalid material - you must select a type of stone or gem or soil.\n");
        return CR_FAILURE;
    }


    MapExtras::MapCache mc;

    int32_t regionX, regionY, regionZ;
    Maps::getPosition(regionX,regionY,regionZ);

    int32_t cursorX, cursorY, cursorZ;
    Gui::getCursorCoords(cursorX,cursorY,cursorZ);
    if(cursorX == -30000)
    {
        out.printerr("No cursor; place cursor over tile.\n");
        return CR_FAILURE;
    }
    DFCoord cursor (cursorX,cursorY,cursorZ);

    uint32_t blockX = cursorX / 16;
    uint32_t tileX = cursorX % 16;
    uint32_t blockY = cursorY / 16;
    uint32_t tileY = cursorY % 16;

    MapExtras::Block * b = mc.BlockAt(cursor/16);
    if(!b || !b->is_valid())
    {
        out.printerr("No data.\n");
        return CR_OK;
    }

    df::tile_designation des = b->DesignationAt(cursor%16);

    // get biome and geolayer at cursor position
    uint32_t biome = des.bits.biome;
    uint32_t layer = des.bits.geolayer_index;
    if(verbose)
    {
        out << "biome: " << biome << endl
            << "geolayer: " << layer << endl;
    }


    // there is no Maps::WriteGeology or whatever, and I didn't want to mess with the library and add it
    // so I copied the stuff which reads the geology information and modified it to be able to change it
    // 
    // a more elegant solution would probably look like this:
    // 1) modify Maps::ReadGeology to accept and fill one more optional vector 
    //    where the geolayer ids of the 9 biomes are stored
    // 2) call ReadGeology here, modify the data in the vectors without having to do all that map stuff
    // 3) write Maps::WriteGeology, pass the vectors, let it do it's work
    // Step 1) is optional, but it would make implementing 3) easier. 
    // Otherwise that "check which geo_index is used by biome X" loop would need to be done again.

    // no need to touch the same geology more than once
    // though it wouldn't matter much since there is not much data to be processed
    vector<uint16_t> v_geoprocessed;
    v_geoprocessed.clear();

    // iterate over 8 surrounding regions + local region
    for (int i = eNorthWest; i < eBiomeCount; i++)
    {
        if(verbose) 
            out << "---Biome: " << i;
        if(!all_biomes && i!=biome)
        {
            if(verbose) 
                out << "-skipping" << endl;
            continue;
        }
        else
        {
            if(verbose) 
                out << "-checking" << endl;
        }

        // check against worldmap boundaries, fix if needed
        // regionX is in embark squares
        // regionX/16 is in 16x16 embark square regions
        // i provides -1 .. +1 offset from the current region
        int bioRX = world->map.region_x / 16 + ((i % 3) - 1);
        if (bioRX < 0) bioRX = 0;
        if (bioRX >= world->world_data->world_width) bioRX = world->world_data->world_width - 1;
        int bioRY = world->map.region_y / 16 + ((i / 3) - 1);
        if (bioRY < 0) bioRY = 0;
        if (bioRY >= world->world_data->world_height) bioRY = world->world_data->world_height - 1;

        // get index into geoblock vector
        uint16_t geoindex = world->world_data->region_map[bioRX][bioRY].geo_index;

        if(verbose)
            out << "geoindex: " << geoindex << endl;

        bool skip = false;
        for(int g=0; g<v_geoprocessed.size(); g++)
        {
            if(v_geoprocessed.at(g)==geoindex)
            {
                if(verbose)
                    out << "already processed" << endl;
                skip = true;
                break;
            }
        }
        if(skip)
            continue;

        v_geoprocessed.push_back(geoindex);

        /// geology blocks have a vector of layer descriptors
        // get the vector with pointer to layers
        df::world_geo_biome *geo_biome = df::world_geo_biome::find(geoindex);
        if (!geo_biome)
        {
            if(verbose)
                out << "no geology found here." << endl;
            continue;
        }

        vector <df::world_geo_layer*> &geolayers = geo_biome->layers;

        // complain if layer is out of range
        // geology has up to 16 layers currently, but can have less!
        if(layer >= geolayers.size() || layer < 0)
        {
            if(verbose)
                out << "layer out of range!";
            continue;
        }

        // now let's actually write the new mat id to the layer(s)
        if(all_layers)
        {
            for (size_t j = 0; j < geolayers.size(); j++)
            {
                MaterialInfo mat_old;
                mat_old.decode(0, geolayers[j]->mat_index);
                if(conversionAllowed(out, mat_new, mat_old, force))
                {
                    if(verbose)
                        out << "changing geolayer " << j 
                            << " from " << mat_old.getToken() 
                            << " to " << mat_new.getToken() 
                            << endl;
                    geolayers[j]->mat_index = mat_new.index;
                }
            }
        }
        else
        {
            MaterialInfo mat_old;
            mat_old.decode(0, geolayers[layer]->mat_index);
            if(conversionAllowed(out, mat_new, mat_old, force))
            {
                if(verbose)
                    out << "changing geolayer " << layer
                        << " from " << mat_old.getToken()
                        << " to " << mat_new.getToken()
                        << endl;
                geolayers[layer]->mat_index = mat_new.index;
            }
        }
    }

    out.print("Done.\n");
    
    // Give control back to DF.
    return CR_OK;
}
Example #30
0
command_result df_seedwatch(color_ostream &out, vector<string>& parameters)
{
    CoreSuspender suspend;

    map<string, t_materialIndex> materialsReverser;
    for(size_t i = 0; i < world->raws.plants.all.size(); ++i)
    {
        materialsReverser[world->raws.plants.all[i]->id] = i;
    }

    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))
    {
        // just print the help
        printHelp(out);
        return CR_OK;
    }

    string par;
    int limit;
    switch(parameters.size())
    {
    case 0:
        printHelp(out);
        break;
    case 1:
        par = parameters[0];
        if(par == "help") printHelp(out);
        else if(par == "?") printHelp(out);
        else if(par == "start")
        {
            running = true;
            out.print("seedwatch supervision started.\n");
        }
        else if(par == "stop")
        {
            running = false;
            out.print("seedwatch supervision stopped.\n");
        }
        else if(par == "clear")
        {
            Kitchen::clearLimits();
            out.print("seedwatch watchlist cleared\n");
        }
        else if(par == "info")
        {
            out.print("seedwatch Info:\n");
            if(running)
            {
                out.print("seedwatch is supervising.  Use 'seedwatch stop' to stop supervision.\n");
            }
            else
            {
                out.print("seedwatch is not supervising.  Use 'seedwatch start' to start supervision.\n");
            }
            map<t_materialIndex, unsigned int> watchMap;
            Kitchen::fillWatchMap(watchMap);
            if(watchMap.empty())
            {
                out.print("The watch list is empty.\n");
            }
            else
            {
                out.print("The watch list is:\n");
                for(map<t_materialIndex, unsigned int>::const_iterator i = watchMap.begin(); i != watchMap.end(); ++i)
                {
                    out.print("%s : %u\n", world->raws.plants.all[i->first]->id.c_str(), i->second);
                }
            }
        }
        else if(par == "debug")
        {
            map<t_materialIndex, unsigned int> watchMap;
            Kitchen::fillWatchMap(watchMap);
            Kitchen::debug_print(out);
        }
        /*
        else if(par == "dumpmaps")
        {
            out.print("Plants:\n");
            for(auto i = plantMaterialTypes.begin(); i != plantMaterialTypes.end(); i++)
            {
                auto t = materialsModule.df_organic->at(i->first);
                out.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_basic_mat);
            }
            out.print("Seeds:\n");
            for(auto i = seedMaterialTypes.begin(); i != seedMaterialTypes.end(); i++)
            {
                auto t = materialsModule.df_organic->at(i->first);
                out.print("%s : %u %u\n", organics[i->first].id.c_str(), i->second, t->material_seed);
            }
        }
        */
        else
        {
            string token = searchAbbreviations(par);
            if(materialsReverser.count(token) > 0)
            {
                Kitchen::removeLimit(materialsReverser[token]);
                out.print("%s is not being watched\n", token.c_str());
            }
            else
            {
                out.print("%s has not been found as a material.\n", token.c_str());
            }
        }
        break;
    case 2:
        limit = atoi(parameters[1].c_str());
        if(limit < 0) limit = 0;
        if(parameters[0] == "all")
        {
            for(map<string, string>::const_iterator i = abbreviations.begin(); i != abbreviations.end(); ++i)
            {
                if(materialsReverser.count(i->second) > 0) Kitchen::setLimit(materialsReverser[i->second], limit);
            }
        }
        else
        {
            string token = searchAbbreviations(parameters[0]);
            if(materialsReverser.count(token) > 0)
            {
                Kitchen::setLimit(materialsReverser[token], limit);
                out.print("%s is being watched.\n", token.c_str());
            }
            else
            {
                out.print("%s has not been found as a material.\n", token.c_str());
            }
        }
        break;
    default:
        printHelp(out);
        break;
    }

    return CR_OK;
}