More fun with inventory events

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
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

More fun with inventory events

Post by kaypy »

Suppose you have the following code

Code: Select all

function dlog(text)
	__log(text)
	dsb_write(debug_color, text )
end

function log_on_remove(self,id,who)
	dlog("MOVED : " .. id)
end

obj.silk_shirt.after_from_torso=log_on_remove
obj.tabard.after_from_legs=log_on_remove

-- callback for M_NEXTTICK
function test_on_tick(id, data)
	dlog("CALL0")
	dsb_move(2,0,3,4,3) -- refers to a worn shirt
	dlog("CALL1")
	dsb_move(3,0,3,4,3) -- refers to a worn tabard
	dlog("CALL2")
end
What do you suppose happens when the M_NEXTTICK event occurs?

Answer: It depends on when it is called...

Code: Select all

function test_after_remove(self,id,who)
	dsb_msg(0,id,M_NEXTTICK,0)
end

function method_trigger(name, ppos, who, what)
	dsb_msg(0,what,M_NEXTTICK,0)
end

obj.testcase=clone_arch(obj.dagger, {
	after_from_r_hand=test_after_remove,
	msg_handler={[M_NEXTTICK]=test_on_tick},
	methods = {
		{ "THROW", 0, CLASS_NINJA, method_throw_obj },
		{ "TRIGGER", 0, CLASS_NINJA, method_trigger }
	}
})
From running the trigger:
Lua: CALL0
Lua: MOVED : 2
Lua: CALL1
Lua: MOVED : 3
Lua: CALL2

From the remove callback:
Lua: CALL0
Lua: CALL1
Lua: CALL2
Lua: MOVED : 2
Lua: MOVED : 3

OK I can see why it could wind up working that way, but it sure makes understanding the system challenging...
Friends don't let friends eat worm round
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: More fun with inventory events

Post by Sophia »

It's a bit tricky! I think you're the first (well, second if you count me, I guess) person to analyze DSB's timing of events in this much detail.

The reason for this is because DSB has a queuing system to prevent all kinds of terrible crashes, like moving something out of an inventory slot in a function that iterates over all the inventory slots, or something. So, as a result, the processing of the dsb_move and its subsequent events is delayed. If it would help you, I could put in a flag that would disable the queue, but I would name it something like DISABLING_THE_QUEUE_MIGHT_CRASH_DSB ... :mrgreen:
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: More fun with inventory events

Post by kaypy »

What I think might be useful would be almost the opposite-

How hard would it be to add something like
dsb_msg(END_OF_QUEUE,id,messagetype,data)?

What I am working towards is equipment that occupies multiple slots by putting itself in the primary slot and having virtual items it places in the other slots.

So when it detects being put in its slot it needs to first move the current occupant of the secondary slot out, then move the virtual item in. Since I have to wait for the current occupant to be removed before I can add the new one, the timing gets a bit tricky. And stepping back to a simpler test case kept giving me misleading results 8-)

So for example I think I can put items in place by something like:
1) detect base-item to-inventory
1.1) move current items away
1.2) change base-item type to something with appropriate from-inventory method
1.3) move former-base-item away
2) detect former-base-item from-inventory
2.1) current items are away, so move virtual items in
2.2) move former-base-item back in

The really messy part comes from merging all the virtual items back in to the base item when it gets removed. Or for real mess, dealing with replacing one multipart item with another.

Some sort of wait-till-the-end-of-the-queue function would allow for much less item-type shuffling
Friends don't let friends eat worm round
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: More fun with inventory events

Post by Sophia »

kaypy wrote:How hard would it be to add something like dsb_msg(END_OF_QUEUE,id,messagetype,data)?
Flushing the queue before DSB is expecting it would have all sorts of weird problems. I'd really rather not do that if we can help it.
kaypy wrote:What I am working towards is equipment that occupies multiple slots by putting itself in the primary slot and having virtual items it places in the other slots.
Clever!

One option, of course, is that large items don't actually clear space for themselves at all. If they're put in a place where they "fit," then they go in, and if they don't, then they'll simply refuse to be dropped in the backpack. It's one of the easier ways to handle it, and would completely circumvent the problem-- although it's perhaps not the most user-friendly.

Otherwise, it seems like what would help you the most would be some way of handling the object clearing space for itself and then being able to move objects in without creating problems, without having to use messages delayed by a tick or something else that might be awkward like that. Ultimately, what might be the best approach would be to maintain some state information in the queue and then let calls to dsb_move use that, so that it won't fail if you try to move something into a slot that is queued up to be emptied. That will allow everything to "just work." I'll try to update DSB to work that way.
kaypy
Artisan
Posts: 171
Joined: Sun Jan 19, 2014 7:11 am

Re: More fun with inventory events

Post by kaypy »

I wasn't thinking of flushing the queue, just appending a "send this message now" event to the end of it.

So I can do
"move this item"
"at the end of the queue (ie once the item is moved) do the next step"

Here's a version that works except there are visible delays at each step. If I could fire off the next event at the end of the queue instead of a tick later than the end of the queue it would probably all be fine
http://en.file-upload.net/download-8612 ... s.lua.html
Friends don't let friends eat worm round
User avatar
Sophia
Concise and Honest
Posts: 4240
Joined: Thu Sep 12, 2002 9:50 pm
Location: Nowhere in particular
Contact:

Re: More fun with inventory events

Post by Sophia »

Oh, I see.

I'll add a special END_OF_FRAME delay that defers the processing of the message to the end of the current frame. It isn't quite 1, but it's more than 0. That should have the same effect for you, but without the mess of connecting any message processing to the inventory queue.
Post Reply