Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,11 @@ Template for new versions:
## New Features

## Fixes
- `spectate`: don't show a hover tooltip for hidden units (e.g. invisible snatchers)
- `stockpiles`: fix one-off error in item type when importing furniture stockpile settings
- `dig-now`: fix cases where boulders/rough gems of incorrect material were being generated when digging through walls
- `dig-now`: properly generate ice boulders when digging through ice walls
- `gui/teleport`: now properly handles teleporting units that are currently falling or being flung

## Misc Improvements
- `spectate`: show dwarves' activities (like prayer)
Expand All @@ -67,6 +69,7 @@ Template for new versions:

## API
- ``Military`` module: added ``addToSquad`` function
- ``Units::teleport``: projectile information is now cleared for teleported units

## Lua
- ``dfhack.military.addToSquad``: expose Military API function
Expand Down
16 changes: 16 additions & 0 deletions library/include/BitArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,22 @@ namespace DFHack
return cur->item;
}

I * operator->()
{
CHECK_NULL_POINTER(root);
CHECK_NULL_POINTER(cur);

return cur->item;
}

I * operator->() const
{
CHECK_NULL_POINTER(root);
CHECK_NULL_POINTER(cur);

return cur->item;
}

operator const_iterator() const
{
return const_iterator(*this);
Expand Down
53 changes: 36 additions & 17 deletions library/include/MiscUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -309,24 +309,43 @@ Link *linked_list_insert_after(Link *pos, Link *link)
}

/**
* Returns true if the item with id idToRemove was found, deleted, and removed
* from the list. Otherwise returns false.
* Returns true if an item that matches the given function was found, deleted,
* and removed from the list. Otherwise returns false. Only removes the first
* match.
*
* Example usage:
*
* linked_list_remove(&world->projectiles.all, [&](df::projectile *proj) {
* if (proj->getType() != df::enums::projectile_type::Unit)
* return false;
* if (auto unit_proj = virtual_cast<df::proj_unitst>(proj))
* return unit_proj->unit == unit;
* return false;
* });
*/
template<typename Link>
bool linked_list_remove(Link *head, int32_t idToRemove)
{
for (Link *link = head; link; link = link->next)
{
if (!link->item || link->item->id != idToRemove)
continue;

link->prev->next = link->next;
if (link->next)
link->next->prev = link->prev;
delete(link);
return true;
}
return false;
template <typename L, typename V = L::iterator::value_type, std::invocable<V> F>
bool linked_list_remove(L *list, F matches) {
auto matches_wrapper = [&](L::iterator::value_type item) {
return item && matches(item);
};
typename L::const_iterator it = std::find_if(list->cbegin(), list->cend(), matches_wrapper);
if (it == list->cend())
return false;
auto item = *it;
list->erase(it);
delete item;
return true;
}

/**
* Returns true if the item with id idToRemove was found, deleted, and
* removed from the list. Otherwise returns false.
*/
template<typename L>
bool linked_list_remove(L *list, int32_t idToRemove) {
return linked_list_remove(list, [&](L::iterator::value_type item) {
return item->id == idToRemove;
});
}

template<typename T>
Expand Down
13 changes: 13 additions & 0 deletions library/modules/Units.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ distribution.
#include "df/nemesis_record.h"
#include "df/personality_goalst.h"
#include "df/plotinfost.h"
#include "df/proj_unitst.h"
#include "df/reputation_profilest.h"
#include "df/syndrome.h"
#include "df/tile_occupancy.h"
Expand Down Expand Up @@ -773,6 +774,18 @@ bool Units::teleport(df::unit *unit, df::coord target_pos)
else
old_occ->bits.unit = false;

// Clear unit projectile info
if (unit->flags1.bits.projectile) {
unit->flags1.bits.projectile = false;
linked_list_remove(&world->projectiles.all, [&](df::projectile *proj) {
if (proj->getType() != df::enums::projectile_type::Unit)
return false;
if (auto unit_proj = virtual_cast<df::proj_unitst>(proj))
return unit_proj->unit == unit;
return false;
});
}

// 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 = true;
Expand Down
6 changes: 5 additions & 1 deletion plugins/lua/spectate.lua
Original file line number Diff line number Diff line change
Expand Up @@ -345,11 +345,15 @@ local function GetUnitInfoText(unit, settings_group_name)
return txt
end

local function unit_filter(unit)
return not dfhack.units.isHidden(unit)
end

local function GetHoverText(pos)
if not pos then return end

local txt = {}
local units = dfhack.units.getUnitsInBox(pos, pos) or {} -- todo: maybe (optionally) use filter parameter here?
local units = dfhack.units.getUnitsInBox(pos, pos, unit_filter) or {}

for _,unit in ipairs(units) do
local info = GetUnitInfoText(unit, 'hover')
Expand Down
Loading