LuaWindow class
#1
LuaWindow
MCServer needs a class open for lua that allows them to create custom windows. For example if you use a command that it will open a window with 9 slots or something. This is the idea i have on how to work with it in Lua but i have no idea if it is possible:
function HandleCommand( Split, Player )
	Window = cLuaWindow(cWindow.Chest, 3 * 9);  -- Create a chest window with 27 slots, besides the player inventory
	Item = cItem( E_BLOCK_DEAD_BUSH, 1, 0, 0 ) -- Create a item. It\'s just an example    <--
	Window:SetSlot( 1, Item ) -- Set the first slot to the Item                          /\
	Window:SetOnSlotChange(MyOnSlotChangeFunction); -- When the player changes a slot, the given function gets called
	Window:SetOnWindowClose(MyOnWindowCloseFunction); -- When the player closes the window, the given function gets called
	Player:OpenWindow( Window ) -- Send the window to the player and let him open it     ||
end

Then with the use of a hook, the plugin should know what item the player clicked on.
  • Client expects a window type with the "OpenWindow" packet, which specifies the UI to show and the number of slots. The types are listed in the cWindow class: cWindow::Inventory, cWindow::Chest, cWindow::Anvil ...)
  • We could pack the Window:Create into the object constructor:
    Window = cLuaWindow(cWindow.Chest, 3 * 9);  -- Create a chest window with 27 slots, besides the player inventory
    
  • MCServer windows are sectioned into SlotAreas. One SlotArea services a groupd of slots of a similar function, such as the armor slots or the crafting grid. It would be wise to use the same distinction for Lua (so that the player inventory can be handled automatically by the server)
    • Disregard this, this can be handled automatically by the API adapter. As far as Lua is concerned, the window can have a contiguous array of slots, count of which is given in the constructor.
  • Hooks are more suited for global callbacks. The window callbacks are more local, so consider using an approach already used for commands - pass in a function which is to be called when something happens:
    Window:SetOnSlotChange(MyOnSlotChangeFunction);
    Window:SetOnWindowClose(MyOnWindowCloseFunction);
    
  • Should it be possible to reuse the window object once the player closes it?
  • Should it be possible to pass the same window object to more different players?

Reply
Thanks given by:
#2
Ok, some notes:
- Client expects a window type with the "OpenWindow" packet, which specifies the UI to show and the number of slots. The types are listed in the cWindow class: cWindow::Inventory, cWindow::Chest, cWindow::Anvil ...)
- We could pack the Window:Create into the object constructor:
Window = cLuaWindow(cWindow.Chest, 3 * 9);  -- Create a chest window with 27 slots, besides the player inventory
- MCServer windows are sectioned into SlotAreas. One SlotArea services a groupd of slots of a similar function, such as the armor slots or the crafting grid. It would be wise to use the same distinction for Lua (so that the player inventory can be handled automatically by the server)
- Hooks are more suited for global callbacks. The window callbacks are more local, so consider using an approach already used for commands - pass in a function which is to be called when something happens:
Window:SetOnSlotChange(MyOnSlotChangeFunction);
Window:SetOnWindowClose(MyOnWindowCloseFunction);
- Should it be possible to reuse the window object once the player closes it?
- Should it be possible to pass the same window object to more different players?

(05-29-2013, 06:00 AM)xoft Wrote: - MCServer windows are sectioned into SlotAreas. One SlotArea services a groupd of slots of a similar function, such as the armor slots or the crafting grid. It would be wise to use the same distinction for Lua (so that the player inventory can be handled automatically by the server)

Disregard this, this can be handled automatically by the API adapter. As far as Lua is concerned, the window can have a contiguous array of slots, count of which is given in the constructor.
Reply
Thanks given by:
#3
(05-29-2013, 06:00 AM)xoft Wrote: Ok, some notes:
- Client expects a window type with the "OpenWindow" packet, which specifies the UI to show and the number of slots. The types are listed in the cWindow class: cWindow::Inventory, cWindow::Chest, cWindow::Anvil ...)
- We could pack the Window:Create into the object constructor:
Window = cLuaWindow(cWindow.Chest, 3 * 9);  -- Create a chest window with 27 slots, besides the player inventory

