From f908a1d1b661a655a5dd15c8950e7db07d2f4d57 Mon Sep 17 00:00:00 2001 From: lethosor Date: Sat, 11 Jun 2016 21:44:15 -0400 Subject: [PATCH] Replace catsplosion plugin with a script Closes #938, #722 --- NEWS.rst | 1 + docs/Plugins.rst | 7 -- plugins/CMakeLists.txt | 1 - plugins/catsplosion.cpp | 166 ---------------------------------------- scripts/catsplosion.lua | 97 +++++++++++++++++++++++ 5 files changed, 98 insertions(+), 174 deletions(-) delete mode 100644 plugins/catsplosion.cpp create mode 100644 scripts/catsplosion.lua diff --git a/NEWS.rst b/NEWS.rst index 7571ec45a..781c22b7b 100644 --- a/NEWS.rst +++ b/NEWS.rst @@ -51,6 +51,7 @@ Fixes Misc Improvements ----------------- +- `catsplosion`: now a lua script instead of a plugin - `fix/diplomats`: replaces ``fixdiplomats`` - `fix/merchants`: replaces ``fixmerchants`` diff --git a/docs/Plugins.rst b/docs/Plugins.rst index 75d2d988d..ba502c38e 100644 --- a/docs/Plugins.rst +++ b/docs/Plugins.rst @@ -2174,13 +2174,6 @@ Usage: * When viewing unit details, body-swaps into that unit. * In the main adventure mode screen, reverts transient swap. -.. _catsplosion: - -catsplosion -=========== -Makes cats just *multiply*. It is not a good idea to run this more than once or -twice. - .. _createitem: createitem diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index cc0de019f..c24b940b9 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -78,7 +78,6 @@ if (BUILD_SUPPORTED) DFHACK_PLUGIN(burrows burrows.cpp LINK_LIBRARIES lua) DFHACK_PLUGIN(building-hacks building-hacks.cpp LINK_LIBRARIES lua) DFHACK_PLUGIN(buildingplan buildingplan.cpp LINK_LIBRARIES buildingplan-lib) - DFHACK_PLUGIN(catsplosion catsplosion.cpp) DFHACK_PLUGIN(changeitem changeitem.cpp) DFHACK_PLUGIN(changelayer changelayer.cpp) DFHACK_PLUGIN(changevein changevein.cpp) diff --git a/plugins/catsplosion.cpp b/plugins/catsplosion.cpp deleted file mode 100644 index eee39a996..000000000 --- a/plugins/catsplosion.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// Catsplosion -// By Zhentar , Further modified by dark_rabite, peterix, belal -// This work of evil makes animals pregnant -// and due within 2 in-game hours... - -#include -#include -#include -#include -#include // for rand() -#include // for std::transform -#include -#include -#include -using namespace std; - -#include "DFHack.h" -#include "Core.h" -#include "Console.h" -#include "Export.h" -#include "PluginManager.h" -#include "DataDefs.h" -#include -#include -#include - -using namespace DFHack; - -DFHACK_PLUGIN("catsplosion"); -REQUIRE_GLOBAL(world); - -command_result catsplosion (color_ostream &out, std::vector & parameters); - -// Mandatory init function. If you have some global state, create it here. -DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands) -{ - // Fill the command list with your commands. - commands.push_back(PluginCommand( - "catsplosion", "Make cats just /multiply/.", - catsplosion, false, - " Makes cats abnormally abundant, if you provide some base population ;)\n" - )); - return CR_OK; -} - -DFhackCExport command_result plugin_shutdown ( color_ostream &out ) -{ - return CR_OK; -} - -command_result catsplosion (color_ostream &out, std::vector & parameters) -{ - if (!Core::getInstance().isWorldLoaded()) - { - out.printerr("World not loaded.\n"); - return CR_FAILURE; - } - bool list_only = false; - list s_creatures; - if (parameters.size()) - { - for (size_t i = 0; i < parameters.size(); i++) - { - if (parameters[i] == "list") - { - list_only = true; - } - else - { - s_creatures.push_back(parameters[i]); - } - } - } - else - { - s_creatures.push_back("CAT"); - } - // make the creature list unique ... with cats. they are always unique - s_creatures.unique(); - // SUSPEND THE CORE! ::Evil laugh:: - CoreSuspender susp; - - uint32_t numCreatures; - if(!(numCreatures = Units::getNumCreatures())) - { - out.printerr("Can't get any creatures.\n"); - return CR_FAILURE; - } - - int totalcount=0; - int totalchanged=0; - int totalcreated=0; - string sextype; - - int maxlength = 0; - map > male_counts; - map > female_counts; - - // classify - for(uint32_t i =0;i < numCreatures;i++) - { - df::unit * creature = Units::GetCreature(i); - df::creature_raw *raw = world->raws.creatures.all[creature->race]; - if(Units::isFemale(creature)) - { - female_counts[raw->creature_id].push_back(creature); - male_counts[raw->creature_id].size(); - } - else // male, other, etc. - { - male_counts[raw->creature_id].push_back(creature); - female_counts[raw->creature_id].size(); //auto initialize the females as well - } - } - - if (list_only) - { - out.print("Type Male # Female #\n"); - for (auto it1 = male_counts.begin(); it1!=male_counts.end(); it1++) - { - out.print("%22s %6d %8d\n", it1->first.c_str(), it1->second.size(), female_counts[it1->first].size()); - } - return CR_OK; - } - - // process - for (list::iterator it = s_creatures.begin(); it != s_creatures.end(); ++it) - { - std::string clinput = *it; - std::transform(clinput.begin(), clinput.end(), clinput.begin(), ::toupper); - vector &females = female_counts[clinput]; - uint32_t sz_fem = females.size(); - totalcount += sz_fem; - for(uint32_t i = 0; i < sz_fem; i++)// max 1 pregnancy - { - df::unit * female = females[i]; - // accelerate - if(female->relations.pregnancy_timer != 0) - { - female->relations.pregnancy_timer = rand() % 100 + 1; - totalchanged++; - } - else if(!female->relations.pregnancy_genes) - { - df::unit_genes *preg = new df::unit_genes; - preg->appearance = female->appearance.genes.appearance; - preg->colors = female->appearance.genes.colors; - female->relations.pregnancy_genes = preg; - female->relations.pregnancy_timer = rand() % 100 + 1; - female->relations.pregnancy_caste = 1; - totalcreated ++; - } - } - } - if(totalchanged) - out.print("%d pregnancies accelerated.\n", totalchanged); - if(totalcreated) - out.print("%d pregnancies created.\n", totalcreated); - if (!totalcount) - { - out.printerr("No creatures matched.\n"); - return CR_FAILURE; - } - out.print("Total creatures checked: %d\n", totalcount); - return CR_OK; -} diff --git a/scripts/catsplosion.lua b/scripts/catsplosion.lua new file mode 100644 index 000000000..bd3728b9c --- /dev/null +++ b/scripts/catsplosion.lua @@ -0,0 +1,97 @@ +-- Make cats just /multiply/. +--[[=begin + +catsplosion +=========== +Makes cats (and other animals) just *multiply*. It is not a good idea to run this +more than once or twice. + +Usage: + +:catsplosion: Make all cats pregnant +:catsplosion list: List IDs of all animals on the map +:catsplosion ID ...: Make animals with given ID(s) pregnant + +Animals will give birth within two in-game hours (100 ticks or fewer). + +=end]] + +world = df.global.world + +if not dfhack.isWorldLoaded() then + qerror('World not loaded.') +end + +args = {...} +list_only = false +creatures = {} + +if #args > 0 then + for _, arg in pairs(args) do + if arg == 'list' then + list_only = true + else + creatures[arg:upper()] = true + end + end +else + creatures.CAT = true +end + +total = 0 +total_changed = 0 +total_created = 0 + +males = {} +females = {} + +for _, unit in pairs(world.units.all) do + local id = world.raws.creatures.all[unit.race].creature_id + males[id] = males[id] or {} + females[id] = females[id] or {} + table.insert((dfhack.units.isFemale(unit) and females or males)[id], unit) +end + +if list_only then + print("Type Male # Female #") + -- sort IDs alphabetically + local ids = {} + for id in pairs(males) do + table.insert(ids, id) + end + table.sort(ids) + for _, id in pairs(ids) do + print(("%22s %6d %8d"):format(id, #males[id], #females[id])) + end + return +end + +for id in pairs(creatures) do + local females = females[id] or {} + total = total + #females + for _, female in pairs(females) do + if female.relations.pregnancy_timer ~= 0 then + female.relations.pregnancy_timer = math.random(1, 100) + total_changed = total_changed + 1 + elseif not female.relations.pregnancy_genes then + local preg = df.unit_genes:new() + preg.appearance:assign(female.appearance.genes.appearance) + preg.colors:assign(female.appearance.genes.colors) + female.relations.pregnancy_genes = preg + female.relations.pregnancy_timer = math.random(1, 100) + female.relations.pregnancy_caste = 1 + total_created = total_created + 1 + end + end +end + +if total_changed ~= 0 then + print(("%d pregnancies accelerated."):format(total_changed)) +end +if total_created ~= 0 then + print(("%d pregnancies created."):format(total_created)) +end +if total == 0 then + qerror("No creatures matched.") +end +print(("Total creatures checked: %d"):format(total))