Inventory view customisation

This forum is for the Lua scriptable clone of DM/CSB called Dungeon Strikes Back by Sophia. Use DSB to build your own highly customised games.

Moderator: Sophia

Forum rules
Please read the Forum rules and policies before posting.
Post Reply
User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Inventory view customisation

Post by Gambit37 » 23-Nov-18 15:04

Me again! :D

I'm re-designing the DM inventory screen, and have thought of some ways to improve it. However, I don't know how to code this in DSB. This is what I want to do:
  1. Add an extra button to the inventory screen
  2. Display a custom sub-renderer when the button is clicked. (I also want the sub-renderer to stay open after the button is clicked)
  3. Allow interaction (clicks) within the new subrenderers (ie, get user input and respond to it, like in a full-screen renderer)
Please would it be possible to get some help with this? (I'm probably OK with parts of #2, but the other stuff doesn't seem to have any examples anywhere that I can find...)

User avatar
Sophia
Concise and Honest
Posts: 4002
Joined: 12-Sep-02 19:50
Location: Nowhere in particular
Contact:

Re: Inventory view customisation

Post by Sophia » 6-Dec-18 22:46

Adding buttons is accomplished via dsb_msgzone, which has some examples (albeit somewhat opaque ones) in base/render.lua. You'll probably want to write your own h_custom_inventory function of the form:

Code: Select all

function h_custom_inventory(bmp, who, name_draw_type, final)
   if (final == true) then
      -- add dsb_msgzone or whatever here
   end
   return false
end
You actually asked about dsb_msgzone some years ago, in this thread. The method of using a function_caller still works, of course, although there is more information on the "correct" approach on the wiki now.

You can then have a your own h_custom_mainsub that checks some variable that was set by the msgzone and overrides the main subrenderer for however long it takes; it can of course have its own dsb_msgzone calls that add more buttons.

I understand that this is all still probably a bit unclear so feel free to ask questions!

User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Re: Inventory view customisation

Post by Gambit37 » 6-Dec-18 23:40

Wow, I'd totally forgotten I'd asked about this before...! :shock: 6 years ago!

I understand these hooks slightly better now. It was clever of you to allow the text to be added to, rather than obliterated by a custom function :)

But back to the issue of adding a button to the inventory. Lets check my understanding: If I want a new button in my inventory that, for example, pops up a full screen renderer, then I think I need these various moving parts:

1) A new user defined system message, eg, SYS_MYSCREEN = 32
2) Within the new inventory hook, add a message zone for this message (should the third number be 0?)

Code: Select all

function h_custom_inventory(bmp, who, name_draw_type, final)
   if (final == true) then
      dsb_msgzone(bmp, SYSTEM, 0, x, y, w, h, SYS_MYSCREEN)
   end
   return false
end
3) A new system function for SYS_MYSCREEN to do the full screen renderer.

^^ This is the bit I've no idea about ^^^

In that old thread you said "Then, write sys_system_message, which by default does nothing, to handle your message." I don't follow this bit, please could you elaborate in the context of my example? How should this be named, and what parameters will it accept?

I think I'm more or less getting there, but need a bit more help. Thank you :)

User avatar
Sophia
Concise and Honest
Posts: 4002
Joined: 12-Sep-02 19:50
Location: Nowhere in particular
Contact:

Re: Inventory view customisation

Post by Sophia » 7-Dec-18 00:14

The third parameter is the zone id. If two zones on the same screen have the same zone id, then the first one will get replaced. You can specify AUTOMATIC and DSB will assign you a unique id so you can be sure this won't happen, which is probably what you want to do in this case.

Your sys_system_message function will probably look like this:

Code: Select all

function sys_system_message(msg, data, ext_data)
	if (msg == SYS_MYSCREEN) then
		-- do whatever!
	end

	return nil
end
If you want to pop up a fullscreen renderer, that's where you'd put your call to dsb_fullscreen for example.

User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Re: Inventory view customisation

Post by Gambit37 » 7-Dec-18 09:06

Superb, thanks for clarifying. That's the last piece of the puzzle I was missing. I think I can now do all the stuff I was aiming to! Fantastic, thank you. :)

User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Re: Inventory view customisation

Post by Gambit37 » 7-Dec-18 09:37

Regarding sub-renderers: can you point me in the right direction for how to create msgzones and responses for a tabbed interface? How would I do something like this, where each tab responds to a click and displays different information? I'm still not 100% sure how to send a msgzone message back into the sub-renderer itself?

Image

EDIT: After looking at the moneybox example on the test dungeon, I think I can see how to do it. Send the messages to the SR instance, but with a data parameter for each "tab", then respond to the value of that tab with some code to draw the relevant page of data, eg:

Code: Select all

dsb_msgzone(sr, SYSTEM, AUTOMATIC, X1, Y1, W, H, M_NEXTTICK, 1)
dsb_msgzone(sr, SYSTEM, AUTOMATIC, X2, Y2, W, H, M_NEXTTICK, 2)
dsb_msgzone(sr, SYSTEM, AUTOMATIC, X3, Y3, W, H, M_NEXTTICK, 3)
Is this the right approach?

