Skip to content

Commit

Permalink
A clua interface for scrolls of acquirement
Browse files Browse the repository at this point in the history
With the despoilering of acquirement in 0.25, a lua interface to the
acquirement menu is necessary so that clua users can inspect the results
and determine which item to choose. This commit adds a hook
c_choose_acquirement() that is called if it's defined in clua. It's
expected to return a valid index from the set of choices, using 1 for
the first item as is customary for lua. If no c_choose_acquirement
function is found, or if the call generates an error, or if the returned
index is invalid, the acquirement proceeds normally to the acquirement
menu. A valid call and return index will cause the indicated item to be
acquired, bypassing the menu.

This commit also adds items.acquirement_items() to the items library,
which returns a lua array of items.Item representations of the generated
items. All item details are provided, since acquirement gives fully
identified items. If acquirement is not in progress, this function
returns nil. Any c_choose_acquirement() function should call
items.acquirement_items() and inspect the results to make a
determination. I'll later add a commit to elliptic/qw#30 to add support
for 0.25 acquirement to qw using this interface.

Ideally we'd not have to have items.acquirement_items as its own
function and could just pass the item table as an argument to
c_choose_acquirement. I'm not sure if lua's "light userdata" facility
can accommodate this, and we have limited support passing arguments from
C++ to lua. If it turns out to be possible, we can refactor the
interface in a later commit.
  • Loading branch information
gammafunk committed Mar 13, 2020
1 parent 1e14c54 commit a39ba6b
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 7 deletions.
36 changes: 29 additions & 7 deletions crawl-ref/source/acquire.cc
Expand Up @@ -1628,6 +1628,17 @@ void AcquireMenu::update_help()
: "examine item")));
}

static void _create_acquirement_item(item_def &item)
{
if (is_unrandom_artefact(item))
set_unique_item_status(item, UNIQ_EXISTS);

if (copy_item_to_grid(item, you.pos()))
canned_msg(MSG_SOMETHING_APPEARS);
else
canned_msg(MSG_NOTHING_HAPPENS);
}

bool AcquireMenu::acquire_selected()
{
vector<MenuEntry*> selected = selected_entries();
Expand Down Expand Up @@ -1655,14 +1666,8 @@ bool AcquireMenu::acquire_selected()
}

item_def &acq_item = *static_cast<item_def*>(entry.data);
_create_acquirement_item(acq_item);

if (is_unrandom_artefact(acq_item))
set_unique_item_status(acq_item, UNIQ_EXISTS);

if (copy_item_to_grid(acq_item, you.pos()))
canned_msg(MSG_SOMETHING_APPEARS);
else
canned_msg(MSG_NOTHING_HAPPENS);
acq_items.clear();
return false;
}
Expand Down Expand Up @@ -1795,6 +1800,23 @@ bool acquirement_menu()

auto &acq_items = you.props[ACQUIRE_ITEMS_KEY].get_vector();

#ifdef CLUA_BINDINGS
int index = 0;
if (!clua.callfn("c_choose_acquirement", ">d", &index))
{
if (!clua.error.empty())
mprf(MSGCH_ERROR, "Lua error: %s", clua.error.c_str());
}
else if (index >= 1 && index <= acq_items.size())
{
_create_acquirement_item(acq_items[index - 1]);

acq_items.clear();
you.props.erase(ACQUIRE_ITEMS_KEY);
return true;
}
#endif

AcquireMenu acq_menu(acq_items);
acq_menu.show();

Expand Down
9 changes: 9 additions & 0 deletions crawl-ref/source/dat/dlua/userbase.lua
Expand Up @@ -354,3 +354,12 @@ end
--
-- @tparam string kind
-- @function ch_start_running
--
--- Acquirement scroll hook.
--
-- This hook can be defined to execute lua when an acquirement scroll is read.
--
-- The parameter is an array of items.
--
-- @tparam array items
-- @function c_acquirement
25 changes: 25 additions & 0 deletions crawl-ref/source/l-item.cc
Expand Up @@ -1527,6 +1527,30 @@ static int l_item_shopping_list(lua_State *ls)
return 1;
}

/*** See the items offered by acquirement.
* Only works when the acquirement menu is active.
* @treturn array|nil An array of @{Item} objects or nil if not acquiring.
* @function shop_inventory
*/
static int l_item_acquirement_items(lua_State *ls)
{
if (!you.props.exists(ACQUIRE_ITEMS_KEY))
return 0;

auto &acq_items = you.props[ACQUIRE_ITEMS_KEY].get_vector();

lua_newtable(ls);

int index = 0;
for (const item_def &item : acq_items)
{
_clua_push_item_temp(ls, item);
lua_rawseti(ls, -2, ++index);
}

return 1;
}

struct ItemAccessor
{
const char *attribute;
Expand Down Expand Up @@ -1627,6 +1651,7 @@ static const struct luaL_reg item_lib[] =
{ "get_items_at", l_item_get_items_at },
{ "shop_inventory", l_item_shop_inventory },
{ "shopping_list", l_item_shopping_list },
{ "acquirement_items", l_item_acquirement_items },
{ nullptr, nullptr },
};

Expand Down

0 comments on commit a39ba6b

Please sign in to comment.