diff --git a/NEWS.rst b/NEWS.rst index 7fbfdd56a..ae295e4db 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -68,6 +68,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 ----- - `exportlegends`: Handles entities without specific races, and a few other fixes for things new to v0.42 @@ -76,6 +78,7 @@ Fixes Misc Improvements ----------------- - `weather`: now implemented by a script +- `colonies`: now implemented by a script DFHack 0.40.24-r5 diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 33db4d8c3..54b377235 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -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 diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index a321f178a..be795576b 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -107,7 +107,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) diff --git a/plugins/colonies.cpp b/plugins/colonies.cpp deleted file mode 100644 index bea595bf9..000000000 --- a/plugins/colonies.cpp +++ /dev/null @@ -1,153 +0,0 @@ -#include "Core.h" -#include "Console.h" -#include "Export.h" -#include "PluginManager.h" -#include -#include -#include "modules/Vermin.h" -#include "modules/Materials.h" - -using std::vector; -using std::string; -using namespace DFHack; - -command_result colonies (color_ostream &out, vector & parameters); - -DFHACK_PLUGIN("colonies"); -REQUIRE_GLOBAL(world); // used by Materials - -DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &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 & 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; -} diff --git a/scripts/colonies.lua b/scripts/colonies.lua new file mode 100644 index 000000000..2e755ea18 --- /dev/null +++ b/scripts/colonies.lua @@ -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