Also, are subrenderers still restricted to 246x146? If I wrote a whole bunch of new replacements, could they be custom sizes?

User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Re: Inventory view customisation

Post by Gambit37 » 7-Dec-18 11:44

I don't want to overload this thread with too many questions at a time, but I'm having problems with a custom msg zone.

I tried adding an extra button & message zone to the custom inventory hook. The bitmap is drawn correctly, but the msgzone doesn't work and generates four identical errors in the log file:

LUA ERROR: dmredux/code/hooks.lua:24: dsb_msgzone: Invalid msgzone target

What I've got:

1) A new global SYS_OPTIONS = 1
2) My changes to h_custom_inventory in my own hooks.lua:

Code: Select all

function h_custom_inventory(bmp, who, name_draw_type, final)
	-- Custom rendering and msgzones
	if (final == true) then
		-- Options Button
		dsb_bitmap_draw(gfx.ui_icon_options, bmp, 390, 8, false)
		dsb_msgzone(bmp, SYSTEM, AUTOMATIC, 390, 8, 20, 20, SYS_OPTIONS)
	end
	-- Normal rendering
	return false
end
3) A function call for that message in sys_system_message:

Code: Select all

function sys_system_message(msg, data, ext_data)
	-- Options Screen
	if (msg == SYS_OPTIONS) then
		mhf_options()
	end
	return nil
end

User avatar
Sophia
Concise and Honest
Posts: 4002
Joined: 12-Sep-02 19:50
Location: Nowhere in particular
Contact:

Re: Inventory view customisation

Post by Sophia » 7-Dec-18 20:53

That msgzone error is probably a bug in DSB. I'll investigate it and let you know.
(I'll answer the rest once I've sorted out this bug!)

User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Re: Inventory view customisation

Post by Gambit37 » 7-Dec-18 21:33

If it helps, the msgzone and custom sys message works perfectly if I embed it in the sys_render_other function. So the bug might be specific to the inventory renderer?

User avatar
Sophia
Concise and Honest
Posts: 4002
Joined: 12-Sep-02 19:50
Location: Nowhere in particular
Contact:

Re: Inventory view customisation

Post by Sophia » 7-Dec-18 22:45

This is actually sort of a mess. Expect 0.71 soon. :roll: :oops:

User avatar
Gambit37
Should eat more pies
Posts: 13251
Joined: 31-May-00 11:57
Location: Location, Location
Contact:

Re: Inventory view customisation

Post by Gambit37 » 9-Dec-18 15:09

Cool, now that the msg_zone thing is fixed in 0.71, I'll repost my earlier enquiry as I think it got missed:

Regarding sub-renderers: can you point me in the right direction for how to create msgzones and responses for a tabbed interface? How would I do something like this, where each tab responds to a click and displays different information? I'm still not 100% sure how to send a msgzone message back into the sub-renderer itself?

Image

EDIT: After looking at the moneybox example on the test dungeon, I think I can see how to do it. Send the messages to the SR instance, but with a data parameter for each "tab", then respond to the value of that tab with some code to draw the relevant page of data, eg:

Code: Select all

dsb_msgzone(sr, SYSTEM, AUTOMATIC, X1, Y1, W, H, M_NEXTTICK, 1)
dsb_msgzone(sr, SYSTEM, AUTOMATIC, X2, Y2, W, H, M_NEXTTICK, 2)
dsb_msgzone(sr, SYSTEM, AUTOMATIC, X3, Y3, W, H, M_NEXTTICK, 3)
Is this the right approach?

Also, are subrenderers still restricted to 246x146? If I wrote a whole bunch of new replacements, could they be custom sizes?

User avatar
Sophia
Concise and Honest
Posts: 4002
Joined: 12-Sep-02 19:50
Location: Nowhere in particular
Contact:

Re: Inventory view customisation

Post by Sophia » 9-Dec-18 17:20

It was not missed! Bug fixes took priority.

Anyway, another thing that I'd do if I were starting DSB over today is dispense with all the specialized object types and just make everything an object instance: party members, conditions, subrenderers, etc. However, since subrenderers are not instances, you can't send them messages, so your method won't work.

Instead, define a new system message, like SYS_SWITCHTAB, and send that as your message in the tabs' msgzones. System messages can send two parameters so you could also send who as a parameter if you don't want to force everyone's inventory to be looking at the same tab at the same time. In sys_system_message add code to handle this case, and store the displayed tab in a variable. If you're doing it per-character you could store it as a ch_exvar, which is like an exvar for characters. Regardless, you can use that variable in your renderer (which is probably h_custom_mainsub but I don't know exactly what you are doing with it) and draw the correct tab.

Subrenderers are still 246x146 mostly because there was no compelling reason to support any other size. I guess it depends on what you want to actually do.

Post Reply