Merge remote-tracking branch 'myk002/myk_teleport' into develop

develop
lethosor 2021-06-18 18:21:49 -04:00
commit a300c5592d
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
6 changed files with 56 additions and 35 deletions

@ -1172,13 +1172,18 @@ Units module
Returns true *x,y,z* of the unit, or *nil* if invalid; may be not equal to unit.pos if caged. Returns true *x,y,z* of the unit, or *nil* if invalid; may be not equal to unit.pos if caged.
* ``dfhack.getUnitsInBox(x1,y1,z1,x2,y2,z2[,filter])`` * ``dfhack.units.getUnitsInBox(x1,y1,z1,x2,y2,z2[,filter])``
Returns a table of all units within the specified coordinates. If the ``filter`` Returns a table of all units within the specified coordinates. If the ``filter``
argument is given, only units where ``filter(unit)`` returns true will be included. argument is given, only units where ``filter(unit)`` returns true will be included.
Note that ``pos2xyz()`` cannot currently be used to convert coordinate objects to Note that ``pos2xyz()`` cannot currently be used to convert coordinate objects to
the arguments required by this function. the arguments required by this function.
* ``dfhack.units.teleport(unit, pos)``
Moves the specified unit and any riders to the target coordinates, setting
tile occupancy flags appropriately. Returns true if successful.
* ``dfhack.units.getGeneralRef(unit, type)`` * ``dfhack.units.getGeneralRef(unit, type)``
Searches for a general_ref with the given type. Searches for a general_ref with the given type.

@ -56,6 +56,7 @@ changelog.txt uses a syntax similar to RST, with a few special sequences:
- ``utils.processArgsGetopt()``: now properly handles ``--`` like GNU ``getopt`` as a marker to treat all further parameters as non-options - ``utils.processArgsGetopt()``: now properly handles ``--`` like GNU ``getopt`` as a marker to treat all further parameters as non-options
- ``utils.processArgsGetopt()``: now detects when required arguments to long-form options are missing - ``utils.processArgsGetopt()``: now detects when required arguments to long-form options are missing
- `xlsxreader`: added Lua class wrappers for the xlsxreader plugin API - `xlsxreader`: added Lua class wrappers for the xlsxreader plugin API
- added ``dfhack.units.teleport(unit, pos)``
## Documentation ## Documentation
- Added more client library implementations to the `remote interface docs <remote-client-libs>` - Added more client library implementations to the `remote interface docs <remote-client-libs>`

@ -1572,6 +1572,7 @@ static const luaL_Reg dfhack_job_funcs[] = {
/***** Units module *****/ /***** Units module *****/
static const LuaWrapper::FunctionReg dfhack_units_module[] = { static const LuaWrapper::FunctionReg dfhack_units_module[] = {
WRAPM(Units, teleport),
WRAPM(Units, getGeneralRef), WRAPM(Units, getGeneralRef),
WRAPM(Units, getSpecificRef), WRAPM(Units, getSpecificRef),
WRAPM(Units, getContainer), WRAPM(Units, getContainer),

@ -82,6 +82,9 @@ DFHACK_EXPORT int32_t findIndexById(int32_t id);
/// Returns the true position of the unit (non-trivial in case of caged). /// Returns the true position of the unit (non-trivial in case of caged).
DFHACK_EXPORT df::coord getPosition(df::unit *unit); DFHACK_EXPORT df::coord getPosition(df::unit *unit);
// moves unit and any riders to the target coordinates
DFHACK_EXPORT bool teleport(df::unit *unit, df::coord target_pos);
DFHACK_EXPORT df::general_ref *getGeneralRef(df::unit *unit, df::general_ref_type type); DFHACK_EXPORT df::general_ref *getGeneralRef(df::unit *unit, df::general_ref_type type);
DFHACK_EXPORT df::specific_ref *getSpecificRef(df::unit *unit, df::specific_ref_type type); DFHACK_EXPORT df::specific_ref *getSpecificRef(df::unit *unit, df::specific_ref_type type);

@ -71,6 +71,7 @@ using namespace std;
#include "df/job.h" #include "df/job.h"
#include "df/nemesis_record.h" #include "df/nemesis_record.h"
#include "df/squad.h" #include "df/squad.h"
#include "df/tile_occupancy.h"
#include "df/ui.h" #include "df/ui.h"
#include "df/unit_inventory_item.h" #include "df/unit_inventory_item.h"
#include "df/unit_misc_trait.h" #include "df/unit_misc_trait.h"
@ -144,6 +145,49 @@ df::coord Units::getPosition(df::unit *unit)
return unit->pos; return unit->pos;
} }
bool Units::teleport(df::unit *unit, df::coord target_pos)
{
// make sure source and dest map blocks are valid
auto old_occ = Maps::getTileOccupancy(unit->pos);
auto new_occ = Maps::getTileOccupancy(target_pos);
if (!old_occ || !new_occ)
return false;
// clear appropriate occupancy flags at old tile
if (unit->flags1.bits.on_ground)
// this is potentially wrong, but the game will recompute this as needed
old_occ->bits.unit_grounded = 0;
else
old_occ->bits.unit = 0;
// if there's already somebody standing at the destination, then force the
// unit to lay down
if (new_occ->bits.unit)
unit->flags1.bits.on_ground = 1;
// set appropriate occupancy flags at new tile
if (unit->flags1.bits.on_ground)
new_occ->bits.unit_grounded = 1;
else
new_occ->bits.unit = 1;
// move unit to destination
unit->pos = target_pos;
// move unit's riders (including babies) to destination
if (unit->flags1.bits.ridden)
{
for (size_t j = 0; j < world->units.other[units_other_id::ANY_RIDER].size(); j++)
{
df::unit *rider = world->units.other[units_other_id::ANY_RIDER][j];
if (rider->relationship_ids[df::unit_relationship_type::RiderMount] == unit->id)
rider->pos = unit->pos;
}
}
return true;
}
df::general_ref *Units::getGeneralRef(df::unit *unit, df::general_ref_type type) df::general_ref *Units::getGeneralRef(df::unit *unit, df::general_ref_type type)
{ {
CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(unit);

@ -74,43 +74,10 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out )
break; break;
} }
// make sure source and dest map blocks are valid if (!Units::teleport(unit, unit->path.dest))
auto old_occ = Maps::getTileOccupancy(unit->pos);
auto new_occ = Maps::getTileOccupancy(unit->path.dest);
if (!old_occ || !new_occ)
break; break;
// clear appropriate occupancy flags at old tile
if (unit->flags1.bits.on_ground)
// this is technically wrong, but the game will recompute this as needed
old_occ->bits.unit_grounded = 0;
else
old_occ->bits.unit = 0;
// if there's already somebody standing at the destination, then force the unit to lay down
if (new_occ->bits.unit)
unit->flags1.bits.on_ground = 1;
// set appropriate occupancy flags at new tile
if (unit->flags1.bits.on_ground)
new_occ->bits.unit_grounded = 1;
else
new_occ->bits.unit = 1;
// move unit to destination
unit->pos = unit->path.dest;
unit->path.path.clear(); unit->path.path.clear();
//move unit's riders(including babies) to destination
if (unit->flags1.bits.ridden)
{
for (size_t j = 0; j < world->units.other[units_other_id::ANY_RIDER].size(); j++)
{
df::unit *rider = world->units.other[units_other_id::ANY_RIDER][j];
if (rider->relationship_ids[df::unit_relationship_type::RiderMount] == unit->id)
rider->pos = unit->pos;
}
}
} while (0); } while (0);
if (enable_fastdwarf) if (enable_fastdwarf)