Merge pull request #810 from PeridexisErrant/colonies

Colonies as a script, + place feature by Warmist
develop
expwnent 2016-03-13 08:32:05 -04:00
commit 5bb98295b3
5 changed files with 85 additions and 163 deletions

@ -73,6 +73,8 @@ New Features
- ``tweak hide-priority``: Adds an option to hide designation priority indicators
- ``tweak title-start-rename``: Adds a safe rename option to the title screen "Start Playing" menu
- `colonies`: new ``place`` subcommand and supports any vermin (default honey bees)
Fixes
-----
- Fixed a crash bug caused by the historical figures DFHack uses to store persistent data.
@ -103,6 +105,7 @@ Misc Improvements
- `lua`: Now supports some built-in variables like `gui/gm-editor`, e.g. ``unit``, ``screen``
- `stockflow`: Now offers better control over individual craft jobs
- `weather`: now implemented by a script
- `colonies`: now implemented by a script
DFHack 0.40.24-r5

@ -1667,15 +1667,6 @@ This utility alters all constructions on the map so that they spawn their
building component when they are disassembled, allowing their actual
build items to be safely deleted. This can improve FPS in extreme situations.
colonies
========
Allows listing all the vermin colonies on the map and optionally turning
them into honey bee colonies.
Options:
:bees: turn colonies into honey bee colonies
deramp
======
Removes all ramps designated for removal from the map. This is useful for

@ -85,7 +85,6 @@ if (BUILD_SUPPORTED)
DFHACK_PLUGIN(cleanconst cleanconst.cpp)
DFHACK_PLUGIN(cleaners cleaners.cpp)
DFHACK_PLUGIN(cleanowned cleanowned.cpp)
DFHACK_PLUGIN(colonies colonies.cpp)
DFHACK_PLUGIN(command-prompt command-prompt.cpp)
DFHACK_PLUGIN(confirm confirm.cpp LINK_LIBRARIES lua)
DFHACK_PLUGIN(createitem createitem.cpp)

@ -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