Posts: 4,634
Threads: 115
Joined: Dec 2011
Thanks: 695
Given 495 thank(s) in 424 post(s)
05-29-2013, 05:20 AM
(This post was last modified: 05-29-2013, 07:13 AM by NiLSPACE.)
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?
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1075 thank(s) in 852 post(s)
05-29-2013, 06:00 AM
(This post was last modified: 05-29-2013, 06:07 AM by xoft.)
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.
Posts: 4,634
Threads: 115
Joined: Dec 2011
Thanks: 695
Given 495 thank(s) in 424 post(s)
(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
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?
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1075 thank(s) in 852 post(s)
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?
Posts: 4,634
Threads: 115
Joined: Dec 2011
Thanks: 695
Given 495 thank(s) in 424 post(s)
05-29-2013, 11:41 PM
(This post was last modified: 05-29-2013, 11:42 PM by NiLSPACE.)
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.
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1075 thank(s) in 852 post(s)
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?
Posts: 4,634
Threads: 115
Joined: Dec 2011
Thanks: 695
Given 495 thank(s) in 424 post(s)
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
Posts: 6,485
Threads: 176
Joined: Jan 2012
Thanks: 131
Given 1075 thank(s) in 852 post(s)
Wow, a teleport-vending machine, cool idea for a plugin, once we get this class working "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.
Posts: 4,634
Threads: 115
Joined: Dec 2011
Thanks: 695
Given 495 thank(s) in 424 post(s)
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 mc.mcorigins.com But what i am thinking about is give my Login plugin a update Then you can use a window + items as a password ;D
Posts: 4,634
Threads: 115
Joined: Dec 2011
Thanks: 695
Given 495 thank(s) in 424 post(s)
Maybe also add something that when the OnSlotChange returns true that the change will be stopped or something.
|