That does look a lot better.

xoft Wrote:- MCServer windows are sectioned into SlotAreas. One SlotArea services a groupd of slots of a similar function, such as the armor slots or the crafting grid. It would be wise to use the same distinction for Lua (so that the player inventory can be handled automatically by the server)

Yes it would be smart to make the normal window and the LuaWindow look like each other. Also grouping the slots would be much more manageable.

xoft Wrote:- Hooks are more suited for global callbacks. The window callbacks are more local, so consider using an approach already used for commands - pass in a function which is to be called when something happens:
Window:SetOnSlotChange(MyOnSlotChangeFunction);
Window:SetOnWindowClose(MyOnWindowCloseFunction);

Yes i was thinking if there maybe was a better way to do it but I didn't know about anything. That idea of yours looks like the best solution to me Wink

xoft Wrote:- Should it be possible to reuse the window object once the player closes it?
- Should it be possible to pass the same window object to more different players?

They can put it in a variable or a table i think?
Reply
Thanks given by:
#4
Ok, so now we have a code to open the window. How about code that reacts to the events in the window (the MyOnSlotChangeFunction() and MyOnWindowCloseFunction() )? What functions will there be for manipulating the window's slots' contents?
Reply
Thanks given by:
#5
I think:
 
Window:Close() --To force the player to close the window.
Window:SetSlot() -- to set a slot to another item
Window:GetNumSlots() -- returns the amount of slots. maybe it can return 2 values. the first is the amount of rows and the second is the amount of slots per row.
Window:GetSlot() -- returns the item type in the given slot.
 
Reply
Thanks given by:
#6
I think it'd be better to have a single cItemGrid represent the virtual window contents. We have quite a nice interface for that class, it knows how to do lots of things, so why duplicate the technology. I'd still keep the Window:SetSlot() and Window:GetSlot() functions, but other than that, you should do a Window:GetItemGrid() and perform more complex operations on it.

Now that we have the contents settled, how about those callbacks? Some example code?
Reply
Thanks given by:
#7
Maybe something like this?:
function HandleCommand( Split, Player )
	local MyOnSlotChangeFunction = function(Player, ChangedSlot)
		if Window:GetSlot( ChangedSlot ) == E_ITEM_EMERALD then
			Player:TeleportTo( X, Y, Z )
		elseif Window:GetSlot( ChangedSlot ) == E_ITEM_DIAMOND then
			Player:TeleportTo( X, Y, Z )
		elseif Window:GetSlot( ChangedSlot ) == E_BLOCK_DIRT then
			Player:SendMessage( cChatColor.Rose .. "Dirt is nothing worth" )
		else
			--Some code here
		end
	end
	local MyOnWindowCloseFunction = function( Player )
		Player:SendMessage( cChatColor.Rose .. "Pick something please" )
	end
    Window = cLuaWindow(cWindow.Chest, 3 * 9);
    Item = cItem( E_BLOCK_DEAD_BUSH, 1, 0, 0 );
    Window:SetSlot( 1, Item );
    Window:SetOnSlotChange(MyOnSlotChangeFunction);
    Window:SetOnWindowClose(MyOnWindowCloseFunction);
    Player:OpenWindow( Window );
end
Reply
Thanks given by:
#8
Wow, a teleport-vending machine, cool idea for a plugin, once we get this class working Smile "Insert a diamond to teleport."

Your MyOnSlotChangeFunction() is accessing a Window variable that it doesn't get anywhere; unless you store it somewhere globally, which is a bad idea. I'd add a Window parameter to both callbacks.
Reply
Thanks given by:
#9
Got that idea from a Minigame server I join once in a while. when you join you get a compass and when you right click it you get a screen with all kinds of items ( with custom names ) and then you can just pick a game and play Wink mc.mcorigins.com But what i am thinking about is give my Login plugin a update Wink Then you can use a window + items as a password ;D
Reply
Thanks given by:
#10
Maybe also add something that when the OnSlotChange returns true that the change will be stopped or something.
Reply
Thanks given by:




Users browsing this thread: 1 Guest(s)