Skip to content

Lua custom items#8550

Open
yuripourre wants to merge 13 commits intodiasurgical:masterfrom
yuripourre:lua-custom-items
Open

Lua custom items#8550
yuripourre wants to merge 13 commits intodiasurgical:masterfrom
yuripourre:lua-custom-items

Conversation

@yuripourre
Copy link
Copy Markdown
Collaborator

@yuripourre yuripourre commented Apr 22, 2026

PR to enable custom items using Lua

  • Add method to register/free custom item graphics
  • Add helper methods to get item graphics (instead of directly from the array)
  • Add method to create items using lua

Loading regular diablo save files do not break.

Example of Mod - Katar (as a sword)

local events = require("devilutionx.events")
local items = require("devilutionx.items")
local audio = require("devilutionx.audio")

events.ItemDataLoaded.add(function()
  local cursId = items.registerCursorGraphic("lua\\mods\\katar\\objcur\\katar", 28)
  -- Register the item
  items.addItem({
    name = "Katar",
    shortName = "Katar",
    mappingId = 50000,
    type = items.ItemType.Sword,
    class = items.ItemClass.Weapon,equipType = items.ItemEquipType.OneHand,
    cursorGraphic = cursId,
    minDam = 4,
    maxDam = 7,
    durability = 30,
    value = 100
  })
end)
katar.mp4

File with the mod katar.mpq
katar_mod.zip

@HoofedEar
Copy link
Copy Markdown
Contributor

Love this!
Looks like this is specifically adding a new equipment in your example right? Would there be support for adding a consumable (with a custom effect) or will that be something separate?

@yuripourre
Copy link
Copy Markdown
Collaborator Author

Love this! Looks like this is specifically adding a new equipment in your example right? Would there be support for adding a consumable (with a custom effect) or will that be something separate?

It can be done, I only created a weapon because it would be a more complex example but I can try to create a consumable. @HoofedEar do you have anything specific in mind?

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR enables Lua-defined custom items by allowing mods to register custom cursor/drop graphics and sounds, and by routing item animation/sound lookups through helper functions that safely handle custom cursor IDs. It also adjusts save-loading to better preserve modded items.

Changes:

  • Add custom cursor/drop graphic + sound registration APIs and safe lookup helpers (GetItemAnimType, GetItemInvSnd, GetItemDropSnd).
  • Expose Lua APIs to define items/uniques and register associated graphics/sounds.
  • Update inventory/stash/store UI call sites to use the new helpers; add unit tests and wire them into CMake.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
test/custom_items_test.cpp Adds unit tests for new item anim/sound lookup and custom item registration behavior.
Source/tables/itemdat.cpp Clears custom cursor sprites before reloading item data.
Source/qol/visual_store.cpp Uses GetItemInvSnd instead of direct table lookup.
Source/qol/stash.cpp Uses GetItemInvSnd instead of direct table lookup.
Source/qol/itemlabels.cpp Uses GetItemAnimType instead of direct table lookup.
Source/lua/modules/items.cpp Adds Lua APIs for adding items/uniques and registering graphics/sounds.
Source/loadsave.cpp Preserves unpacked items when heroitems data can’t be loaded/recreated.
Source/items.h Declares new custom item APIs and exposes ItemCAnimTblSize.
Source/items.cpp Implements custom drop anim/sound registries + safe lookup helpers.
Source/inv.cpp Uses GetItemInvSnd instead of direct table lookup.
Source/cursor.h Declares custom cursor sprite registration/free APIs.
Source/cursor.cpp Implements custom cursor sprite storage and lookup in GetInvItemSprite.
CMake/Tests.cmake Adds custom_items_test to the test suite.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Source/tables/itemdat.cpp
Comment thread Source/cursor.cpp
Comment thread Source/items.cpp Outdated
Comment thread Source/lua/modules/items.cpp Outdated
Comment thread Source/lua/modules/items.cpp
Comment thread test/custom_items_test.cpp
Comment thread test/custom_items_test.cpp
Comment thread Source/cursor.cpp
Comment thread Source/items.cpp Outdated
@HoofedEar
Copy link
Copy Markdown
Contributor

It can be done, I only created a weapon because it would be a more complex example but I can try to create a consumable. @HoofedEar do you have anything specific in mind?

Coming from that source mod I was working on, where I added an item that turns a normal equipment into a magical one, I remember having to define what the cursor sprite would be when consumed, and then the effect that applies it. But I believe I went the route of creating a spell, so consuming the item was similar to reading a scroll. But I'm not sure what the best way to do that in Lua would be hmm. I guess "recreating" a scroll with a different name might be a good starting point?

@yuripourre
Copy link
Copy Markdown
Collaborator Author

It can be done, I only created a weapon because it would be a more complex example but I can try to create a consumable. @HoofedEar do you have anything specific in mind?

Coming from that source mod I was working on, where I added an item that turns a normal equipment into a magical one, I remember having to define what the cursor sprite would be when consumed, and then the effect that applies it. But I believe I went the route of creating a spell, so consuming the item was similar to reading a scroll. But I'm not sure what the best way to do that in Lua would be hmm. I guess "recreating" a scroll with a different name might be a good starting point?

Hmm, if you have that spell already created, I think the new item can be used as a scroll. I can try that! But the new spell cannot be created using only lua, right?

@HoofedEar
Copy link
Copy Markdown
Contributor

Coming from that source mod I was working on, where I added an item that turns a normal equipment into a magical one, I remember having to define what the cursor sprite would be when consumed, and then the effect that applies it. But I believe I went the route of creating a spell, so consuming the item was similar to reading a scroll. But I'm not sure what the best way to do that in Lua would be hmm. I guess "recreating" a scroll with a different name might be a good starting point?

Hmm, if you have that spell already created, I think the new item can be used as a scroll. I can try that! But the new spell cannot be created using only lua, right?

I believe yes, for certain effects we'd probably have to write custom code
So in my mind, the mod would be two lua files: one for the spell, and then one for the item that is a consumable that uses the spell (kinda like scroll of identify)

Definitely not trying to scope creep this haha just thinking out loud

@StephenCWills
Copy link
Copy Markdown
Member

You need to add DVL_API_FOR_TEST to the extern declarations in the header files for the following global variables:

  • ItemMappingIdsToIndices
  • ItemCAnimTbl
  • ItemCAnimTblSize

@yuripourre
Copy link
Copy Markdown
Collaborator Author

You need to add DVL_API_FOR_TEST to the extern declarations in the header files for the following global variables:

* `ItemMappingIdsToIndices`

* `ItemCAnimTbl`

* `ItemCAnimTblSize`

Done!

@yuripourre yuripourre force-pushed the lua-custom-items branch 2 times, most recently from 3a7ff02 to 8269f25 Compare April 27, 2026 19:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants