commit
a40153a8e1
@ -0,0 +1,86 @@
|
||||
#pragma once
|
||||
#ifndef CL_MOD_VERMIN
|
||||
#define CL_MOD_VERMIN
|
||||
/**
|
||||
* \defgroup grp_vermin Wild vermin (ants, bees, etc)
|
||||
* @ingroup grp_vermin
|
||||
*/
|
||||
#include "dfhack/Export.h"
|
||||
#include "dfhack/Module.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace DFHack
|
||||
{
|
||||
#endif
|
||||
/**
|
||||
* Structure for holding a read DF vermin spawn point object
|
||||
* \ingroup grp_vermin
|
||||
*/
|
||||
struct t_spawnPoint
|
||||
{
|
||||
uint32_t origin;
|
||||
uint16_t race;
|
||||
uint16_t type;
|
||||
uint16_t x;
|
||||
uint16_t y;
|
||||
uint16_t z;
|
||||
bool in_use;
|
||||
uint8_t unknown;
|
||||
uint32_t countdown;
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
class DFContextShared;
|
||||
class SpawnPoints;
|
||||
|
||||
/**
|
||||
* The Vermin module - allows reading DF vermin
|
||||
* \ingroup grp_modules
|
||||
* \ingroup grp_vermin
|
||||
*/
|
||||
class DFHACK_EXPORT Vermin : public Module
|
||||
{
|
||||
public:
|
||||
Vermin();
|
||||
~Vermin();
|
||||
|
||||
bool Finish();
|
||||
|
||||
// NOTE: caller must call delete on result when done.
|
||||
SpawnPoints* getSpawnPoints();
|
||||
|
||||
private:
|
||||
struct Private;
|
||||
Private *d;
|
||||
|
||||
friend class SpawnPoints;
|
||||
};
|
||||
|
||||
class DFHACK_EXPORT SpawnPoints
|
||||
{
|
||||
public:
|
||||
static const uint16_t TYPE_WILD_COLONY = 0xFFFF;
|
||||
|
||||
protected:
|
||||
SpawnPoints(Vermin * v);
|
||||
|
||||
public:
|
||||
~SpawnPoints();
|
||||
|
||||
size_t size();
|
||||
bool Read (const uint32_t index, t_spawnPoint & point);
|
||||
bool Write (const uint32_t index, t_spawnPoint & point);
|
||||
bool isValid();
|
||||
|
||||
static bool isWildColony(t_spawnPoint & point);
|
||||
|
||||
private:
|
||||
Vermin* v;
|
||||
std::vector <void*> * p_sp;
|
||||
|
||||
friend class Vermin;
|
||||
};
|
||||
}
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
@ -0,0 +1,191 @@
|
||||
/*
|
||||
www.sourceforge.net/projects/dfhack
|
||||
Copyright (c) 2009 Petr Mrázek (peterix), Kenneth Ferland (Impaler[WrG]), dorf
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any
|
||||
damages arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any
|
||||
purpose, including commercial applications, and to alter it and
|
||||
redistribute it freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must
|
||||
not claim that you wrote the original software. If you use this
|
||||
software in a product, an acknowledgment in the product documentation
|
||||
would be appreciated but is not required.
|
||||
|
||||
2. Altered source versions must be plainly marked as such, and
|
||||
must not be misrepresented as being the original software.
|
||||
|
||||
3. This notice may not be removed or altered from any source
|
||||
distribution.
|
||||
*/
|
||||
|
||||
#include "Internal.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
using namespace std;
|
||||
|
||||
#include "dfhack/VersionInfo.h"
|
||||
#include "dfhack/Types.h"
|
||||
#include "dfhack/Error.h"
|
||||
#include "dfhack/Process.h"
|
||||
#include "dfhack/modules/Vermin.h"
|
||||
#include "ModuleFactory.h"
|
||||
#include "dfhack/Core.h"
|
||||
using namespace DFHack;
|
||||
|
||||
struct Vermin::Private
|
||||
{
|
||||
uint32_t spawn_points_vector;
|
||||
uint32_t race_offset;
|
||||
uint32_t type_offset;
|
||||
uint32_t position_offset;
|
||||
uint32_t in_use_offset;
|
||||
uint32_t unknown_offset;
|
||||
uint32_t countdown_offset;
|
||||
Process * owner;
|
||||
bool Inited;
|
||||
bool Started;
|
||||
};
|
||||
|
||||
Module* DFHack::createVermin()
|
||||
{
|
||||
return new Vermin();
|
||||
}
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
Vermin::Vermin()
|
||||
{
|
||||
Core & c = Core::getInstance();
|
||||
|
||||
d = new Private;
|
||||
d->owner = c.p;
|
||||
d->Inited = d->Started = false;
|
||||
VersionInfo * mem = c.vinfo;
|
||||
OffsetGroup * OG_vermin = mem->getGroup("Vermin");
|
||||
OffsetGroup * OG_spawn = OG_vermin->getGroup("Spawn Points");
|
||||
d->Inited = true;
|
||||
try
|
||||
{
|
||||
d->spawn_points_vector = OG_spawn->getAddress("vector");
|
||||
|
||||
d->race_offset = OG_spawn->getOffset("race");
|
||||
d->type_offset = OG_spawn->getOffset("type");
|
||||
d->position_offset = OG_spawn->getOffset("position");
|
||||
d->in_use_offset = OG_spawn->getOffset("in_use");
|
||||
d->unknown_offset = OG_spawn->getOffset("unknown");
|
||||
d->countdown_offset = OG_spawn->getOffset("countdown");
|
||||
}
|
||||
catch(DFHack::Error::AllMemdef &e)
|
||||
{
|
||||
cerr << "Vermin not available... " << e.what() << endl;
|
||||
d->Inited = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Vermin::Finish()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
Vermin::~Vermin()
|
||||
{
|
||||
delete d;
|
||||
}
|
||||
|
||||
// NOTE: caller must call delete on result when done.
|
||||
SpawnPoints* Vermin::getSpawnPoints()
|
||||
{
|
||||
if (!d->Inited)
|
||||
{
|
||||
cerr << "Couldn't get spawn points: Vermin module not inited" << endl;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new SpawnPoints(this);
|
||||
}
|
||||
|
||||
SpawnPoints::SpawnPoints(Vermin* v_)
|
||||
{
|
||||
v = v_;
|
||||
p_sp = NULL;
|
||||
|
||||
if (!v->d->Inited)
|
||||
{
|
||||
cerr << "Couldn't get spawn points: Vermin module not inited" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
//p_sp = new DfVector <uint32_t> (v->d->spawn_points_vector);
|
||||
//p_sp = new vector <void*> (v->d->spawn_points_vector);
|
||||
p_sp = (vector <void*>*) (v->d->spawn_points_vector);
|
||||
}
|
||||
|
||||
SpawnPoints::~SpawnPoints()
|
||||
{
|
||||
// Do NOT delete p_sp; it's a pointer to memory the game owns.
|
||||
}
|
||||
|
||||
size_t SpawnPoints::size()
|
||||
{
|
||||
if (!isValid())
|
||||
return 0;
|
||||
|
||||
return p_sp->size();
|
||||
}
|
||||
|
||||
bool SpawnPoints::Read (const uint32_t index, t_spawnPoint & sp)
|
||||
{
|
||||
if(!isValid())
|
||||
return false;
|
||||
|
||||
// read pointer from vector at position
|
||||
uint32_t temp = (uint32_t) p_sp->at (index);
|
||||
|
||||
sp.origin = temp;
|
||||
sp.race = v->d->owner->readWord(temp + v->d->race_offset);
|
||||
sp.type = v->d->owner->readWord(temp + v->d->type_offset);
|
||||
sp.in_use = v->d->owner->readByte(temp + v->d->in_use_offset);
|
||||
sp.unknown = v->d->owner->readByte(temp + v->d->unknown_offset);
|
||||
sp.countdown = v->d->owner->readDWord(temp + v->d->countdown_offset);
|
||||
|
||||
// Three consecutive 16 bit numbers for x/y/z
|
||||
v->d->owner->read(temp + v->d->position_offset, 6, (uint8_t*) &sp.x);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpawnPoints::Write (const uint32_t index, t_spawnPoint & sp)
|
||||
{
|
||||
if(!isValid())
|
||||
return false;
|
||||
|
||||
// read pointer from vector at position
|
||||
uint32_t temp = (uint32_t) p_sp->at (index);
|
||||
|
||||
v->d->owner->writeWord(temp + v->d->race_offset, sp.race);
|
||||
v->d->owner->writeWord(temp + v->d->type_offset, sp.type);
|
||||
v->d->owner->writeByte(temp + v->d->in_use_offset, sp.in_use);
|
||||
v->d->owner->writeByte(temp + v->d->unknown_offset, sp.unknown);
|
||||
v->d->owner->writeDWord(temp + v->d->countdown_offset, sp.countdown);
|
||||
|
||||
// Three consecutive 16 bit numbers for x/y/z
|
||||
v->d->owner->write(temp + v->d->position_offset, 6, (uint8_t*) &sp.x);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SpawnPoints::isWildColony(t_spawnPoint & point)
|
||||
{
|
||||
return (point.type == TYPE_WILD_COLONY);
|
||||
}
|
||||
|
||||
bool SpawnPoints::isValid()
|
||||
{
|
||||
return (v != NULL && v->d->Inited && p_sp != NULL);
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
#include <dfhack/Core.h>
|
||||
#include <dfhack/Console.h>
|
||||
#include <dfhack/Export.h>
|
||||
#include <dfhack/PluginManager.h>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <dfhack/modules/Vermin.h>
|
||||
|
||||
using std::vector;
|
||||
using std::string;
|
||||
using namespace DFHack;
|
||||
#include <DFHack.h>
|
||||
|
||||
DFhackCExport command_result colonies (Core * c, vector <string> & parameters);
|
||||
|
||||
DFhackCExport const char * plugin_name ( void )
|
||||
{
|
||||
return "colonies";
|
||||
}
|
||||
|
||||
DFhackCExport command_result plugin_init ( Core * c, std::vector <PluginCommand> &commands)
|
||||
{
|
||||
commands.clear();
|
||||
commands.push_back(PluginCommand("colonies",
|
||||
"List or change wild colonies (ants hills and such)\
|
||||
\n Options: 'kill' = destroy all colonies\
|
||||
\n 'bees' = change all colonies to honey bees",
|
||||
colonies));
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
DFhackCExport command_result plugin_shutdown ( Core * c )
|
||||
{
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
void destroyColonies(DFHack::SpawnPoints *points);
|
||||
void convertColonies(DFHack::SpawnPoints *points, DFHack::Materials *Materials);
|
||||
void showColonies(DFHack::SpawnPoints *points, DFHack::Materials *Materials);
|
||||
|
||||
DFhackCExport command_result colonies (Core * c, vector <string> & parameters)
|
||||
{
|
||||
bool destroy = false;
|
||||
bool convert = false;
|
||||
|
||||
for(int i = 0; i < parameters.size();i++)
|
||||
{
|
||||
if(parameters[i] == "kill")
|
||||
destroy = true;
|
||||
else if(parameters[i] == "bees")
|
||||
convert = true;
|
||||
}
|
||||
|
||||
if (destroy && convert)
|
||||
{
|
||||
|
||||
dfout << "Kill or make bees? DECIDE!" << std::endl;
|
||||
return CR_FAILURE;
|
||||
}
|
||||
|
||||
c->Suspend();
|
||||
|
||||
Vermin * vermin = c->getVermin();
|
||||
Materials * materials = c->getMaterials();
|
||||
|
||||
SpawnPoints *points = vermin->getSpawnPoints();
|
||||
|
||||
if(!points->isValid())
|
||||
{
|
||||
std::cerr << "vermin not supported for this DF version" << std::endl;
|
||||
return CR_FAILURE;
|
||||
}
|
||||
|
||||
materials->ReadCreatureTypesEx();
|
||||
|
||||
if (destroy)
|
||||
destroyColonies(points);
|
||||
else if (convert)
|
||||
convertColonies(points, materials);
|
||||
else
|
||||
showColonies(points, materials);
|
||||
|
||||
delete points;
|
||||
|
||||
vermin->Finish();
|
||||
materials->Finish();
|
||||
|
||||
c->Resume();
|
||||
return CR_OK;
|
||||
}
|
||||
|
||||
void destroyColonies(DFHack::SpawnPoints *points)
|
||||
{
|
||||
uint32_t numSpawnPoints = points->size();
|
||||
for (uint32_t i = 0; i < numSpawnPoints; i++)
|
||||
{
|
||||
DFHack::t_spawnPoint sp;
|
||||
points->Read(i, sp);
|
||||
|
||||
if (sp.in_use && DFHack::SpawnPoints::isWildColony(sp))
|
||||
{
|
||||
sp.in_use = false;
|
||||
points->Write(i, sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Convert all colonies to honey bees.
|
||||
void convertColonies(DFHack::SpawnPoints *points, DFHack::Materials *Materials)
|
||||
{
|
||||
int bee_idx = -1;
|
||||
for (size_t i = 0; i < Materials->raceEx.size(); i++)
|
||||
if (strcmp(Materials->raceEx[i].rawname, "HONEY_BEE") == 0)
|
||||
{
|
||||
bee_idx = i;
|
||||
break;
|
||||
}
|
||||
|
||||
if (bee_idx == -1)
|
||||
{
|
||||
std::cerr << "Honey bees not present in game." << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t numSpawnPoints = points->size();
|
||||
for (uint32_t i = 0; i < numSpawnPoints; i++)
|
||||
{
|
||||
DFHack::t_spawnPoint sp;
|
||||
points->Read(i, sp);
|
||||
|
||||
if (sp.in_use && DFHack::SpawnPoints::isWildColony(sp))
|
||||
{
|
||||
sp.race = bee_idx;
|
||||
points->Write(i, sp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void showColonies(DFHack::SpawnPoints *points, DFHack::Materials *Materials)
|
||||
{
|
||||
uint32_t numSpawnPoints = points->size();
|
||||
int numColonies = 0;
|
||||
for (uint32_t i = 0; i < numSpawnPoints; i++)
|
||||
{
|
||||
DFHack::t_spawnPoint sp;
|
||||
|
||||
points->Read(i, sp);
|
||||
|
||||
if (sp.in_use && DFHack::SpawnPoints::isWildColony(sp))
|
||||
{
|
||||
numColonies++;
|
||||
string race="(no race)";
|
||||
if (Materials->raceEx[sp.race].rawname[0])
|
||||
race = Materials->raceEx[sp.race].rawname;
|
||||
|
||||
fprintf(dfout_C, "Spawn point %u: %s at %d:%d:%d\n",
|
||||
i, race.c_str(), sp.x, sp.y, sp.z);
|
||||
}
|
||||
}
|
||||
|
||||
if (numColonies == 0)
|
||||
dfout << "No colonies present." << std::endl;
|
||||
}
|
Loading…
Reference in New Issue