Merge pull request #810 from PeridexisErrant/colonies
Colonies as a script, + place feature by Warmistdevelop
						commit
						5bb98295b3
					
				@ -1,153 +0,0 @@
 | 
			
		||||
#include "Core.h"
 | 
			
		||||
#include "Console.h"
 | 
			
		||||
#include "Export.h"
 | 
			
		||||
#include "PluginManager.h"
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <string>
 | 
			
		||||
#include "modules/Vermin.h"
 | 
			
		||||
#include "modules/Materials.h"
 | 
			
		||||
 | 
			
		||||
using std::vector;
 | 
			
		||||
using std::string;
 | 
			
		||||
using namespace DFHack;
 | 
			
		||||
 | 
			
		||||
command_result colonies (color_ostream &out, vector <string> & parameters);
 | 
			
		||||
 | 
			
		||||
DFHACK_PLUGIN("colonies");
 | 
			
		||||
REQUIRE_GLOBAL(world);  // used by Materials
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_init ( color_ostream &out, std::vector <PluginCommand> &commands)
 | 
			
		||||
{
 | 
			
		||||
    commands.push_back(PluginCommand(
 | 
			
		||||
        "colonies", "List or change wild colonies (ants hills and such)",
 | 
			
		||||
        colonies, false,
 | 
			
		||||
        "  Without any options, this command lists all the vermin colonies present.\n"
 | 
			
		||||
        "Options:\n"
 | 
			
		||||
        //"  kill   - destroy colonies\n" // unlisted because it's likely broken anyway
 | 
			
		||||
        "  bees   - turn colonies into honey bee hives\n"
 | 
			
		||||
    ));
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DFhackCExport command_result plugin_shutdown ( color_ostream &out )
 | 
			
		||||
{
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void destroyColonies();
 | 
			
		||||
void convertColonies(Materials *Materials);
 | 
			
		||||
void showColonies(color_ostream &out, Materials *Materials);
 | 
			
		||||
 | 
			
		||||
command_result colonies (color_ostream &out, vector <string> & parameters)
 | 
			
		||||
{
 | 
			
		||||
    bool destroy = false;
 | 
			
		||||
    bool convert = false;
 | 
			
		||||
 | 
			
		||||
    for(size_t i = 0; i < parameters.size();i++)
 | 
			
		||||
    {
 | 
			
		||||
        if(parameters[i] == "kill")
 | 
			
		||||
            destroy = true;
 | 
			
		||||
        else if(parameters[i] == "bees")
 | 
			
		||||
            convert = true;
 | 
			
		||||
        else
 | 
			
		||||
            return CR_WRONG_USAGE;
 | 
			
		||||
    }
 | 
			
		||||
    if (destroy && convert)
 | 
			
		||||
    {
 | 
			
		||||
        out.printerr("Kill or make bees? DECIDE!\n");
 | 
			
		||||
        return CR_FAILURE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    CoreSuspender suspend;
 | 
			
		||||
 | 
			
		||||
    Materials * materials = Core::getInstance().getMaterials();
 | 
			
		||||
 | 
			
		||||
    materials->ReadCreatureTypesEx();
 | 
			
		||||
 | 
			
		||||
    if (destroy)
 | 
			
		||||
        destroyColonies();
 | 
			
		||||
    else if (convert)
 | 
			
		||||
        convertColonies(materials);
 | 
			
		||||
    else
 | 
			
		||||
        showColonies(out, materials);
 | 
			
		||||
 | 
			
		||||
    materials->Finish();
 | 
			
		||||
 | 
			
		||||
    return CR_OK;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
//FIXME: this is probably bullshit
 | 
			
		||||
void destroyColonies()
 | 
			
		||||
{
 | 
			
		||||
    uint32_t numSpawnPoints = Vermin::getNumVermin();
 | 
			
		||||
    for (uint32_t i = 0; i < numSpawnPoints; i++)
 | 
			
		||||
    {
 | 
			
		||||
        Vermin::t_vermin sp;
 | 
			
		||||
        Vermin::Read(i, sp);
 | 
			
		||||
 | 
			
		||||
        if (sp.visible && sp.is_colony)
 | 
			
		||||
        {
 | 
			
		||||
            sp.visible = false;
 | 
			
		||||
            Vermin::Write(i, sp);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Convert all colonies to honey bees.
 | 
			
		||||
void convertColonies(Materials *Materials)
 | 
			
		||||
{
 | 
			
		||||
    int bee_idx = -1;
 | 
			
		||||
    for (size_t i = 0; i < Materials->raceEx.size(); i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (Materials->raceEx[i].id == "HONEY_BEE")
 | 
			
		||||
        {
 | 
			
		||||
            bee_idx = i;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (bee_idx == -1)
 | 
			
		||||
    {
 | 
			
		||||
        std::cerr << "Honey bees not present in game." << std::endl;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t numSpawnPoints = Vermin::getNumVermin();
 | 
			
		||||
    for (uint32_t i = 0; i < numSpawnPoints; i++)
 | 
			
		||||
    {
 | 
			
		||||
        Vermin::t_vermin sp;
 | 
			
		||||
        Vermin::Read(i, sp);
 | 
			
		||||
 | 
			
		||||
        if (sp.visible && sp.is_colony)
 | 
			
		||||
        {
 | 
			
		||||
            sp.race = bee_idx;
 | 
			
		||||
            Vermin::Write(i, sp);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void showColonies(color_ostream &out, Materials *Materials)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t numSpawnPoints = Vermin::getNumVermin();
 | 
			
		||||
    int      numColonies    = 0;
 | 
			
		||||
    for (uint32_t i = 0; i < numSpawnPoints; i++)
 | 
			
		||||
    {
 | 
			
		||||
        Vermin::t_vermin sp;
 | 
			
		||||
 | 
			
		||||
        Vermin::Read(i, sp);
 | 
			
		||||
 | 
			
		||||
        if (sp.visible && sp.is_colony)
 | 
			
		||||
        {
 | 
			
		||||
            numColonies++;
 | 
			
		||||
            string race="(no race)";
 | 
			
		||||
            if(sp.race != -1)
 | 
			
		||||
                race = Materials->raceEx[sp.race].id;
 | 
			
		||||
 | 
			
		||||
            out.print("Colony %u: %s at %d:%d:%d\n", i,
 | 
			
		||||
                      race.c_str(), sp.x, sp.y, sp.z);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (numColonies == 0)
 | 
			
		||||
        out << "No colonies present." << std::endl;
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,82 @@
 | 
			
		||||
-- List, create, or change wild colonies (eg honey bees)
 | 
			
		||||
-- By PeridexisErrant and Warmist
 | 
			
		||||
 | 
			
		||||
local help = [[=begin
 | 
			
		||||
 | 
			
		||||
colonies
 | 
			
		||||
========
 | 
			
		||||
List vermin colonies, place honey bees, or convert all vermin
 | 
			
		||||
to honey bees.  Usage:
 | 
			
		||||
 | 
			
		||||
:colonies:          List all vermin colonies on the map.
 | 
			
		||||
:colonies place:    Place a honey bee colony under the cursor.
 | 
			
		||||
:colonies convert:  Convert all existing colonies to honey bees.
 | 
			
		||||
 | 
			
		||||
The ``place`` and ``convert`` subcommands by default create or
 | 
			
		||||
convert to honey bees, as this is the most commonly useful.
 | 
			
		||||
However both accept an optional flag to use a different vermin
 | 
			
		||||
type, for example ``colonies place ANT`` creates an ant colony
 | 
			
		||||
and ``colonies convert TERMITE`` ends your beekeeping industry.
 | 
			
		||||
 | 
			
		||||
=end]]
 | 
			
		||||
 | 
			
		||||
function findVermin(target_verm)
 | 
			
		||||
    for k,v in pairs(df.global.world.raws.creatures.all) do
 | 
			
		||||
        if v.creature_id == target_verm then
 | 
			
		||||
            return k
 | 
			
		||||
        end
 | 
			
		||||
    end
 | 
			
		||||
    qerror("No vermin found with name: "..target_verm)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function list_colonies()
 | 
			
		||||
    for idx, col in pairs(df.global.world.vermin.colonies) do
 | 
			
		||||
        race = df.global.world.raws.creatures.all[col.race].creature_id
 | 
			
		||||
        print(race..'    at  '..col.pos.x..', '..col.pos.y..', '..col.pos.z)
 | 
			
		||||
    end
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function convert_vermin_to(target_verm)
 | 
			
		||||
    local vermin_id = findVermin(target_verm)
 | 
			
		||||
    local changed = 0
 | 
			
		||||
    for _, verm in pairs(df.global.world.vermin.colonies) do
 | 
			
		||||
        verm.race = vermin_id
 | 
			
		||||
        verm.caste = -1 -- check for queen bee?
 | 
			
		||||
        verm.amount = 18826
 | 
			
		||||
        verm.visible = true
 | 
			
		||||
        changed = changed + 1
 | 
			
		||||
    end
 | 
			
		||||
    print('Converted '..changed..' colonies to '..target_verm)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
function place_vermin(target_verm)
 | 
			
		||||
    local pos = copyall(df.global.cursor)
 | 
			
		||||
    if pos.x == -30000 then
 | 
			
		||||
        qerror("Cursor must be pointing somewhere")
 | 
			
		||||
    end
 | 
			
		||||
    local verm = df.vermin:new()
 | 
			
		||||
    verm.race = findVermin(target_verm)
 | 
			
		||||
    verm.flags.is_colony = true
 | 
			
		||||
    verm.caste = -1 -- check for queen bee?
 | 
			
		||||
    verm.amount = 18826
 | 
			
		||||
    verm.visible = true
 | 
			
		||||
    verm.pos:assign(pos)
 | 
			
		||||
    df.global.world.vermin.colonies:insert("#", verm)
 | 
			
		||||
    df.global.world.vermin.all:insert("#", verm)
 | 
			
		||||
end
 | 
			
		||||
 | 
			
		||||
local args = {...}
 | 
			
		||||
local target_verm = args[2] or "HONEY_BEE"
 | 
			
		||||
 | 
			
		||||
if args[1] == 'help' or args[1] == '?' then
 | 
			
		||||
    print(help)
 | 
			
		||||
elseif args[1] == 'convert' then
 | 
			
		||||
    convert_vermin_to(target_verm)
 | 
			
		||||
elseif args[1] == 'place' then
 | 
			
		||||
    place_vermin(target_verm)
 | 
			
		||||
else
 | 
			
		||||
    if #df.global.world.vermin.colonies < 1 then
 | 
			
		||||
        dfhack.printerr('There are no colonies on the map.')
 | 
			
		||||
    end
 | 
			
		||||
    list_colonies()
 | 
			
		||||
end
 | 
			
		||||
		Loading…
	
		Reference in New Issue