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