Move catsplosion, tweak for build targets under MSVC.
parent
9163dda076
commit
f600928ec1
@ -0,0 +1,131 @@
|
||||
// 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 <iostream>
|
||||
#include <cstdlib>
|
||||
#include <assert.h>
|
||||
#include <climits>
|
||||
#include <stdlib.h> // for rand()
|
||||
#include <algorithm> // for std::transform
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
using namespace std;
|
||||
|
||||
#include "DFHack.h"
|
||||
#include "Core.h"
|
||||
#include "Console.h"
|
||||
#include "Export.h"
|
||||
#include "PluginManager.h"
|
||||
#include "DataDefs.h"
|
||||
#include <df/caste_raw.h>
|
||||
#include <df/creature_raw.h>
|
||||
|
||||
using namespace DFHack;
|
||||
using namespace DFHack::Simple;
|
||||
|
||||
command_result catsplosion (Core * c, std::vector <std::string> & parameters);
|
||||
|
||||
DFhackCExport const char * plugin_name ( void )
|
||||
{
|
||||
return "catsplosion";
|
||||
}
|
||||
|
||||
// Mandatory init function. If you have some global state, create it here.
|
||||
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
|
||||
{
|
||||
// Fill the command list with your commands.
|
||||
commands.clear();
|
||||
commands.push_back(PluginCommand(
|
||||
"catsplosion", "Do nothing, look pretty.",
|
||||
catsplosion, false,
|
||||
" This command does nothing at all. For now.\n"
|
||||
));
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
DFhackCExport command_result plugin_shutdown ( Core * c )
|
||||
{
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
command_result catsplosion (Core * c, std::vector <std::string> & parameters)
|
||||
{
|
||||
list<string> s_creatures;
|
||||
// only cats for now.
|
||||
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(c);
|
||||
|
||||
uint32_t numCreatures;
|
||||
if(!(numCreatures = Units::getNumCreatures()))
|
||||
{
|
||||
cerr << "Can't get any creatures." << endl;
|
||||
return CR_FAILURE;
|
||||
}
|
||||
|
||||
int totalcount=0;
|
||||
int totalchanged=0;
|
||||
string sextype;
|
||||
|
||||
// shows all the creatures and returns.
|
||||
|
||||
int maxlength = 0;
|
||||
map<string, vector <df::unit *> > male_counts;
|
||||
map<string, vector <df::unit *> > female_counts;
|
||||
|
||||
// classify
|
||||
for(uint32_t i =0;i < numCreatures;i++)
|
||||
{
|
||||
df::unit * creature = Units::GetCreature(i);
|
||||
df::creature_raw *raw = df::global::world->raws.creatures.all[creature->race];
|
||||
if(creature->sex == 0) // female
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// print (optional)
|
||||
//if (showcreatures == 1)
|
||||
{
|
||||
c->con.print("Type Male # Female #\n");
|
||||
for(auto it1 = male_counts.begin();it1!=male_counts.end();it1++)
|
||||
{
|
||||
c->con.print("%20s %6d %8d\n", it1->first.c_str(), it1->second.size(), female_counts[it1->first].size());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
// process
|
||||
for (list<string>::iterator it = s_creatures.begin(); it != s_creatures.end(); ++it)
|
||||
{
|
||||
std::string clinput = *it;
|
||||
std::transform(clinput.begin(), clinput.end(), clinput.begin(), ::toupper);
|
||||
vector <t_creature> &females = female_counts[clinput];
|
||||
uint32_t sz_fem = females.size();
|
||||
totalcount += sz_fem;
|
||||
for(uint32_t i = 0; i < sz_fem && totalchanged != maxpreg; i++)
|
||||
{
|
||||
t_creature & female = females[i];
|
||||
uint32_t preg_timer = proc->readDWord(female.origin + creature_pregnancy_offset);
|
||||
if(preg_timer != 0)
|
||||
{
|
||||
proc->writeDWord(female.origin + creature_pregnancy_offset, rand() % 100 + 1);
|
||||
totalchanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
cout << totalchanged << " pregnancies accelerated. Total creatures checked: " << totalcount << "." << endl;
|
||||
return CR_OK;
|
||||
}
|
@ -1,172 +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 <iostream>
|
||||
#include <cstdlib>
|
||||
#include <assert.h>
|
||||
#include <climits>
|
||||
#include <stdlib.h> // for rand()
|
||||
#include <algorithm> // for std::transform
|
||||
#include <vector>
|
||||
#include <list>
|
||||
#include <iterator>
|
||||
using namespace std;
|
||||
|
||||
#include <DFHack.h>
|
||||
#include <argstream.h>
|
||||
|
||||
using namespace DFHack;
|
||||
|
||||
int main ( int argc, char** argv )
|
||||
{
|
||||
DFHack::VersionInfo *mem;
|
||||
DFHack::Process *proc;
|
||||
uint32_t creature_pregnancy_offset;
|
||||
|
||||
//bool femaleonly = 0;
|
||||
bool showcreatures = 0;
|
||||
int maxpreg = 1000; // random start value, since its not required and im not sure how to set it to infinity
|
||||
list<string> s_creatures;
|
||||
|
||||
// parse input, handle this nice and neat before we get to the connecting
|
||||
argstream as(argc,argv);
|
||||
as // >>option('f',"female",femaleonly,"Impregnate females only")
|
||||
>>option('s',"show",showcreatures,"Show creature list (read only)")
|
||||
>>parameter('m',"max",maxpreg,"The maximum limit of pregnancies ", false)
|
||||
>>values<string>(back_inserter(s_creatures), "any number of creatures")
|
||||
>>help();
|
||||
|
||||
// make the creature list unique
|
||||
s_creatures.unique();
|
||||
|
||||
if (!as.isOk())
|
||||
{
|
||||
cout << as.errorLog();
|
||||
return(0);
|
||||
}
|
||||
else if (as.helpRequested())
|
||||
{
|
||||
cout<<as.usage()<<endl;
|
||||
return(1);
|
||||
}
|
||||
else if(showcreatures==1)
|
||||
{
|
||||
}
|
||||
else if (s_creatures.size() == 0 && showcreatures != 1)
|
||||
{
|
||||
cout << as.usage() << endl << "---------------------------------------" << endl;
|
||||
cout << "Creature list empty, assuming CATs" << endl;
|
||||
s_creatures.push_back("CAT");
|
||||
}
|
||||
|
||||
DFHack::ContextManager DFMgr("Memory.xml");
|
||||
DFHack::Context *DF;
|
||||
try
|
||||
{
|
||||
DF = DFMgr.getSingleContext();
|
||||
DF->Attach();
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
#ifndef LINUX_BUILD
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
proc = DF->getProcess();
|
||||
mem = DF->getMemoryInfo();
|
||||
DFHack::Materials *Mats = DF->getMaterials();
|
||||
DFHack::Creatures *Cre = DF->getCreatures();
|
||||
creature_pregnancy_offset = mem->getOffset("creature_pregnancy");
|
||||
|
||||
if(!Mats->ReadCreatureTypesEx())
|
||||
{
|
||||
cerr << "Can't get the creature types." << endl;
|
||||
#ifndef LINUX_BUILD
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t numCreatures;
|
||||
if(!Cre->Start(numCreatures))
|
||||
{
|
||||
cerr << "Can't get creatures" << endl;
|
||||
#ifndef LINUX_BUILD
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
||||
int totalcount=0;
|
||||
int totalchanged=0;
|
||||
string sextype;
|
||||
|
||||
// shows all the creatures and returns.
|
||||
|
||||
int maxlength = 0;
|
||||
map<string, vector <t_creature> > male_counts;
|
||||
map<string, vector <t_creature> > female_counts;
|
||||
|
||||
// classify
|
||||
for(uint32_t i =0;i < numCreatures;i++)
|
||||
{
|
||||
DFHack::t_creature creature;
|
||||
Cre->ReadCreature(i,creature);
|
||||
DFHack::t_creaturetype & crt = Mats->raceEx[creature.race];
|
||||
string castename = crt.castes[creature.sex].rawname;
|
||||
if(castename == "FEMALE")
|
||||
{
|
||||
female_counts[Mats->raceEx[creature.race].rawname].push_back(creature);
|
||||
male_counts[Mats->raceEx[creature.race].rawname].size();
|
||||
}
|
||||
else // male, other, etc.
|
||||
{
|
||||
male_counts[Mats->raceEx[creature.race].rawname].push_back(creature);
|
||||
female_counts[Mats->raceEx[creature.race].rawname].size(); //auto initialize the females as well
|
||||
}
|
||||
}
|
||||
|
||||
// print (optional)
|
||||
if (showcreatures == 1)
|
||||
{
|
||||
cout << "Type\t\tMale #\tFemale #" << endl;
|
||||
for(map<string, vector <t_creature> >::iterator it1 = male_counts.begin();it1!=male_counts.end();it1++)
|
||||
{
|
||||
cout << it1->first << "\t\t" << it1->second.size() << "\t" << female_counts[it1->first].size() << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// process
|
||||
for (list<string>::iterator it = s_creatures.begin(); it != s_creatures.end(); ++it)
|
||||
{
|
||||
std::string clinput = *it;
|
||||
std::transform(clinput.begin(), clinput.end(), clinput.begin(), ::toupper);
|
||||
vector <t_creature> &females = female_counts[clinput];
|
||||
uint32_t sz_fem = females.size();
|
||||
totalcount += sz_fem;
|
||||
for(uint32_t i = 0; i < sz_fem && totalchanged != maxpreg; i++)
|
||||
{
|
||||
t_creature & female = females[i];
|
||||
uint32_t preg_timer = proc->readDWord(female.origin + creature_pregnancy_offset);
|
||||
if(preg_timer != 0)
|
||||
{
|
||||
proc->writeDWord(female.origin + creature_pregnancy_offset, rand() % 100 + 1);
|
||||
totalchanged++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cout << totalchanged << " pregnancies accelerated. Total creatures checked: " << totalcount << "." << endl;
|
||||
Cre->Finish();
|
||||
DF->Detach();
|
||||
#ifndef LINUX_BUILD
|
||||
cout << "Done. Press any key to continue" << endl;
|
||||
cin.ignore();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
@ -1,126 +0,0 @@
|
||||
// Just show some position data
|
||||
|
||||
#include <iostream>
|
||||
#include <climits>
|
||||
#include <vector>
|
||||
#include <ctime>
|
||||
using namespace std;
|
||||
|
||||
#include <DFHack.h>
|
||||
#include <extra/termutil.h>
|
||||
std::ostream &operator<<(std::ostream &stream, DFHack::t_gamemodes funzies)
|
||||
{
|
||||
const char * gm[]=
|
||||
{
|
||||
"Fort",
|
||||
"Adventurer",
|
||||
"Legends",
|
||||
"Menus",
|
||||
"Arena",
|
||||
"Arena - Assumed",
|
||||
"Kittens!",
|
||||
"Worldgen"
|
||||
};
|
||||
const char * cm[]=
|
||||
{
|
||||
"Managing",
|
||||
"Direct Control",
|
||||
"Kittens!",
|
||||
"Menus"
|
||||
};
|
||||
if(funzies.game_mode <= DFHack::GM_MAX && funzies.control_mode <= DFHack::CM_MAX)
|
||||
stream << "Game mode: " << gm[funzies.game_mode] << ", Control mode: " << cm[funzies.control_mode];
|
||||
else
|
||||
stream << "Game mode is too funky: (" << funzies.game_mode << "," << funzies.control_mode << ")";
|
||||
return stream;
|
||||
}
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
bool temporary_terminal = TemporaryTerminal();
|
||||
bool quiet = false;
|
||||
for(int i = 1; i < argc; i++)
|
||||
{
|
||||
string test = argv[i];
|
||||
if(test == "-q")
|
||||
{
|
||||
quiet = true;
|
||||
}
|
||||
}
|
||||
|
||||
DFHack::Gui * Gui = 0;
|
||||
DFHack::Maps * Maps = 0;
|
||||
DFHack::World * World = 0;
|
||||
DFHack::ContextManager DFMgr("Memory.xml");
|
||||
DFHack::Context * DF;
|
||||
bool have_maps = false;
|
||||
try
|
||||
{
|
||||
DF = DFMgr.getSingleContext();
|
||||
DF->Attach();
|
||||
Gui = DF->getGui();
|
||||
Maps = DF->getMaps();
|
||||
World = DF->getWorld();
|
||||
have_maps = Maps->Start();
|
||||
}
|
||||
catch (exception& e)
|
||||
{
|
||||
cerr << e.what() << endl;
|
||||
if(temporary_terminal)
|
||||
cin.ignore();
|
||||
return 1;
|
||||
}
|
||||
DFHack::t_gamemodes gmm;
|
||||
if(World->ReadGameMode(gmm))
|
||||
{
|
||||
cout << gmm << endl;
|
||||
}
|
||||
cout << "Year: " << World->ReadCurrentYear()
|
||||
<< " Month: " << World->ReadCurrentMonth()
|
||||
<< " Day: " << World->ReadCurrentDay()
|
||||
<< " Tick: " << World->ReadCurrentTick() << endl;
|
||||
if (Gui)
|
||||
{
|
||||
int32_t vx,vy,vz;
|
||||
int32_t cx,cy,cz;
|
||||
int32_t wx,wy,wz;
|
||||
int32_t width,height;
|
||||
if(have_maps)
|
||||
{
|
||||
Maps->getPosition(wx,wy,wz);
|
||||
cout << "Map world offset: " << wx << "/" << wy << "/" << wz << " embark squares." << endl;
|
||||
}
|
||||
bool have_cursor = Gui->getCursorCoords(cx,cy,cz);
|
||||
bool have_view = Gui->getViewCoords(vx,vy,vz);
|
||||
if(have_view)
|
||||
{
|
||||
cout << "view coords: " << vx << "/" << vy << "/" << vz << endl;
|
||||
if(have_maps)
|
||||
cout << " world: " << vx+wx*48 << "/" << vy+wy*48 << "/" << vz+wz << endl;
|
||||
}
|
||||
if(have_cursor)
|
||||
{
|
||||
cout << "cursor coords: " << cx << "/" << cy << "/" << cz << endl;
|
||||
if(have_maps)
|
||||
cout << " world: " << cx+wx*48 << "/" << cy+wy*48 << "/" << cz+wz << endl;
|
||||
}
|
||||
if(Gui->getWindowSize(width,height))
|
||||
cout << "window size : " << width << " " << height << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
cerr << "cursor and window parameters are unsupported on your version of DF" << endl;
|
||||
}
|
||||
|
||||
if(!DF->Detach())
|
||||
{
|
||||
cerr << "Can't detach from DF" << endl;
|
||||
}
|
||||
|
||||
if(!quiet && temporary_terminal)
|
||||
{
|
||||
cout << "Done. Press any key to continue" << endl;
|
||||
cin.ignore();
|
||||
}
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue