From 7c71aeab5f44c7fce106a0efc07c1ea2860e4638 Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Wed, 12 Sep 2012 18:17:42 +0400
Subject: [PATCH] Add function for making item projectiles.
---
LUA_API.rst | 4 +++
Lua API.html | 3 +++
library/LuaApi.cpp | 8 ++++++
library/include/modules/Items.h | 4 +++
library/modules/Items.cpp | 45 +++++++++++++++++++++++++++++++++
5 files changed, 64 insertions(+)
diff --git a/LUA_API.rst b/LUA_API.rst
index a5be09a0e..1ffdada0a 100644
--- a/LUA_API.rst
+++ b/LUA_API.rst
@@ -999,6 +999,10 @@ Items module
Move the item to the unit inventory. Returns *false* if impossible.
+* ``dfhack.items.makeProjectile(item)``
+
+ Turns the item into a projectile, and returns the new object, or *nil* if impossible.
+
Maps module
-----------
diff --git a/Lua API.html b/Lua API.html
index 7886fbc25..168f7dcc6 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -1213,6 +1213,9 @@ Returns false in case of error.
dfhack.items.moveToInventory(item,unit,use_mode,body_part)
Move the item to the unit inventory. Returns false if impossible.
+dfhack.items.makeProjectile(item)
+Turns the item into a projectile, and returns the new object, or nil if impossible.
+
diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp
index d39a945dd..f69fa7a1b 100644
--- a/library/LuaApi.cpp
+++ b/library/LuaApi.cpp
@@ -80,6 +80,7 @@ distribution.
#include "df/region_map_entry.h"
#include "df/flow_info.h"
#include "df/unit_misc_trait.h"
+#include "df/proj_itemst.h"
#include
#include
@@ -885,6 +886,12 @@ static bool items_moveToInventory
return Items::moveToInventory(mc, item, unit, mode, body_part);
}
+static df::proj_itemst *items_makeProjectile(df::item *item)
+{
+ MapExtras::MapCache mc;
+ return Items::makeProjectile(mc, item);
+}
+
static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPM(Items, getGeneralRef),
WRAPM(Items, getSpecificRef),
@@ -896,6 +903,7 @@ static const LuaWrapper::FunctionReg dfhack_items_module[] = {
WRAPN(moveToContainer, items_moveToContainer),
WRAPN(moveToBuilding, items_moveToBuilding),
WRAPN(moveToInventory, items_moveToInventory),
+ WRAPN(makeProjectile, items_makeProjectile),
{ NULL, NULL }
};
diff --git a/library/include/modules/Items.h b/library/include/modules/Items.h
index 4236f068a..7493d22fc 100644
--- a/library/include/modules/Items.h
+++ b/library/include/modules/Items.h
@@ -44,6 +44,7 @@ distribution.
namespace df
{
struct itemdef;
+ struct proj_itemst;
}
namespace MapExtras {
@@ -155,5 +156,8 @@ DFHACK_EXPORT bool moveToContainer(MapExtras::MapCache &mc, df::item *item, df::
DFHACK_EXPORT bool moveToBuilding(MapExtras::MapCache &mc, df::item *item, df::building_actual *building,int16_t use_mode);
DFHACK_EXPORT bool moveToInventory(MapExtras::MapCache &mc, df::item *item, df::unit *unit,
df::unit_inventory_item::T_mode mode = df::unit_inventory_item::Carried, int body_part = -1);
+
+/// Detaches the items from its current location and turns it into a projectile
+DFHACK_EXPORT df::proj_itemst *makeProjectile(MapExtras::MapCache &mc, df::item *item);
}
}
diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp
index dc64143c9..751797f06 100644
--- a/library/modules/Items.cpp
+++ b/library/modules/Items.cpp
@@ -72,8 +72,11 @@ using namespace std;
#include "df/general_ref_contains_itemst.h"
#include "df/general_ref_contained_in_itemst.h"
#include "df/general_ref_building_holderst.h"
+#include "df/general_ref_projectile.h"
#include "df/viewscreen_itemst.h"
#include "df/vermin.h"
+#include "df/proj_itemst.h"
+#include "df/proj_list_link.h"
#include "df/unit_inventory_item.h"
#include "df/body_part_raw.h"
@@ -88,6 +91,7 @@ using namespace df::enums;
using df::global::world;
using df::global::ui;
using df::global::ui_selected_unit;
+using df::global::proj_next_id;
#define ITEMDEF_VECTORS \
ITEM(WEAPON, weapons, itemdef_weaponst) \
@@ -866,3 +870,44 @@ bool DFHack::Items::moveToInventory(
return true;
}
+
+df::proj_itemst *Items::makeProjectile(MapExtras::MapCache &mc, df::item *item)
+{
+ CHECK_NULL_POINTER(item);
+
+ if (!world || !proj_next_id)
+ return NULL;
+
+ auto pos = getPosition(item);
+ if (!pos.isValid())
+ return NULL;
+
+ auto ref = df::allocate();
+ if (!ref)
+ return NULL;
+
+ if (!detachItem(mc, item))
+ {
+ delete ref;
+ return NULL;
+ }
+
+ item->pos = pos;
+ item->flags.bits.in_job = true;
+
+ auto proj = new df::proj_itemst();
+ proj->link = new df::proj_list_link();
+ proj->link->item = proj;
+ proj->id = (*proj_next_id)++;
+
+ proj->origin_pos = proj->target_pos = pos;
+ proj->cur_pos = proj->prev_pos = pos;
+ proj->item = item;
+
+ ref->projectile_id = proj->id;
+ item->itemrefs.push_back(ref);
+
+ linked_list_append(&world->proj_list, proj->link);
+
+ return proj;
+}