Merge branch 'dfapi' of github.com:peterix/dfhack into dfapi
commit
96153a7b05
@ -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,165 @@
|
|||||||
|
#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(Core *c, 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)
|
||||||
|
{
|
||||||
|
|
||||||
|
c->con << "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())
|
||||||
|
{
|
||||||
|
c->con << "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(c, 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(Core *c, 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;
|
||||||
|
|
||||||
|
c->con.print("Spawn point %u: %s at %d:%d:%d\n", i,
|
||||||
|
race.c_str(), sp.x, sp.y, sp.z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numColonies == 0)
|
||||||
|
c->con << "No colonies present." << std::endl;
|
||||||
|
}
|
Loading…
Reference in New Issue