From 1148314bf123d16d6a9f9602c867302b74b10194 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Thu, 6 Apr 2023 21:50:00 +0200 Subject: [PATCH 01/35] Create gui_menu.sc --- programs/fundamentals/gui_menu.sc | 86 +++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 programs/fundamentals/gui_menu.sc diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc new file mode 100644 index 00000000..9e126287 --- /dev/null +++ b/programs/fundamentals/gui_menu.sc @@ -0,0 +1,86 @@ + + +__command() -> ( + gui = new_gui_menu(global_Test); + call_gui_menu(gui, player()); +); + +test()->( + screen = create_screen(player(),'generic_9x6',format('db Button Screen'),_(screen, player, action, data) -> ( + //print(str('Action:\nAction: %s\nData: %s',action,data)); + if(action=='quick_move'&&data:'slot'>=54, + return('cancel') + ); + if(action=='pickup', + print(str('Action:\nAction: %s\nData: %s',action,data)); //for testing + ); + //print(data); + if(data:'slot'==10, + 'cancel'//prevent tampering with slot 10 + ); + )); + inventory_set(screen, 10, 1, 'stone') +); + +global_inventory_sizes={ + 'generic_3x3'->9, + 'generic_9x1'->9, + 'generic_9x2'->18, + 'generic_9x3'->27, + 'generic_9x4'->36, + 'generic_9x5'->45, + 'generic_9x6'->54 +}; + +global_Test={ + 'inventory_shape'->'generic_3x3', + 'title'->format('db Test GUI menu!'), + 'buttons'->{ + 0->['green_stained_glass', _(button)->print(str('Clicked with %s button', if(button, 'Right', 'Left')))] + } +}; + + +new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function + if(type(gui_screen)!='map' || !has(gui_screen, 'inventory_shape'), + throw('Invalid gui creation: '+gui_screen) + ); + + inventory_shape = gui_screen:'inventory_shape'; + + inventory_size = global_inventory_sizes:inventory_shape; + + if(inventory_size==0, + throw('Invalid gui creation: Must be one of '+keys(global_inventory_sizes)+', not '+inventory_shape) + ); + + { + 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above + 'title'->gui_screen:'title', //Fancy GUI title + 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits + for(gui_screen:'buttons', + inventory_set(screen, _, 1, gui_screen:'buttons':_:0) + ); + ), + 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens + if(action=='quick_move', //disabling quick move cos it messes up the GUI, and there's no reason to allow it + return('cancel') + ); + + slot = data:'slot'; + + if(has(gui_screen:'buttons', slot) && action=='pickup', //This is equivalent of clicking (button action) + call(gui_screen:'buttons':slot:1, data:'button') + ); + + if(slot( + screen = create_screen(player, gui_menu:'inventory_shape', gui_menu:'title', gui_menu:'callback'); + call(gui_menu:'on_created', screen) +); From a4db6da4ebd4664f8e3422e38838000f54cf621b Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Thu, 6 Apr 2023 21:51:30 +0200 Subject: [PATCH 02/35] Getting rid of previous test functions --- programs/fundamentals/gui_menu.sc | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 9e126287..ed2d861d 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -5,22 +5,6 @@ __command() -> ( call_gui_menu(gui, player()); ); -test()->( - screen = create_screen(player(),'generic_9x6',format('db Button Screen'),_(screen, player, action, data) -> ( - //print(str('Action:\nAction: %s\nData: %s',action,data)); - if(action=='quick_move'&&data:'slot'>=54, - return('cancel') - ); - if(action=='pickup', - print(str('Action:\nAction: %s\nData: %s',action,data)); //for testing - ); - //print(data); - if(data:'slot'==10, - 'cancel'//prevent tampering with slot 10 - ); - )); - inventory_set(screen, 10, 1, 'stone') -); global_inventory_sizes={ 'generic_3x3'->9, From 8bf50b408ef7059230c3bc32fa8c73ff3f09bc4f Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Thu, 6 Apr 2023 22:02:14 +0200 Subject: [PATCH 03/35] Rearranged code, made prettier example --- programs/fundamentals/gui_menu.sc | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index ed2d861d..4dd71ce8 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -5,6 +5,7 @@ __command() -> ( call_gui_menu(gui, player()); ); +//Config global_inventory_sizes={ 'generic_3x3'->9, @@ -16,11 +17,15 @@ global_inventory_sizes={ 'generic_9x6'->54 }; +//Certain names are subject to change, so instead I'll store them in global variables while I'm still fiddling with exact nomenclature +global_static_buttons='buttons'; + global_Test={ 'inventory_shape'->'generic_3x3', 'title'->format('db Test GUI menu!'), - 'buttons'->{ - 0->['green_stained_glass', _(button)->print(str('Clicked with %s button', if(button, 'Right', 'Left')))] + global_static_buttons->{ + 0->['red_stained_glass', _(button)->print('Pressed the red button!')], + 4->['green_stained_glass', _(button)->print(str('Clicked with %s button', if(button, 'Right', 'Left')))] } }; @@ -42,8 +47,8 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above 'title'->gui_screen:'title', //Fancy GUI title 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits - for(gui_screen:'buttons', - inventory_set(screen, _, 1, gui_screen:'buttons':_:0) + for(gui_screen:global_static_buttons, + inventory_set(screen, _, 1, gui_screen:global_static_buttons:_:0) ); ), 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens @@ -53,10 +58,13 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p slot = data:'slot'; - if(has(gui_screen:'buttons', slot) && action=='pickup', //This is equivalent of clicking (button action) - call(gui_screen:'buttons':slot:1, data:'button') + if(action=='pickup', //This is equivalent of clicking (button action) + + if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button + call(gui_screen:global_static_buttons:slot:1, data:'button') + ); ); - + if(slot Date: Thu, 6 Apr 2023 22:37:30 +0200 Subject: [PATCH 04/35] Adding dynamic buttons (+ examples) Also changing from stained glass to stained glass panes --- programs/fundamentals/gui_menu.sc | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 4dd71ce8..eb9d0fdb 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -19,13 +19,26 @@ global_inventory_sizes={ //Certain names are subject to change, so instead I'll store them in global variables while I'm still fiddling with exact nomenclature global_static_buttons='buttons'; +global_dynamic_buttons='dynamic_buttons'; global_Test={ 'inventory_shape'->'generic_3x3', 'title'->format('db Test GUI menu!'), global_static_buttons->{ - 0->['red_stained_glass', _(button)->print('Pressed the red button!')], - 4->['green_stained_glass', _(button)->print(str('Clicked with %s button', if(button, 'Right', 'Left')))] + 0->['red_stained_glass_pane', _(button)->print('Pressed the red button!')], + 4->['green_stained_glass_pane', _(button)->print(str('Clicked with %s button', if(button, 'Right', 'Left')))] + }, + global_dynamic_buttons->{ + 1->{ //Blue button to black button + 'icon'->'blue_stained_glass_pane', + 'action'->_(screen)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); + }, + 6->{ //Turns the slot above purple + 'icon'->'lime_stained_glass_pane', + 'action'->_(screen)->( + inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); + ) + } } }; @@ -50,6 +63,9 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p for(gui_screen:global_static_buttons, inventory_set(screen, _, 1, gui_screen:global_static_buttons:_:0) ); + for(gui_screen:global_dynamic_buttons, + inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:'icon') + ); ), 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens if(action=='quick_move', //disabling quick move cos it messes up the GUI, and there's no reason to allow it @@ -61,7 +77,9 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p if(action=='pickup', //This is equivalent of clicking (button action) if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button - call(gui_screen:global_static_buttons:slot:1, data:'button') + call(gui_screen:global_static_buttons:slot:1, data:'button'), + has(gui_screen:global_dynamic_buttons, slot), //A more exciting button + call(gui_screen:global_dynamic_buttons:slot:'action', screen) ); ); From 9c4f6934ad13197b4fe091bc0172d91753230c29 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Thu, 6 Apr 2023 22:43:18 +0200 Subject: [PATCH 05/35] editing testing tools --- programs/fundamentals/gui_menu.sc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index eb9d0fdb..37377f90 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -1,8 +1,7 @@ - -__command() -> ( +__on_player_swings_hand(player, hand)-> ( gui = new_gui_menu(global_Test); - call_gui_menu(gui, player()); + call_gui_menu(gui, player); ); //Config From 9fe65df8d54d9de7ff094280c6905bf47eac7de1 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Fri, 7 Apr 2023 10:54:51 +0200 Subject: [PATCH 06/35] Adding storage slots --- programs/fundamentals/gui_menu.sc | 46 +++++++++++++++++++++---------- 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 37377f90..461c77b7 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -1,7 +1,8 @@ __on_player_swings_hand(player, hand)-> ( - gui = new_gui_menu(global_Test); - call_gui_menu(gui, player); + if(hand=='mainhand' && player~'holds':0=='brewing_stand', + call_gui_menu(global_Test_GUI, player) + ) ); //Config @@ -19,6 +20,7 @@ global_inventory_sizes={ //Certain names are subject to change, so instead I'll store them in global variables while I'm still fiddling with exact nomenclature global_static_buttons='buttons'; global_dynamic_buttons='dynamic_buttons'; +global_storage_slots='storage_slots'; global_Test={ 'inventory_shape'->'generic_3x3', @@ -30,18 +32,20 @@ global_Test={ global_dynamic_buttons->{ 1->{ //Blue button to black button 'icon'->'blue_stained_glass_pane', - 'action'->_(screen)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); + 'action'->_(screen, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); }, 6->{ //Turns the slot above purple 'icon'->'lime_stained_glass_pane', 'action'->_(screen)->( - inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); + inventory_set(screen, button, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); ) } + }, + global_storage_slots->{ //These slots can be used for storage by the player + 8->['stone', 4, null] //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot } }; - new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map' || !has(gui_screen, 'inventory_shape'), throw('Invalid gui creation: '+gui_screen) @@ -65,25 +69,34 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p for(gui_screen:global_dynamic_buttons, inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:'icon') ); + for(gui_screen:global_storage_slots, + [item, count, nbt] = gui_screen:global_storage_slots:_; + inventory_set(screen, _, count, item, nbt) + ); ), 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens - if(action=='quick_move', //disabling quick move cos it messes up the GUI, and there's no reason to allow it - return('cancel') - ); - - slot = data:'slot'; + slot = data:'slot'; //Grabbing slot, this is the focus of the action if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button call(gui_screen:global_static_buttons:slot:1, data:'button'), has(gui_screen:global_dynamic_buttons, slot), //A more exciting button - call(gui_screen:global_dynamic_buttons:slot:'action', screen) + call(gui_screen:global_dynamic_buttons:slot:'action', screen, data:'button') ); ); - if(slot( //Stores GUI data in intermediary map form, so the p call_gui_menu(gui_menu, player)->( screen = create_screen(player, gui_menu:'inventory_shape', gui_menu:'title', gui_menu:'callback'); - call(gui_menu:'on_created', screen) + call(gui_menu:'on_created', screen); + screen ); + +global_Test_GUI = new_gui_menu(global_Test); From 054ea20be716c1aff3884e7987072c48ef69bdd8 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Fri, 7 Apr 2023 12:23:07 +0200 Subject: [PATCH 07/35] Bugfix Storage slot functionality allowed players to tamper with slots --- programs/fundamentals/gui_menu.sc | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 461c77b7..57e5ffd2 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -70,7 +70,7 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:'icon') ); for(gui_screen:global_storage_slots, - [item, count, nbt] = gui_screen:global_storage_slots:_; + [item, count, nbt] = gui_screen:global_storage_slots:_ || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); ), @@ -85,24 +85,24 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p ); ); - //Disabling quick move cos it messes up the GUI, and there's no reason to allow it - //Also preventing the player from tampering with button slots - //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slot( +call_gui_menu(gui_menu, player)->( //Opens the screen to the player, returns screen for further manipulation screen = create_screen(player, gui_menu:'inventory_shape', gui_menu:'title', gui_menu:'callback'); call(gui_menu:'on_created', screen); screen From ebb23daf9927211e975bb1d962cc5ec09e7076fe Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Fri, 7 Apr 2023 12:31:45 +0200 Subject: [PATCH 08/35] adding player variable in button action callback --- programs/fundamentals/gui_menu.sc | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 57e5ffd2..2fabf36f 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -26,23 +26,24 @@ global_Test={ 'inventory_shape'->'generic_3x3', 'title'->format('db Test GUI menu!'), global_static_buttons->{ - 0->['red_stained_glass_pane', _(button)->print('Pressed the red button!')], - 4->['green_stained_glass_pane', _(button)->print(str('Clicked with %s button', if(button, 'Right', 'Left')))] + 0->['red_stained_glass_pane', _(player, button)->print(player, 'Pressed the red button!')], + 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] }, global_dynamic_buttons->{ 1->{ //Blue button to black button 'icon'->'blue_stained_glass_pane', - 'action'->_(screen, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); + 'action'->_(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); }, 6->{ //Turns the slot above purple 'icon'->'lime_stained_glass_pane', - 'action'->_(screen)->( - inventory_set(screen, button, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); + 'action'->_(screen, player, button)->( + inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); ) } }, global_storage_slots->{ //These slots can be used for storage by the player - 8->['stone', 4, null] //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot + 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot + 5, 2 //leaving this blank makes the slot blank } }; @@ -79,9 +80,9 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p if(action=='pickup', //This is equivalent of clicking (button action) if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button - call(gui_screen:global_static_buttons:slot:1, data:'button'), + call(gui_screen:global_static_buttons:slot:1, player, data:'button'), has(gui_screen:global_dynamic_buttons, slot), //A more exciting button - call(gui_screen:global_dynamic_buttons:slot:'action', screen, data:'button') + call(gui_screen:global_dynamic_buttons:slot:'action', screen, player, data:'button') ); ); From 1bdfce20a11c4dd1ef35fd6c9516b22f5c209f17 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Fri, 7 Apr 2023 13:12:02 +0200 Subject: [PATCH 09/35] Switching from map to list Might switch back later if it turns out to be more convenient --- programs/fundamentals/gui_menu.sc | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 2fabf36f..6777c65a 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -30,16 +30,17 @@ global_Test={ 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] }, global_dynamic_buttons->{ - 1->{ //Blue button to black button - 'icon'->'blue_stained_glass_pane', - 'action'->_(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); - }, - 6->{ //Turns the slot above purple - 'icon'->'lime_stained_glass_pane', - 'action'->_(screen, player, button)->( + 1->[ //Blue button to black button + 'blue_stained_glass_pane', + _(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); + ], + + 6->[ //Turns the slot above purple + 'lime_stained_glass_pane', + _(screen, player, button)->( inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); ) - } + ], }, global_storage_slots->{ //These slots can be used for storage by the player 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot @@ -68,7 +69,7 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p inventory_set(screen, _, 1, gui_screen:global_static_buttons:_:0) ); for(gui_screen:global_dynamic_buttons, - inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:'icon') + inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:0) ); for(gui_screen:global_storage_slots, [item, count, nbt] = gui_screen:global_storage_slots:_ || ['air', 0, null]; @@ -82,7 +83,7 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button call(gui_screen:global_static_buttons:slot:1, player, data:'button'), has(gui_screen:global_dynamic_buttons, slot), //A more exciting button - call(gui_screen:global_dynamic_buttons:slot:'action', screen, player, data:'button') + call(gui_screen:global_dynamic_buttons:slot:1, screen, player, data:'button') ); ); From 989c917eb2fbc1a6c2f1a9e9074f96939d6535ff Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Sat, 8 Apr 2023 22:22:55 +0200 Subject: [PATCH 10/35] Framework for pages functionality --- programs/fundamentals/gui_menu.sc | 166 +++++++++++++++++++++++------- 1 file changed, 126 insertions(+), 40 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 6777c65a..0af2f88b 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -18,9 +18,12 @@ global_inventory_sizes={ }; //Certain names are subject to change, so instead I'll store them in global variables while I'm still fiddling with exact nomenclature -global_static_buttons='buttons'; +global_static_buttons='static_buttons'; global_dynamic_buttons='dynamic_buttons'; global_storage_slots='storage_slots'; +global_pages='pages'; +global_main_page='main_page_title'; +global_current_page='current_page'; global_Test={ 'inventory_shape'->'generic_3x3', @@ -48,6 +51,40 @@ global_Test={ } }; +global_Test_pages={ + 'inventory_shape'->'generic_3x3', + 'title'->format('db Test GUI with pages!'), + global_main_page->'main_page', + global_current_page->null, + global_pages->{ + 'main_page'->{ + global_static_buttons->{ + 0->['red_stained_glass_pane', _(player, button)->print(player, 'Pressed the red button!')], + 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] + }, + global_storage_slots->{ //These slots can be used for storage by the player + 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot + 5, 2 //leaving this blank makes the slot blank + } + }, + 'second_page'->{ + global_dynamic_buttons->{ + 1->[ //Blue button to black button + 'blue_stained_glass_pane', + _(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); + ], + + 6->[ //Turns the slot above purple + 'lime_stained_glass_pane', + _(screen, player, button)->( + inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); + ) + ], + }, + } + } +}; + new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map' || !has(gui_screen, 'inventory_shape'), throw('Invalid gui creation: '+gui_screen) @@ -61,52 +98,101 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p throw('Invalid gui creation: Must be one of '+keys(global_inventory_sizes)+', not '+inventory_shape) ); - { - 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above - 'title'->gui_screen:'title', //Fancy GUI title - 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits - for(gui_screen:global_static_buttons, - inventory_set(screen, _, 1, gui_screen:global_static_buttons:_:0) - ); - for(gui_screen:global_dynamic_buttons, - inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:0) - ); - for(gui_screen:global_storage_slots, - [item, count, nbt] = gui_screen:global_storage_slots:_ || ['air', 0, null]; - inventory_set(screen, _, count, item, nbt) - ); - ), - 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens - slot = data:'slot'; //Grabbing slot, this is the focus of the action - - if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button - call(gui_screen:global_static_buttons:slot:1, player, data:'button'), - has(gui_screen:global_dynamic_buttons, slot), //A more exciting button - call(gui_screen:global_dynamic_buttons:slot:1, screen, player, data:'button') + if(!has(gui_screen, global_pages), //If there is no page functionality + { + 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above + 'title'->gui_screen:'title', //Fancy GUI title + 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits + for(gui_screen:global_static_buttons, + inventory_set(screen, _, 1, gui_screen:global_static_buttons:_:0) + ); + for(gui_screen:global_dynamic_buttons, + inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:0) ); - ); - - //Saving items in storage slots when closing - if(action=='close', for(gui_screen:global_storage_slots, - gui_screen:global_storage_slots:_ = inventory_get(screen, _); + [item, count, nbt] = gui_screen:global_storage_slots:_ || ['air', 0, null]; + inventory_set(screen, _, count, item, nbt) ); - ); - - //Disabling quick move cos it messes up the GUI, and there's no reason to allow it - //Also preventing the player from tampering with button slots - //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slot_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens + slot = data:'slot'; //Grabbing slot, this is the focus of the action + + if(action=='pickup', //This is equivalent of clicking (button action) + if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button + call(gui_screen:global_static_buttons:slot:1, player, data:'button'), + has(gui_screen:global_dynamic_buttons, slot), //A more exciting button + call(gui_screen:global_dynamic_buttons:slot:1, screen, player, data:'button') + ); + ); + + //Saving items in storage slots when closing + if(action=='close', + for(gui_screen:global_storage_slots, + gui_screen:global_storage_slots:_ = inventory_get(screen, _); + ); + ); + + //Disabling quick move cos it messes up the GUI, and there's no reason to allow it + //Also preventing the player from tampering with button slots + //Unless the slot is marked as a storage slot, in which case we allow it + if((action=='quick_move'||slotinventory_shape, //shape of the inventory, copied from above + 'title'->gui_screen:'title', //Fancy GUI title + 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits + gui_page=gui_screen:global_pages:(gui_screen:global_main_page); + for(gui_page:global_static_buttons, + inventory_set(screen, _, 1, gui_page:global_static_buttons:_:0) + ); + for(gui_page:global_dynamic_buttons, + inventory_set(screen, _, 1, gui_page:global_dynamic_buttons:_:0) + ); + for(gui_page:global_storage_slots, + [item, count, nbt] = gui_page:global_storage_slots:_ || ['air', 0, null]; + inventory_set(screen, _, count, item, nbt) + ); + ), + 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( + gui_page=gui_screen:global_pages:(gui_screen:global_main_page); + slot = data:'slot'; //Grabbing slot, this is the focus of the action + + if(action=='pickup', //This is equivalent of clicking (button action) + if(has(gui_page:global_static_buttons, slot), //Plain, vanilla button + call(gui_page:global_static_buttons:slot:1, player, data:'button'), + has(gui_page:global_dynamic_buttons, slot), //A more exciting button + call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button') + ); + ); + + //Saving items in storage slots when closing + if(action=='close', + for(gui_page:global_storage_slots, + gui_page:global_storage_slots:_ = inventory_get(screen, _); + ); + ); + + //Disabling quick move cos it messes up the GUI, and there's no reason to allow it + //Also preventing the player from tampering with button slots + //Unless the slot is marked as a storage slot, in which case we allow it + if((action=='quick_move'||slot( //Opens the screen to the player, returns screen for further manipulation screen = create_screen(player, gui_menu:'inventory_shape', gui_menu:'title', gui_menu:'callback'); - call(gui_menu:'on_created', screen); + call(gui_menu:'on_created', screen), screen ); From 2a6b8783dc47dd6e383e9c1ffd609a96491c59fe Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Sun, 9 Apr 2023 16:42:06 +0200 Subject: [PATCH 11/35] Added page switching funcionality Multi-page GUIs are now separate from regular GUIs --- programs/fundamentals/gui_menu.sc | 170 ++++++++++++++---------------- 1 file changed, 82 insertions(+), 88 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 0af2f88b..d02c06b3 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -1,10 +1,15 @@ __on_player_swings_hand(player, hand)-> ( - if(hand=='mainhand' && player~'holds':0=='brewing_stand', - call_gui_menu(global_Test_GUI, player) + item = player~'holds':0; + if(hand=='mainhand', + if(item=='brewing_stand', + call_gui_menu(global_Test_GUI, player), + item=='stick', + call_gui_menu(global_Test_pages_GUI, player) + ) ) ); - + //Config global_inventory_sizes={ @@ -24,6 +29,7 @@ global_storage_slots='storage_slots'; global_pages='pages'; global_main_page='main_page_title'; global_current_page='current_page'; +global_page_switcher='change_page_buttons'; global_Test={ 'inventory_shape'->'generic_3x3', @@ -65,6 +71,9 @@ global_Test_pages={ global_storage_slots->{ //These slots can be used for storage by the player 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot 5, 2 //leaving this blank makes the slot blank + }, + global_page_switcher->{ + 3->['cyan_stained_glass', 'second_page'] } }, 'second_page'->{ @@ -81,6 +90,9 @@ global_Test_pages={ ) ], }, + global_page_switcher->{ + 4->['cyan_stained_glass', 'main_page'] + } } } }; @@ -98,102 +110,84 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p throw('Invalid gui creation: Must be one of '+keys(global_inventory_sizes)+', not '+inventory_shape) ); - if(!has(gui_screen, global_pages), //If there is no page functionality - { - 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above - 'title'->gui_screen:'title', //Fancy GUI title - 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits - for(gui_screen:global_static_buttons, - inventory_set(screen, _, 1, gui_screen:global_static_buttons:_:0) - ); - for(gui_screen:global_dynamic_buttons, - inventory_set(screen, _, 1, gui_screen:global_dynamic_buttons:_:0) - ); - for(gui_screen:global_storage_slots, - [item, count, nbt] = gui_screen:global_storage_slots:_ || ['air', 0, null]; - inventory_set(screen, _, count, item, nbt) - ); - ), - 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->(//This is where most of the action happens - slot = data:'slot'; //Grabbing slot, this is the focus of the action - - if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_screen:global_static_buttons, slot), //Plain, vanilla button - call(gui_screen:global_static_buttons:slot:1, player, data:'button'), - has(gui_screen:global_dynamic_buttons, slot), //A more exciting button - call(gui_screen:global_dynamic_buttons:slot:1, screen, player, data:'button') - ); - ); - - //Saving items in storage slots when closing - if(action=='close', - for(gui_screen:global_storage_slots, - gui_screen:global_storage_slots:_ = inventory_get(screen, _); - ); - ); - - //Disabling quick move cos it messes up the GUI, and there's no reason to allow it - //Also preventing the player from tampering with button slots - //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slotinventory_shape, //shape of the inventory, copied from above - 'title'->gui_screen:'title', //Fancy GUI title - 'on_created'->_(screen, outer(gui_screen))->(// Fiddling with the screen after it's made to add fancy visual bits - gui_page=gui_screen:global_pages:(gui_screen:global_main_page); - for(gui_page:global_static_buttons, - inventory_set(screen, _, 1, gui_page:global_static_buttons:_:0) - ); - for(gui_page:global_dynamic_buttons, - inventory_set(screen, _, 1, gui_page:global_dynamic_buttons:_:0) - ); - for(gui_page:global_storage_slots, - [item, count, nbt] = gui_page:global_storage_slots:_ || ['air', 0, null]; - inventory_set(screen, _, count, item, nbt) - ); - ), - 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( - gui_page=gui_screen:global_pages:(gui_screen:global_main_page); - slot = data:'slot'; //Grabbing slot, this is the focus of the action - - if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_page:global_static_buttons, slot), //Plain, vanilla button - call(gui_page:global_static_buttons:slot:1, player, data:'button'), - has(gui_page:global_dynamic_buttons, slot), //A more exciting button - call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button') - ); - ); + if(has(gui_screen, global_pages) && !has(gui_screen:global_pages, gui_screen:global_main_page), + throw('Tried to create a GUI Menu, but did not find a main page with the name '+gui_screen:global_main_page) + ); - //Saving items in storage slots when closing - if(action=='close', - for(gui_page:global_storage_slots, + gui_screen:global_current_page = gui_screen:global_main_page; + + { + 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above + 'title'->gui_screen:'title', //Fancy GUI title + 'on_created'->_(screen, outer(gui_screen))->__create_gui_screen(screen, gui_screen), + 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( + gui_page=if(has(gui_screen, global_pages), + gui_screen:global_pages:(gui_screen:global_current_page), + gui_screen //If there is no page functionality, just use the screen map as the page + ); + + slot = data:'slot'; //Grabbing slot, this is the focus of the action + + if(action=='pickup', //This is equivalent of clicking (button action) + if(has(gui_page:global_static_buttons, slot), //Plain, vanilla button + call(gui_page:global_static_buttons:slot:1, player, data:'button'), + has(gui_page:global_dynamic_buttons, slot), //A more exciting button + call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button'), + has(gui_page:global_page_switcher, slot), //Switching screens + gui_screen:global_current_page = gui_page:global_page_switcher:slot:1; + for(gui_page:global_storage_slots, //Saving storage slots when switching screens gui_page:global_storage_slots:_ = inventory_get(screen, _); ); + loop(inventory_size, //Clearing inventory before switching + inventory_set(screen, _, 0) + ); + __create_gui_screen(screen, gui_screen) ); + ); - //Disabling quick move cos it messes up the GUI, and there's no reason to allow it - //Also preventing the player from tampering with button slots - //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slot( //Opens the screen to the player, returns screen for further manipulation screen = create_screen(player, gui_menu:'inventory_shape', gui_menu:'title', gui_menu:'callback'); - call(gui_menu:'on_created', screen), + call(gui_menu:'on_created', screen); screen ); +__create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right after it's made to add fancy visual bits + gui_page=if(has(gui_screen, global_pages), + gui_screen:global_pages:(gui_screen:global_current_page), + gui_screen //If there is no page functionality, just use the screen map as the page + ); + for(gui_page:global_static_buttons, + inventory_set(screen, _, 1, gui_page:global_static_buttons:_:0) + ); + for(gui_page:global_dynamic_buttons, + inventory_set(screen, _, 1, gui_page:global_dynamic_buttons:_:0) + ); + for(gui_page:global_storage_slots, + [item, count, nbt] = gui_page:global_storage_slots:_ || ['air', 0, null]; + inventory_set(screen, _, count, item, nbt) + ); + for(gui_page:global_page_switcher, + inventory_set(screen, _, 1, gui_page:global_page_switcher:_:0) + ); +); + + global_Test_GUI = new_gui_menu(global_Test); +global_Test_pages_GUI = new_gui_menu(global_Test_pages); From 7f965b821584e4acda65831d005d4330657b5fd4 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 10:32:28 +0200 Subject: [PATCH 12/35] Added ability for different pages to have different titles Also moved screen callback to separate function --- programs/fundamentals/gui_menu.sc | 116 +++++++++++++++++++----------- 1 file changed, 74 insertions(+), 42 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index d02c06b3..e058269f 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -64,6 +64,7 @@ global_Test_pages={ global_current_page->null, global_pages->{ 'main_page'->{ + 'title'->format('cb Test GUI menu first page!'), global_static_buttons->{ 0->['red_stained_glass_pane', _(player, button)->print(player, 'Pressed the red button!')], 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] @@ -77,6 +78,7 @@ global_Test_pages={ } }, 'second_page'->{ + 'title'->format('c Test GUI menu second page'), global_dynamic_buttons->{ 1->[ //Blue button to black button 'blue_stained_glass_pane', @@ -118,46 +120,10 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p { 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above - 'title'->gui_screen:'title', //Fancy GUI title + 'title'->__get_screen_title(gui_screen), //Fancy GUI title 'on_created'->_(screen, outer(gui_screen))->__create_gui_screen(screen, gui_screen), 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( - gui_page=if(has(gui_screen, global_pages), - gui_screen:global_pages:(gui_screen:global_current_page), - gui_screen //If there is no page functionality, just use the screen map as the page - ); - - slot = data:'slot'; //Grabbing slot, this is the focus of the action - - if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_page:global_static_buttons, slot), //Plain, vanilla button - call(gui_page:global_static_buttons:slot:1, player, data:'button'), - has(gui_page:global_dynamic_buttons, slot), //A more exciting button - call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button'), - has(gui_page:global_page_switcher, slot), //Switching screens - gui_screen:global_current_page = gui_page:global_page_switcher:slot:1; - for(gui_page:global_storage_slots, //Saving storage slots when switching screens - gui_page:global_storage_slots:_ = inventory_get(screen, _); - ); - loop(inventory_size, //Clearing inventory before switching - inventory_set(screen, _, 0) - ); - __create_gui_screen(screen, gui_screen) - ); - ); - - //Saving items in storage slots when closing - if(action=='close', - for(gui_page:global_storage_slots, - gui_page:global_storage_slots:_ = inventory_get(screen, _); - ); - ); - - //Disabling quick move cos it messes up the GUI, and there's no reason to allow it - //Also preventing the player from tampering with button slots - //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slot( //Opens the screen to the player, returns scr ); __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right after it's made to add fancy visual bits - gui_page=if(has(gui_screen, global_pages), - gui_screen:global_pages:(gui_screen:global_current_page), - gui_screen //If there is no page functionality, just use the screen map as the page - ); + gui_page=__get_gui_page(gui_screen); + for(gui_page:global_static_buttons, inventory_set(screen, _, 1, gui_page:global_static_buttons:_:0) ); @@ -188,6 +152,74 @@ __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right afte ); ); +__screen_callback(screen, player, action, data, gui_screen, inventory_size)->( + gui_page=__get_gui_page(gui_screen); + + slot = data:'slot'; //Grabbing slot, this is the focus of the action + + if(action=='pickup', //This is equivalent of clicking (button action) + if(has(gui_page:global_static_buttons, slot), //Plain, vanilla button + call(gui_page:global_static_buttons:slot:1, player, data:'button'), + has(gui_page:global_dynamic_buttons, slot), //A more exciting button + call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button'), + has(gui_page:global_page_switcher, slot), //Switching screens + gui_screen:global_current_page = gui_page:global_page_switcher:slot:1; + for(gui_page:global_storage_slots, //Saving storage slots when switching screens + gui_page:global_storage_slots:_ = inventory_get(screen, _); + ); + loop(inventory_size, //Clearing inventory before switching + inventory_set(screen, _, 0) + ); + close_screen(screen); + new_screen = create_screen(player, gui_screen:'inventory_shape', __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( + __screen_callback(screen, player, action, data, gui_screen, inventory_size) + )); + __create_gui_screen(new_screen, gui_screen) + ); + ); + + //Saving items in storage slots when closing + if(action=='close', + for(gui_page:global_storage_slots, + gui_page:global_storage_slots:_ = inventory_get(screen, _); + ); + ); + + //Disabling quick move cos it messes up the GUI, and there's no reason to allow it + //Also preventing the player from tampering with button slots + //Unless the slot is marked as a storage slot, in which case we allow it + if((action=='quick_move'||slotif(has(gui_screen, global_pages), + gui_screen:global_pages:(gui_screen:global_current_page), + gui_screen +); + + +//Gets the title for the current page of the screen. +//A title within the page gets first priority, if not, then use the title defined in the outermost map, +//And if that is not there, then the same title as the main page. +//And failing that, throw an error +__get_screen_title(gui_screen)->( + gui_page=__get_gui_page(gui_screen); + + if(!has(gui_screen, global_pages), + gui_screen:'title', + has(gui_page, 'title'), + gui_page:'title', + has(gui_screen, 'title'), + gui_screen:'title', + has(gui_screen:global_pages:(gui_screen:global_main_page), 'title'), + gui_screen:global_pages:(gui_screen:global_main_page):'title', + throw('No title defined!') + ) +); + global_Test_GUI = new_gui_menu(global_Test); global_Test_pages_GUI = new_gui_menu(global_Test_pages); From e07d2fbc8c6e67b13684e641982b39e2d30909c4 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 10:37:56 +0200 Subject: [PATCH 13/35] Different pages can have different inventory sizes! --- programs/fundamentals/gui_menu.sc | 35 +++++++++++++++++++++++-------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index e058269f..387c2750 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -29,7 +29,7 @@ global_storage_slots='storage_slots'; global_pages='pages'; global_main_page='main_page_title'; global_current_page='current_page'; -global_page_switcher='change_page_buttons'; +global_page_switcher='navigation_buttons'; global_Test={ 'inventory_shape'->'generic_3x3', @@ -79,6 +79,7 @@ global_Test_pages={ }, 'second_page'->{ 'title'->format('c Test GUI menu second page'), + 'inventory_shape'->'generic_9x3', global_dynamic_buttons->{ 1->[ //Blue button to black button 'blue_stained_glass_pane', @@ -104,13 +105,7 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p throw('Invalid gui creation: '+gui_screen) ); - inventory_shape = gui_screen:'inventory_shape'; - - inventory_size = global_inventory_sizes:inventory_shape; - - if(inventory_size==0, - throw('Invalid gui creation: Must be one of '+keys(global_inventory_sizes)+', not '+inventory_shape) - ); + inventory_shape = __get_screen_shape(gui_screen); if(has(gui_screen, global_pages) && !has(gui_screen:global_pages, gui_screen:global_main_page), throw('Tried to create a GUI Menu, but did not find a main page with the name '+gui_screen:global_main_page) @@ -171,7 +166,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( inventory_set(screen, _, 0) ); close_screen(screen); - new_screen = create_screen(player, gui_screen:'inventory_shape', __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( + new_screen = create_screen(player, __get_screen_shape(gui_screen), __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( __screen_callback(screen, player, action, data, gui_screen, inventory_size) )); __create_gui_screen(new_screen, gui_screen) @@ -220,6 +215,28 @@ __get_screen_title(gui_screen)->( ) ); +//Same as above, but for inventory shapes +__get_screen_shape(gui_screen)->( + gui_page=__get_gui_page(gui_screen); + + inventory_shape = if(!has(gui_screen, global_pages), + gui_screen:'inventory_shape', + has(gui_page, 'inventory_shape'), + gui_page:'inventory_shape', + has(gui_screen, 'inventory_shape'), + gui_screen:'inventory_shape', + has(gui_screen:global_pages:(gui_screen:global_main_page), 'inventory_shape'), + gui_screen:global_pages:(gui_screen:global_main_page):'inventory_shape', + throw('No GUI shape defined!') + ); + + inventory_size = global_inventory_sizes:inventory_shape; + + if(!inventory_size, + throw('Invalid gui creation: Must be one of '+keys(global_inventory_sizes)+', not '+inventory_shape) + ); + inventory_shape +); global_Test_GUI = new_gui_menu(global_Test); global_Test_pages_GUI = new_gui_menu(global_Test_pages); From f1647e8aaeda68c7383db0b71cea23d83f528281 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 11:27:10 +0200 Subject: [PATCH 14/35] Fixed bug which allowed player to mess up screen --- programs/fundamentals/gui_menu.sc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 387c2750..c60d0de4 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -106,6 +106,7 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p ); inventory_shape = __get_screen_shape(gui_screen); + inventory_size = global_inventory_sizes:inventory_shape; if(has(gui_screen, global_pages) && !has(gui_screen:global_pages, gui_screen:global_main_page), throw('Tried to create a GUI Menu, but did not find a main page with the name '+gui_screen:global_main_page) @@ -230,9 +231,7 @@ __get_screen_shape(gui_screen)->( throw('No GUI shape defined!') ); - inventory_size = global_inventory_sizes:inventory_shape; - - if(!inventory_size, + if(!has(global_inventory_sizes, inventory_shape), throw('Invalid gui creation: Must be one of '+keys(global_inventory_sizes)+', not '+inventory_shape) ); inventory_shape From a65370de8f0aa37fa904f7d36a820e23174859c2 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 11:32:59 +0200 Subject: [PATCH 15/35] Added button labels --- programs/fundamentals/gui_menu.sc | 37 ++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index c60d0de4..50b4dca1 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -45,7 +45,7 @@ global_Test={ ], 6->[ //Turns the slot above purple - 'lime_stained_glass_pane', + ['lime_stained_glass_pane', 'Flicky!'], _(screen, player, button)->( inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); ) @@ -86,10 +86,10 @@ global_Test_pages={ _(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); ], - 6->[ //Turns the slot above purple - 'lime_stained_glass_pane', + 6->[ //Turns the slot below purple + ['lime_stained_glass_pane', 'Flicky!'], _(screen, player, button)->( - inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); + inventory_set(screen, 15, 1, if(inventory_get(screen, 15)==null, 'purple_stained_glass_pane', 'air')); ) ], }, @@ -132,19 +132,21 @@ call_gui_menu(gui_menu, player)->( //Opens the screen to the player, returns scr __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right after it's made to add fancy visual bits gui_page=__get_gui_page(gui_screen); - for(gui_page:global_static_buttons, - inventory_set(screen, _, 1, gui_page:global_static_buttons:_:0) + [item, count, nbt] = __parse_icon(gui_page:global_static_buttons:_:0); + inventory_set(screen, _, count, item, nbt) ); for(gui_page:global_dynamic_buttons, - inventory_set(screen, _, 1, gui_page:global_dynamic_buttons:_:0) + [item, count, nbt] = __parse_icon(gui_page:global_dynamic_buttons:_:0); + inventory_set(screen, _, count, item, nbt) ); for(gui_page:global_storage_slots, [item, count, nbt] = gui_page:global_storage_slots:_ || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); for(gui_page:global_page_switcher, - inventory_set(screen, _, 1, gui_page:global_page_switcher:_:0) + [item, count, nbt] = __parse_icon(gui_page:global_page_switcher:_:0); + inventory_set(screen, _, count, item, nbt) ); ); @@ -237,5 +239,24 @@ __get_screen_shape(gui_screen)->( inventory_shape ); +//Parses the item used as slot icon +//If it's a string, returns [item_name, 1, null], +//If it's a list of length 2, second item is the name of the item +//If it's a triplet, then return that (making the assumption that it's a triplet of [item, count, nbt]) +//IF it's a list of length 4, first three arguments are [item, count, nbt], fourth is item name. +__parse_icon(icon)->if(type(icon)=='string', + [icon, 1, null], + type(icon)=='list', + if(length(icon)==2, + [icon:0, 1, str('{display:{Name:\'{"text":"%s"}\'}}', icon:1)], + length(icon)==3, + icon, + length(icon)==4, + icon:2 = icon:2 || nbt({}); //JIC input nbt was null + put(icon:2, 'display', nbt(str('{display:{Name:\'{"text":"%s"}\'}}', icon:1))); + icon + ) +); + global_Test_GUI = new_gui_menu(global_Test); global_Test_pages_GUI = new_gui_menu(global_Test_pages); From 1703bef5d4fb50538a2a7f31f4ef0c50b51a4a97 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 14:21:14 +0200 Subject: [PATCH 16/35] Fixed bug causing incorrect inventory shape opened incase of nondefault page shape --- programs/fundamentals/gui_menu.sc | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.sc index 50b4dca1..20b0fbc1 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.sc @@ -79,7 +79,7 @@ global_Test_pages={ }, 'second_page'->{ 'title'->format('c Test GUI menu second page'), - 'inventory_shape'->'generic_9x3', + 'inventory_shape'->'generic_9x2', global_dynamic_buttons->{ 1->[ //Blue button to black button 'blue_stained_glass_pane', @@ -101,31 +101,28 @@ global_Test_pages={ }; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function - if(type(gui_screen)!='map' || !has(gui_screen, 'inventory_shape'), + if(type(gui_screen)!='map', throw('Invalid gui creation: '+gui_screen) ); - inventory_shape = __get_screen_shape(gui_screen); - inventory_size = global_inventory_sizes:inventory_shape; - if(has(gui_screen, global_pages) && !has(gui_screen:global_pages, gui_screen:global_main_page), - throw('Tried to create a GUI Menu, but did not find a main page with the name '+gui_screen:global_main_page) + throw('Tried to create a GUI Menu with page functionality, but did not find a main page with the name '+gui_screen:global_main_page) ); gui_screen:global_current_page = gui_screen:global_main_page; { - 'inventory_shape'->inventory_shape, //shape of the inventory, copied from above + 'inventory_shape'->_(outer(gui_screen))->__get_screen_shape(gui_screen), //shape of the inventory, copied from above 'title'->__get_screen_title(gui_screen), //Fancy GUI title 'on_created'->_(screen, outer(gui_screen))->__create_gui_screen(screen, gui_screen), - 'callback'->_(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( - __screen_callback(screen, player, action, data, gui_screen, inventory_size) + 'callback'->_(screen, player, action, data, outer(gui_screen))->( + __screen_callback(screen, player, action, data, gui_screen, global_inventory_sizes:__get_screen_shape(gui_screen)) ), } ); call_gui_menu(gui_menu, player)->( //Opens the screen to the player, returns screen for further manipulation - screen = create_screen(player, gui_menu:'inventory_shape', gui_menu:'title', gui_menu:'callback'); + screen = create_screen(player, call(gui_menu:'inventory_shape'), gui_menu:'title', gui_menu:'callback'); call(gui_menu:'on_created', screen); screen ); @@ -169,8 +166,8 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( inventory_set(screen, _, 0) ); close_screen(screen); - new_screen = create_screen(player, __get_screen_shape(gui_screen), __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen), outer(inventory_size))->( - __screen_callback(screen, player, action, data, gui_screen, inventory_size) + new_screen = create_screen(player, __get_screen_shape(gui_screen), __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen))->( + __screen_callback(screen, player, action, data, gui_screen, global_inventory_sizes:__get_screen_shape(gui_screen)) )); __create_gui_screen(new_screen, gui_screen) ); From ac8801622b491285727adb716087feafe0bb79d8 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 17:28:29 +0200 Subject: [PATCH 17/35] Renaming to .scl and removing testing stuff --- .../{gui_menu.sc => gui_menu.scl} | 102 ++++-------------- 1 file changed, 18 insertions(+), 84 deletions(-) rename programs/fundamentals/{gui_menu.sc => gui_menu.scl} (66%) diff --git a/programs/fundamentals/gui_menu.sc b/programs/fundamentals/gui_menu.scl similarity index 66% rename from programs/fundamentals/gui_menu.sc rename to programs/fundamentals/gui_menu.scl index 20b0fbc1..c41c55f7 100644 --- a/programs/fundamentals/gui_menu.sc +++ b/programs/fundamentals/gui_menu.scl @@ -1,25 +1,31 @@ -__on_player_swings_hand(player, hand)-> ( - item = player~'holds':0; - if(hand=='mainhand', - if(item=='brewing_stand', - call_gui_menu(global_Test_GUI, player), - item=='stick', - call_gui_menu(global_Test_pages_GUI, player) - ) - ) -); - //Config global_inventory_sizes={ + 'anvil'->3, + 'beacon'->1, + 'blast_furnace'->3, + 'brewing_stand'->5, + 'cartography_table'->3, + 'crafting'->10, + 'enchantment'->2, + 'furnace'->3, 'generic_3x3'->9, 'generic_9x1'->9, 'generic_9x2'->18, 'generic_9x3'->27, 'generic_9x4'->36, 'generic_9x5'->45, - 'generic_9x6'->54 + 'generic_9x6'->54, + 'grindstone'->3 + 'hopper'->5, + 'lectern'->1, + 'loom'->4, + 'merchant'->3, + 'shulker_box'->27, + 'smithing'->4 + 'smoker'->3, + 'stonecutter'->2, }; //Certain names are subject to change, so instead I'll store them in global variables while I'm still fiddling with exact nomenclature @@ -31,75 +37,6 @@ global_main_page='main_page_title'; global_current_page='current_page'; global_page_switcher='navigation_buttons'; -global_Test={ - 'inventory_shape'->'generic_3x3', - 'title'->format('db Test GUI menu!'), - global_static_buttons->{ - 0->['red_stained_glass_pane', _(player, button)->print(player, 'Pressed the red button!')], - 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] - }, - global_dynamic_buttons->{ - 1->[ //Blue button to black button - 'blue_stained_glass_pane', - _(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); - ], - - 6->[ //Turns the slot above purple - ['lime_stained_glass_pane', 'Flicky!'], - _(screen, player, button)->( - inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); - ) - ], - }, - global_storage_slots->{ //These slots can be used for storage by the player - 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot - 5, 2 //leaving this blank makes the slot blank - } -}; - -global_Test_pages={ - 'inventory_shape'->'generic_3x3', - 'title'->format('db Test GUI with pages!'), - global_main_page->'main_page', - global_current_page->null, - global_pages->{ - 'main_page'->{ - 'title'->format('cb Test GUI menu first page!'), - global_static_buttons->{ - 0->['red_stained_glass_pane', _(player, button)->print(player, 'Pressed the red button!')], - 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] - }, - global_storage_slots->{ //These slots can be used for storage by the player - 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot - 5, 2 //leaving this blank makes the slot blank - }, - global_page_switcher->{ - 3->['cyan_stained_glass', 'second_page'] - } - }, - 'second_page'->{ - 'title'->format('c Test GUI menu second page'), - 'inventory_shape'->'generic_9x2', - global_dynamic_buttons->{ - 1->[ //Blue button to black button - 'blue_stained_glass_pane', - _(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); - ], - - 6->[ //Turns the slot below purple - ['lime_stained_glass_pane', 'Flicky!'], - _(screen, player, button)->( - inventory_set(screen, 15, 1, if(inventory_get(screen, 15)==null, 'purple_stained_glass_pane', 'air')); - ) - ], - }, - global_page_switcher->{ - 4->['cyan_stained_glass', 'main_page'] - } - } - } -}; - new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', throw('Invalid gui creation: '+gui_screen) @@ -254,6 +191,3 @@ __parse_icon(icon)->if(type(icon)=='string', icon ) ); - -global_Test_GUI = new_gui_menu(global_Test); -global_Test_pages_GUI = new_gui_menu(global_Test_pages); From 19d4ebc25a910337bca7adaa9e94733241a40ab0 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 17:38:37 +0200 Subject: [PATCH 18/35] Added ability to have all types of gui screen --- programs/fundamentals/gui_menu.scl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index c41c55f7..03ce74c6 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -17,13 +17,13 @@ global_inventory_sizes={ 'generic_9x4'->36, 'generic_9x5'->45, 'generic_9x6'->54, - 'grindstone'->3 + 'grindstone'->3, 'hopper'->5, 'lectern'->1, 'loom'->4, 'merchant'->3, 'shulker_box'->27, - 'smithing'->4 + 'smithing'->4, 'smoker'->3, 'stonecutter'->2, }; From cb0ac79d8550e39a3eb0652786178950c3875c64 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 19:32:06 +0200 Subject: [PATCH 19/35] Added callback for anvil GUI modification --- programs/fundamentals/gui_menu.scl | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 03ce74c6..8a25b9d3 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -36,6 +36,7 @@ global_pages='pages'; global_main_page='main_page_title'; global_current_page='current_page'; global_page_switcher='navigation_buttons'; +global_anvil_rename_item='anvil_rename_item'; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', @@ -110,6 +111,16 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ); ); + //Special effects for special GUI types + inventory_shape = __get_screen_shape(gui_screen); + if(inventory_shape == 'anvil', + if(has(gui_page, global_anvil_rename_item) && action=='slot_update' && slot==2 && has(data, 'stack'), + call(gui_page:global_anvil_rename_item, player, item_display_name(data:'stack')) + ), + + ); + + //Saving items in storage slots when closing if(action=='close', for(gui_page:global_storage_slots, From ffa42d0ac73f8498c15844f818dc12bad7ea85de Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 20:02:23 +0200 Subject: [PATCH 20/35] Giving more info with anvil item modification --- programs/fundamentals/gui_menu.scl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 8a25b9d3..39172f11 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -36,7 +36,7 @@ global_pages='pages'; global_main_page='main_page_title'; global_current_page='current_page'; global_page_switcher='navigation_buttons'; -global_anvil_rename_item='anvil_rename_item'; +global_anvil_rename_item='anvil_modify_item'; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', @@ -114,10 +114,10 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( //Special effects for special GUI types inventory_shape = __get_screen_shape(gui_screen); if(inventory_shape == 'anvil', - if(has(gui_page, global_anvil_rename_item) && action=='slot_update' && slot==2 && has(data, 'stack'), - call(gui_page:global_anvil_rename_item, player, item_display_name(data:'stack')) + if(has(gui_page, global_anvil_rename_item) && action=='slot_update' && slot==2 && has(data, 'stack') && data:'stack', + call(gui_page:global_anvil_rename_item, player, item_display_name(data:'stack'), screen_property(screen, 'level_cost')) ), - + ); From 18f1dbfb363c6ddda88384fad8e6e3236f103254 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 10 Apr 2023 21:10:41 +0200 Subject: [PATCH 21/35] Added select_recipe events --- programs/fundamentals/gui_menu.scl | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 39172f11..252b579e 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -36,7 +36,8 @@ global_pages='pages'; global_main_page='main_page_title'; global_current_page='current_page'; global_page_switcher='navigation_buttons'; -global_anvil_rename_item='anvil_modify_item'; +global_anvil_rename_item='on_anvil_modify_item'; +global_crafting_recipe_select='on_select_crafting_recipe'; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', @@ -115,9 +116,12 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( inventory_shape = __get_screen_shape(gui_screen); if(inventory_shape == 'anvil', if(has(gui_page, global_anvil_rename_item) && action=='slot_update' && slot==2 && has(data, 'stack') && data:'stack', - call(gui_page:global_anvil_rename_item, player, item_display_name(data:'stack'), screen_property(screen, 'level_cost')) + call(gui_page:global_anvil_rename_item, player, screen, item_display_name(data:'stack'), screen_property(screen, 'level_cost')) ), - + has({'crafting_table', 'furnace', 'blast_furnace', 'smoker'}, inventory_shape), //If it is an inventory with green crafting book item in GUI + if(has(gui_page, global_crafting_recipe_select) && action=='select_recipe', + call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') + ) ); From f484d7b7d8fd75dd5d5ab66bde25012146b6880c Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Tue, 11 Apr 2023 09:18:43 +0200 Subject: [PATCH 22/35] Added dynamic slots --- programs/fundamentals/gui_menu.scl | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 252b579e..217c2863 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -32,6 +32,7 @@ global_inventory_sizes={ global_static_buttons='static_buttons'; global_dynamic_buttons='dynamic_buttons'; global_storage_slots='storage_slots'; +global_dynamic_slots='dynamic_slots'; global_pages='pages'; global_main_page='main_page_title'; global_current_page='current_page'; @@ -121,7 +122,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( has({'crafting_table', 'furnace', 'blast_furnace', 'smoker'}, inventory_shape), //If it is an inventory with green crafting book item in GUI if(has(gui_page, global_crafting_recipe_select) && action=='select_recipe', call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') - ) + ), ); @@ -132,10 +133,14 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ); ); + if(action=='slot_update' && has(gui_page:global_dynamic_slots,slot), //Updating dynamic slots + call(gui_page:global_dynamic_slots:slot:1, player, screen, slot, data:'stack') + ); + //Disabling quick move cos it messes up the GUI, and there's no reason to allow it //Also preventing the player from tampering with button slots //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slot Date: Tue, 11 Apr 2023 09:49:15 +0200 Subject: [PATCH 23/35] Added additional screen callback for programmers --- programs/fundamentals/gui_menu.scl | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 217c2863..814a9ebe 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -34,6 +34,7 @@ global_dynamic_buttons='dynamic_buttons'; global_storage_slots='storage_slots'; global_dynamic_slots='dynamic_slots'; global_pages='pages'; +global_additional_screen_callback='additional_screen_callback'; global_main_page='main_page_title'; global_current_page='current_page'; global_page_switcher='navigation_buttons'; @@ -113,6 +114,10 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ); ); + if(action=='slot_update' && has(gui_page:global_dynamic_slots,slot), //Updating dynamic slots + call(gui_page:global_dynamic_slots:slot:1, player, screen, slot, data:'stack') + ); + //Special effects for special GUI types inventory_shape = __get_screen_shape(gui_screen); if(inventory_shape == 'anvil', @@ -123,8 +128,8 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( if(has(gui_page, global_crafting_recipe_select) && action=='select_recipe', call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') ), - ); + ); //Saving items in storage slots when closing if(action=='close', @@ -133,14 +138,16 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ); ); - if(action=='slot_update' && has(gui_page:global_dynamic_slots,slot), //Updating dynamic slots - call(gui_page:global_dynamic_slots:slot:1, player, screen, slot, data:'stack') + cb = ''; //allowing programmer to cancel event in additional screen callback function + + if(has(gui_page, global_additional_screen_callback), + cb = call(gui_page:global_additional_screen_callback, screen, player, action, data, gui_screen) ); //Disabling quick move cos it messes up the GUI, and there's no reason to allow it //Also preventing the player from tampering with button slots //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slot Date: Tue, 11 Apr 2023 09:59:08 +0200 Subject: [PATCH 24/35] Added loom pattern selection --- programs/fundamentals/gui_menu.scl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 814a9ebe..4f7b3a37 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -40,6 +40,7 @@ global_current_page='current_page'; global_page_switcher='navigation_buttons'; global_anvil_rename_item='on_anvil_modify_item'; global_crafting_recipe_select='on_select_crafting_recipe'; +global_loom_pattern_select='on_select_banner_pattern'; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', @@ -128,7 +129,10 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( if(has(gui_page, global_crafting_recipe_select) && action=='select_recipe', call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') ), - + inventory_shape=='loom', + if(has(gui_page, global_loom_pattern_select) && action=='button', + call(gui_page:global_loom_pattern_select, player, screen, data:'button') + ) ); //Saving items in storage slots when closing From 8767362a6dd91d04bd6ec8c544b1cf24b08bd07f Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Tue, 11 Apr 2023 10:53:01 +0200 Subject: [PATCH 25/35] Added stonecutter and loom functionality --- programs/fundamentals/gui_menu.scl | 33 +++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 4f7b3a37..b0a1b8d3 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -41,6 +41,8 @@ global_page_switcher='navigation_buttons'; global_anvil_rename_item='on_anvil_modify_item'; global_crafting_recipe_select='on_select_crafting_recipe'; global_loom_pattern_select='on_select_banner_pattern'; +global_stonecutter_pattern_select='on_select_stonecutting_pattern'; + new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', @@ -130,8 +132,28 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') ), inventory_shape=='loom', - if(has(gui_page, global_loom_pattern_select) && action=='button', - call(gui_page:global_loom_pattern_select, player, screen, data:'button') + if(has(gui_page, global_loom_pattern_select), + if(action=='button', + global_action_cache={ + 'data'->data, + 'active'->true + }, + global_action_cache:'active' && action=='slot_update', + call(gui_page:global_loom_pattern_select, player, screen, global_action_cache:'data':'button', parse_nbt(data:'stack':2):'BlockEntityTag':'Patterns':(-1):'Pattern'); + global_action_cache:'active'=false + ) + ), + inventory_shape=='stonecutter', + if(has(gui_page, global_stonecutter_pattern_select), + if(action=='button', + global_action_cache={ + 'data'->data, + 'active'->true + }, + global_action_cache:'active' && action=='slot_update', + call(gui_page:global_stonecutter_pattern_select, player, screen, global_action_cache:'data':'button', data:'stack'); + global_action_cache:'active'=false + ) ) ); @@ -151,11 +173,16 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( //Disabling quick move cos it messes up the GUI, and there's no reason to allow it //Also preventing the player from tampering with button slots //Unless the slot is marked as a storage slot, in which case we allow it - if((action=='quick_move'||slotnull, + 'active'->false +}; //If gui supports page functionality, returns current page, else returns the gui screen __get_gui_page(gui_screen)->if(has(gui_screen, global_pages), From f11babf7b72df1ded20d6c57d30837950ebf2ce2 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Tue, 11 Apr 2023 11:22:09 +0200 Subject: [PATCH 26/35] Extracted page switching to new function --- programs/fundamentals/gui_menu.scl | 44 +++++++++++++++++++----------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index b0a1b8d3..664f5aa6 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -85,6 +85,10 @@ __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right afte [item, count, nbt] = gui_page:global_storage_slots:_ || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); + for(gui_page:global_dynamic_slots, + [item, count, nbt] = gui_page:global_dynamic_slots:_:0 || ['air', 0, null]; + inventory_set(screen, _, count, item, nbt) + ); for(gui_page:global_page_switcher, [item, count, nbt] = __parse_icon(gui_page:global_page_switcher:_:0); inventory_set(screen, _, count, item, nbt) @@ -102,18 +106,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( has(gui_page:global_dynamic_buttons, slot), //A more exciting button call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button'), has(gui_page:global_page_switcher, slot), //Switching screens - gui_screen:global_current_page = gui_page:global_page_switcher:slot:1; - for(gui_page:global_storage_slots, //Saving storage slots when switching screens - gui_page:global_storage_slots:_ = inventory_get(screen, _); - ); - loop(inventory_size, //Clearing inventory before switching - inventory_set(screen, _, 0) - ); - close_screen(screen); - new_screen = create_screen(player, __get_screen_shape(gui_screen), __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen))->( - __screen_callback(screen, player, action, data, gui_screen, global_inventory_sizes:__get_screen_shape(gui_screen)) - )); - __create_gui_screen(new_screen, gui_screen) + __switch_page(gui_screen, gui_page, gui_page:global_page_switcher:slot:1, screen, player) ); ); @@ -164,17 +157,18 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ); ); - cb = ''; //allowing programmer to cancel event in additional screen callback function + acb = ''; //allowing programmer to cancel event in additional screen callback function if(has(gui_page, global_additional_screen_callback), - cb = call(gui_page:global_additional_screen_callback, screen, player, action, data, gui_screen) + acb = call(gui_page:global_additional_screen_callback, screen, player, action, data, gui_screen) ); //Disabling quick move cos it messes up the GUI, and there's no reason to allow it //Also preventing the player from tampering with button slots //Unless the slot is marked as a storage slot, in which case we allow it - //Also unless the action is a button click, cos those could have other knock-on effects which we don't wanna cancel - if((action=='quick_move'||slotif(type(icon)=='string', icon ) ); + +__switch_page(gui_screen, gui_page, new_page_name, old_screen, player)->( + gui_screen:global_current_page = new_page_name; //Changing current page + for(gui_page:global_storage_slots, //Saving storage slots when switching screens + gui_page:global_storage_slots:_ = inventory_get(old_screen, _); + ); + for(gui_page:global_dynamic_slots, //Saving dynamic slots when switching screens + gui_page:global_dynamic_slots:_:0 = inventory_get(old_screen, _); + ); + loop(inventory_size, //Clearing inventory before switching + inventory_set(old_screen, _, 0) + ); + close_screen(old_screen); + new_screen = create_screen(player, __get_screen_shape(gui_screen), __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen))->( + __screen_callback(screen, player, action, data, gui_screen, global_inventory_sizes:__get_screen_shape(gui_screen)) + )); + __create_gui_screen(new_screen, gui_screen) +); From c905785ca498991d075c8d535a59ab822038ddcc Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Tue, 11 Apr 2023 11:53:10 +0200 Subject: [PATCH 27/35] Added lectern button detection --- programs/fundamentals/gui_menu.scl | 31 +++++++++++++++++++++--------- 1 file changed, 22 insertions(+), 9 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 664f5aa6..06b17b24 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -42,6 +42,8 @@ global_anvil_rename_item='on_anvil_modify_item'; global_crafting_recipe_select='on_select_crafting_recipe'; global_loom_pattern_select='on_select_banner_pattern'; global_stonecutter_pattern_select='on_select_stonecutting_pattern'; +global_lectern_flip_page='on_flip_page'; +global_lectern_take_book='on_take_book'; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function @@ -72,7 +74,7 @@ call_gui_menu(gui_menu, player)->( //Opens the screen to the player, returns scr ); __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right after it's made to add fancy visual bits - gui_page=__get_gui_page(gui_screen); + gui_page=_get_gui_page(gui_screen); for(gui_page:global_static_buttons, [item, count, nbt] = __parse_icon(gui_page:global_static_buttons:_:0); inventory_set(screen, _, count, item, nbt) @@ -96,7 +98,7 @@ __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right afte ); __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( - gui_page=__get_gui_page(gui_screen); + gui_page=_get_gui_page(gui_screen); slot = data:'slot'; //Grabbing slot, this is the focus of the action @@ -106,7 +108,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( has(gui_page:global_dynamic_buttons, slot), //A more exciting button call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button'), has(gui_page:global_page_switcher, slot), //Switching screens - __switch_page(gui_screen, gui_page, gui_page:global_page_switcher:slot:1, screen, player) + _switch_page(gui_screen, gui_page, gui_page:global_page_switcher:slot:1, screen, player) ); ); @@ -124,6 +126,17 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( if(has(gui_page, global_crafting_recipe_select) && action=='select_recipe', call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') ), + inventory_shape=='lectern', + if(action=='button', + button = data:'button'; + if(has(gui_page, global_lectern_take_book) && button==3, + call(gui_page:global_lectern_take_book, player, screen) + ); + if(has(gui_page, global_lectern_flip_page) && button < 3, + page = screen_property(screen, 'page'); + call(gui_page:global_lectern_flip_page, player, screen, button, 2*button-3+page) //This looks silly, but the page number is not immediately updated, so I modify it instead + ) + ), inventory_shape=='loom', if(has(gui_page, global_loom_pattern_select), if(action=='button', @@ -166,9 +179,9 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( //Disabling quick move cos it messes up the GUI, and there's no reason to allow it //Also preventing the player from tampering with button slots //Unless the slot is marked as a storage slot, in which case we allow it - //Also unless the action cache is active, in which case we're listening for any feedback which will get lost if we cancel + //Also unless the action is clicking a button within the GUI, cos it has useful functionality //But if the programmer decided to cancel event using the additional screen callback, it will be cancelled regardless - if((action=='quick_move'||slotif(has(gui_screen, global_pages), +_get_gui_page(gui_screen)->if(has(gui_screen, global_pages), gui_screen:global_pages:(gui_screen:global_current_page), gui_screen ); @@ -190,7 +203,7 @@ __get_gui_page(gui_screen)->if(has(gui_screen, global_pages), //And if that is not there, then the same title as the main page. //And failing that, throw an error __get_screen_title(gui_screen)->( - gui_page=__get_gui_page(gui_screen); + gui_page=_get_gui_page(gui_screen); if(!has(gui_screen, global_pages), gui_screen:'title', @@ -206,7 +219,7 @@ __get_screen_title(gui_screen)->( //Same as above, but for inventory shapes __get_screen_shape(gui_screen)->( - gui_page=__get_gui_page(gui_screen); + gui_page=_get_gui_page(gui_screen); inventory_shape = if(!has(gui_screen, global_pages), gui_screen:'inventory_shape', @@ -244,7 +257,7 @@ __parse_icon(icon)->if(type(icon)=='string', ) ); -__switch_page(gui_screen, gui_page, new_page_name, old_screen, player)->( +_switch_page(gui_screen, gui_page, new_page_name, old_screen, player)->( gui_screen:global_current_page = new_page_name; //Changing current page for(gui_page:global_storage_slots, //Saving storage slots when switching screens gui_page:global_storage_slots:_ = inventory_get(old_screen, _); From 4086355727a5d359634ee67238eb7e3ccb6650ce Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Tue, 11 Apr 2023 13:21:17 +0200 Subject: [PATCH 28/35] Fixing bug with dynamic slots --- programs/fundamentals/gui_menu.scl | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 06b17b24..c0e0614f 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -1,7 +1,7 @@ //Config -global_inventory_sizes={ +global_inventory_sizes={ //cos inventory_size() function doesn't work properly with sone of these 'anvil'->3, 'beacon'->1, 'blast_furnace'->3, @@ -163,11 +163,14 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ) ); - //Saving items in storage slots when closing + //Saving items in storage and dynamic slots when closing if(action=='close', for(gui_page:global_storage_slots, gui_page:global_storage_slots:_ = inventory_get(screen, _); ); + for(gui_page:global_dynamic_slots, + gui_page:global_dynamic_slots:_:0 = inventory_get(screen, _); + ); ); acb = ''; //allowing programmer to cancel event in additional screen callback function From 55810ce4d50a7fb0570a91f4498d4d6fa17a7a71 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Fri, 23 Jun 2023 13:32:08 +0530 Subject: [PATCH 29/35] Added enchantment table function --- programs/fundamentals/gui_menu.scl | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index c0e0614f..9d8e195f 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -44,6 +44,7 @@ global_loom_pattern_select='on_select_banner_pattern'; global_stonecutter_pattern_select='on_select_stonecutting_pattern'; global_lectern_flip_page='on_flip_page'; global_lectern_take_book='on_take_book'; +global_enchanting_table_enchantment_select='on_select_enchantment'; new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function @@ -160,7 +161,25 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( call(gui_page:global_stonecutter_pattern_select, player, screen, global_action_cache:'data':'button', data:'stack'); global_action_cache:'active'=false ) - ) + ), + inventory_shape=='enchantment',//global_enchanting_table_enchantment_select + if(has(gui_page, global_enchanting_table_enchantment_select), + if(action=='button', + global_action_cache={ + 'data'->data, + 'active'->true + }, + global_action_cache:'active' && action=='slot_update', + button = global_action_cache:'data':'button' + 1; + call(gui_page:global_enchanting_table_enchantment_select, + player, screen, + screen_property(screen, 'enchantment_power_'+button), + screen_property(screen, 'enchantment_id_'+button), + screen_property(screen, 'enchantment_level_'+button), + ); + global_action_cache:'active'=false + ) + ), ); //Saving items in storage and dynamic slots when closing From 89c43965e83ca7c152eb2aae9f7f23b7a4b8fb62 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Fri, 23 Jun 2023 15:25:24 +0530 Subject: [PATCH 30/35] Removed name placeholders --- programs/fundamentals/gui_menu.scl | 134 +++++++++++++---------------- 1 file changed, 59 insertions(+), 75 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 9d8e195f..1c0ae7dd 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -28,35 +28,16 @@ global_inventory_sizes={ //cos inventory_size() function doesn't work properly w 'stonecutter'->2, }; -//Certain names are subject to change, so instead I'll store them in global variables while I'm still fiddling with exact nomenclature -global_static_buttons='static_buttons'; -global_dynamic_buttons='dynamic_buttons'; -global_storage_slots='storage_slots'; -global_dynamic_slots='dynamic_slots'; -global_pages='pages'; -global_additional_screen_callback='additional_screen_callback'; -global_main_page='main_page_title'; -global_current_page='current_page'; -global_page_switcher='navigation_buttons'; -global_anvil_rename_item='on_anvil_modify_item'; -global_crafting_recipe_select='on_select_crafting_recipe'; -global_loom_pattern_select='on_select_banner_pattern'; -global_stonecutter_pattern_select='on_select_stonecutting_pattern'; -global_lectern_flip_page='on_flip_page'; -global_lectern_take_book='on_take_book'; -global_enchanting_table_enchantment_select='on_select_enchantment'; - - new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function if(type(gui_screen)!='map', throw('Invalid gui creation: '+gui_screen) ); - if(has(gui_screen, global_pages) && !has(gui_screen:global_pages, gui_screen:global_main_page), - throw('Tried to create a GUI Menu with page functionality, but did not find a main page with the name '+gui_screen:global_main_page) + if(has(gui_screen, 'pages') && !has(gui_screen:'pages', gui_screen:'main_page_title'), + throw('Tried to create a GUI Menu with page functionality, but did not find a main page with the name '+gui_screen:'main_page_title') ); - gui_screen:global_current_page = gui_screen:global_main_page; + gui_screen:'current_page' = gui_screen:'main_page_title'; { 'inventory_shape'->_(outer(gui_screen))->__get_screen_shape(gui_screen), //shape of the inventory, copied from above @@ -76,24 +57,24 @@ call_gui_menu(gui_menu, player)->( //Opens the screen to the player, returns scr __create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right after it's made to add fancy visual bits gui_page=_get_gui_page(gui_screen); - for(gui_page:global_static_buttons, - [item, count, nbt] = __parse_icon(gui_page:global_static_buttons:_:0); + for(gui_page:'static_buttons', + [item, count, nbt] = __parse_icon(gui_page:'static_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); - for(gui_page:global_dynamic_buttons, - [item, count, nbt] = __parse_icon(gui_page:global_dynamic_buttons:_:0); + for(gui_page:'dynamic_buttons', + [item, count, nbt] = __parse_icon(gui_page:'dynamic_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); - for(gui_page:global_storage_slots, - [item, count, nbt] = gui_page:global_storage_slots:_ || ['air', 0, null]; + for(gui_page:'storage_slots', + [item, count, nbt] = gui_page:'storage_slots':_ || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); - for(gui_page:global_dynamic_slots, - [item, count, nbt] = gui_page:global_dynamic_slots:_:0 || ['air', 0, null]; + for(gui_page:'dynamic_storage_slots', + [item, count, nbt] = gui_page:'dynamic_storage_slots':_:0 || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); - for(gui_page:global_page_switcher, - [item, count, nbt] = __parse_icon(gui_page:global_page_switcher:_:0); + for(gui_page:'navigation_buttons', + [item, count, nbt] = __parse_icon(gui_page:'navigation_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); ); @@ -104,66 +85,69 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( slot = data:'slot'; //Grabbing slot, this is the focus of the action if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_page:global_static_buttons, slot), //Plain, vanilla button - call(gui_page:global_static_buttons:slot:1, player, data:'button'), - has(gui_page:global_dynamic_buttons, slot), //A more exciting button - call(gui_page:global_dynamic_buttons:slot:1, screen, player, data:'button'), - has(gui_page:global_page_switcher, slot), //Switching screens - _switch_page(gui_screen, gui_page, gui_page:global_page_switcher:slot:1, screen, player) + if(has(gui_page:'static_buttons', slot), //Plain, vanilla button + call(gui_page:'static_buttons':slot:1, player, data:'button'), + has(gui_page:'dynamic_buttons', slot), //A more exciting button + call(gui_page:'dynamic_buttons':slot:1, screen, player, data:'button'), + has(gui_page:'navigation_buttons', slot), //Switching screens + _switch_page(gui_screen, gui_page, gui_page:'navigation_buttons':slot:1, screen, player) ); ); - if(action=='slot_update' && has(gui_page:global_dynamic_slots,slot), //Updating dynamic slots - call(gui_page:global_dynamic_slots:slot:1, player, screen, slot, data:'stack') + if(action=='slot_update' && has(gui_page:'dynamic_storage_slots',slot), //Updating dynamic slots + call(gui_page:'dynamic_storage_slots':slot:1, player, screen, slot, data:'stack') ); //Special effects for special GUI types + //Could have used handle_event() and custom events API, but these events are tied into gui_menu.scl script + //Risk of usin events API is that programmer might try to use the events in an incorrect manner, causing problems + //And it's not like it simplifies the code much on either end tbh. inventory_shape = __get_screen_shape(gui_screen); if(inventory_shape == 'anvil', - if(has(gui_page, global_anvil_rename_item) && action=='slot_update' && slot==2 && has(data, 'stack') && data:'stack', - call(gui_page:global_anvil_rename_item, player, screen, item_display_name(data:'stack'), screen_property(screen, 'level_cost')) + if(has(gui_page, 'on_anvil_modify_item') && action=='slot_update' && slot==2 && has(data, 'stack') && data:'stack', + call(gui_page:'on_anvil_modify_item', player, screen, item_display_name(data:'stack'), screen_property(screen, 'level_cost')) ), has({'crafting_table', 'furnace', 'blast_furnace', 'smoker'}, inventory_shape), //If it is an inventory with green crafting book item in GUI - if(has(gui_page, global_crafting_recipe_select) && action=='select_recipe', - call(gui_page:global_crafting_recipe_select, player, screen, data:'recipe', data:'craft_all') + if(has(gui_page, 'on_select_crafting_recipe') && action=='select_recipe', + call(gui_page:'on_select_crafting_recipe', player, screen, data:'recipe', data:'craft_all') ), inventory_shape=='lectern', if(action=='button', button = data:'button'; - if(has(gui_page, global_lectern_take_book) && button==3, - call(gui_page:global_lectern_take_book, player, screen) + if(has(gui_page, 'on_take_book') && button==3, + call(gui_page:'on_take_book', player, screen) ); - if(has(gui_page, global_lectern_flip_page) && button < 3, + if(has(gui_page, 'on_flip_page') && button < 3, page = screen_property(screen, 'page'); - call(gui_page:global_lectern_flip_page, player, screen, button, 2*button-3+page) //This looks silly, but the page number is not immediately updated, so I modify it instead + call(gui_page:'on_flip_page', player, screen, button, 2*button-3+page) //This looks silly, but the page number is not immediately updated, so I modify it instead ) ), inventory_shape=='loom', - if(has(gui_page, global_loom_pattern_select), + if(has(gui_page, 'on_select_banner_pattern'), if(action=='button', global_action_cache={ 'data'->data, 'active'->true }, global_action_cache:'active' && action=='slot_update', - call(gui_page:global_loom_pattern_select, player, screen, global_action_cache:'data':'button', parse_nbt(data:'stack':2):'BlockEntityTag':'Patterns':(-1):'Pattern'); + call(gui_page:'on_select_banner_pattern', player, screen, global_action_cache:'data':'button', parse_nbt(data:'stack':2):'BlockEntityTag':'Patterns':(-1):'Pattern'); global_action_cache:'active'=false ) ), inventory_shape=='stonecutter', - if(has(gui_page, global_stonecutter_pattern_select), + if(has(gui_page, 'on_select_stonecutting_pattern'), if(action=='button', global_action_cache={ 'data'->data, 'active'->true }, global_action_cache:'active' && action=='slot_update', - call(gui_page:global_stonecutter_pattern_select, player, screen, global_action_cache:'data':'button', data:'stack'); + call(gui_page:'on_select_stonecutting_pattern', player, screen, global_action_cache:'data':'button', data:'stack'); global_action_cache:'active'=false ) ), - inventory_shape=='enchantment',//global_enchanting_table_enchantment_select - if(has(gui_page, global_enchanting_table_enchantment_select), + inventory_shape=='enchantment',//'on_select_enchantment' + if(has(gui_page, 'on_select_enchantment'), if(action=='button', global_action_cache={ 'data'->data, @@ -171,7 +155,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( }, global_action_cache:'active' && action=='slot_update', button = global_action_cache:'data':'button' + 1; - call(gui_page:global_enchanting_table_enchantment_select, + call(gui_page:'on_select_enchantment', player, screen, screen_property(screen, 'enchantment_power_'+button), screen_property(screen, 'enchantment_id_'+button), @@ -184,18 +168,18 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( //Saving items in storage and dynamic slots when closing if(action=='close', - for(gui_page:global_storage_slots, - gui_page:global_storage_slots:_ = inventory_get(screen, _); + for(gui_page:'storage_slots', + gui_page:'storage_slots':_ = inventory_get(screen, _); ); - for(gui_page:global_dynamic_slots, - gui_page:global_dynamic_slots:_:0 = inventory_get(screen, _); + for(gui_page:'dynamic_storage_slots', + gui_page:'dynamic_storage_slots':_:0 = inventory_get(screen, _); ); ); acb = ''; //allowing programmer to cancel event in additional screen callback function - if(has(gui_page, global_additional_screen_callback), - acb = call(gui_page:global_additional_screen_callback, screen, player, action, data, gui_screen) + if(has(gui_page, 'additional_screen_callback'), + acb = call(gui_page:'additional_screen_callback', screen, player, action, data, gui_screen) ); //Disabling quick move cos it messes up the GUI, and there's no reason to allow it @@ -203,7 +187,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( //Unless the slot is marked as a storage slot, in which case we allow it //Also unless the action is clicking a button within the GUI, cos it has useful functionality //But if the programmer decided to cancel event using the additional screen callback, it will be cancelled regardless - if((action=='quick_move'||slotif(has(gui_screen, global_pages), - gui_screen:global_pages:(gui_screen:global_current_page), +_get_gui_page(gui_screen)->if(has(gui_screen, 'pages'), + gui_screen:'pages':(gui_screen:'current_page'), gui_screen ); @@ -227,14 +211,14 @@ _get_gui_page(gui_screen)->if(has(gui_screen, global_pages), __get_screen_title(gui_screen)->( gui_page=_get_gui_page(gui_screen); - if(!has(gui_screen, global_pages), + if(!has(gui_screen, 'pages'), gui_screen:'title', has(gui_page, 'title'), gui_page:'title', has(gui_screen, 'title'), gui_screen:'title', - has(gui_screen:global_pages:(gui_screen:global_main_page), 'title'), - gui_screen:global_pages:(gui_screen:global_main_page):'title', + has(gui_screen:'pages':(gui_screen:'main_page_title'), 'title'), + gui_screen:'pages':(gui_screen:'main_page_title'):'title', throw('No title defined!') ) ); @@ -243,14 +227,14 @@ __get_screen_title(gui_screen)->( __get_screen_shape(gui_screen)->( gui_page=_get_gui_page(gui_screen); - inventory_shape = if(!has(gui_screen, global_pages), + inventory_shape = if(!has(gui_screen, 'pages'), gui_screen:'inventory_shape', has(gui_page, 'inventory_shape'), gui_page:'inventory_shape', has(gui_screen, 'inventory_shape'), gui_screen:'inventory_shape', - has(gui_screen:global_pages:(gui_screen:global_main_page), 'inventory_shape'), - gui_screen:global_pages:(gui_screen:global_main_page):'inventory_shape', + has(gui_screen:'pages':(gui_screen:'main_page_title'), 'inventory_shape'), + gui_screen:'pages':(gui_screen:'main_page_title'):'inventory_shape', throw('No GUI shape defined!') ); @@ -280,12 +264,12 @@ __parse_icon(icon)->if(type(icon)=='string', ); _switch_page(gui_screen, gui_page, new_page_name, old_screen, player)->( - gui_screen:global_current_page = new_page_name; //Changing current page - for(gui_page:global_storage_slots, //Saving storage slots when switching screens - gui_page:global_storage_slots:_ = inventory_get(old_screen, _); + gui_screen:'current_page' = new_page_name; //Changing current page + for(gui_page:'storage_slots', //Saving storage slots when switching screens + gui_page:'storage_slots':_ = inventory_get(old_screen, _); ); - for(gui_page:global_dynamic_slots, //Saving dynamic slots when switching screens - gui_page:global_dynamic_slots:_:0 = inventory_get(old_screen, _); + for(gui_page:'dynamic_storage_slots', //Saving dynamic slots when switching screens + gui_page:'dynamic_storage_slots':_:0 = inventory_get(old_screen, _); ); loop(inventory_size, //Clearing inventory before switching inventory_set(old_screen, _, 0) From 8c18bd032090a4c003a8129e72fb1e139d673012 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 26 Jun 2023 20:49:59 +0100 Subject: [PATCH 31/35] Added descriptive documentation --- programs/fundamentals/gui_menu.scl | 86 +++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 25 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 1c0ae7dd..f57bb68b 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -1,7 +1,7 @@ //Config -global_inventory_sizes={ //cos inventory_size() function doesn't work properly with sone of these +global_inventory_sizes={ //cos inventory_size() function doesn't work properly with some of these 'anvil'->3, 'beacon'->1, 'blast_furnace'->3, @@ -28,13 +28,17 @@ global_inventory_sizes={ //cos inventory_size() function doesn't work properly w 'stonecutter'->2, }; -new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function +//Stores GUI data in intermediary map form, so the programmer can call them at any time with call_gui_menu() function +//Using call_gui_menu(map) will modify the map itself, so it's a good idea to store it as a global variable +//This way, if items are stored in the inventory, they won't be lost +//Even if no items are stored, storing the map returned by this function will help avoid excessive recomputations when re-generating the same GUI +new_gui_menu(gui_screen)->( if(type(gui_screen)!='map', throw('Invalid gui creation: '+gui_screen) ); if(has(gui_screen, 'pages') && !has(gui_screen:'pages', gui_screen:'main_page_title'), - throw('Tried to create a GUI Menu with page functionality, but did not find a main page with the name '+gui_screen:'main_page_title') + throw('Tried to create a GUI Menu with page functionality, but did not find a main page with the title '+gui_screen:'main_page_title') ); gui_screen:'current_page' = gui_screen:'main_page_title'; @@ -42,75 +46,84 @@ new_gui_menu(gui_screen)->( //Stores GUI data in intermediary map form, so the p { 'inventory_shape'->_(outer(gui_screen))->__get_screen_shape(gui_screen), //shape of the inventory, copied from above 'title'->__get_screen_title(gui_screen), //Fancy GUI title - 'on_created'->_(screen, outer(gui_screen))->__create_gui_screen(screen, gui_screen), + 'on_created'->_(screen, player, outer(gui_screen))->__create_gui_screen(screen, player, gui_screen), 'callback'->_(screen, player, action, data, outer(gui_screen))->( __screen_callback(screen, player, action, data, gui_screen, global_inventory_sizes:__get_screen_shape(gui_screen)) ), } ); +//Takes a map returned by the new_gui_menu() function, and interprets it as a gui menu, opening it up to the player +//This function also initialises all the special functions of the gui menu, such as button presses etc. call_gui_menu(gui_menu, player)->( //Opens the screen to the player, returns screen for further manipulation screen = create_screen(player, call(gui_menu:'inventory_shape'), gui_menu:'title', gui_menu:'callback'); - call(gui_menu:'on_created', screen); + call(gui_menu:'on_created', screen, player); screen ); -__create_gui_screen(screen, gui_screen)->(// Fiddling with the screen right after it's made to add fancy visual bits +// Fiddling with the screen right after it's made to add fancy visual bits and run initialisation +__create_gui_screen(screen, player, gui_screen)->( gui_page=_get_gui_page(gui_screen); - for(gui_page:'static_buttons', + for(gui_page:'static_buttons', // Setting the icon for static buttons [item, count, nbt] = __parse_icon(gui_page:'static_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); - for(gui_page:'dynamic_buttons', + for(gui_page:'dynamic_buttons', // Setting the icon for dynamic buttons [item, count, nbt] = __parse_icon(gui_page:'dynamic_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); - for(gui_page:'storage_slots', + for(gui_page:'storage_slots', // Setting the initial item for storage slots, or nothing if undefined [item, count, nbt] = gui_page:'storage_slots':_ || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); - for(gui_page:'dynamic_storage_slots', + for(gui_page:'dynamic_storage_slots', // Setting the initial item for dynamic storage slots, or nothing if undefined [item, count, nbt] = gui_page:'dynamic_storage_slots':_:0 || ['air', 0, null]; inventory_set(screen, _, count, item, nbt) ); - for(gui_page:'navigation_buttons', + for(gui_page:'navigation_buttons', // Setting the icon for navigation buttons [item, count, nbt] = __parse_icon(gui_page:'navigation_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); ); + +//This is the function called whenever a gui_menu screen is updated. It's chonky, but runs pretty fast. +//It's well optimized so it only does what it has to, with no runtime wasted on useless checks and operations. __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( gui_page=_get_gui_page(gui_screen); slot = data:'slot'; //Grabbing slot, this is the focus of the action - if(action=='pickup', //This is equivalent of clicking (button action) - if(has(gui_page:'static_buttons', slot), //Plain, vanilla button + if(action=='pickup', //This is equivalent of clicking (button action) on a slot, which may have been marked as a special slot + if(has(gui_page:'static_buttons', slot), //Plain, vanilla button, pressing of which can call another action call(gui_page:'static_buttons':slot:1, player, data:'button'), - has(gui_page:'dynamic_buttons', slot), //A more exciting button + has(gui_page:'dynamic_buttons', slot), //A more exciting button, which can modify this inventory itself call(gui_page:'dynamic_buttons':slot:1, screen, player, data:'button'), - has(gui_page:'navigation_buttons', slot), //Switching screens + has(gui_page:'navigation_buttons', slot), //Switching screens to a predetermined new page _switch_page(gui_screen, gui_page, gui_page:'navigation_buttons':slot:1, screen, player) ); ); - if(action=='slot_update' && has(gui_page:'dynamic_storage_slots',slot), //Updating dynamic slots + if(action=='slot_update' && has(gui_page:'dynamic_storage_slots',slot), //Updating dynamic storage slots whenever anything happens to them. call(gui_page:'dynamic_storage_slots':slot:1, player, screen, slot, data:'stack') ); //Special effects for special GUI types //Could have used handle_event() and custom events API, but these events are tied into gui_menu.scl script - //Risk of usin events API is that programmer might try to use the events in an incorrect manner, causing problems + //Risk of using events API is that programmer might try to use the events in an incorrect manner, causing problems //And it's not like it simplifies the code much on either end tbh. inventory_shape = __get_screen_shape(gui_screen); - if(inventory_shape == 'anvil', + if(inventory_shape == 'anvil', // Calling 'on_anvil_modify_item' event whenever the player modifies an item using an anvil if(has(gui_page, 'on_anvil_modify_item') && action=='slot_update' && slot==2 && has(data, 'stack') && data:'stack', call(gui_page:'on_anvil_modify_item', player, screen, item_display_name(data:'stack'), screen_property(screen, 'level_cost')) ), - has({'crafting_table', 'furnace', 'blast_furnace', 'smoker'}, inventory_shape), //If it is an inventory with green crafting book item in GUI + // Calling 'on_select_crafting_recipe' event when player selects item in green crafting book + has({'crafting_table', 'furnace', 'blast_furnace', 'smoker'}, inventory_shape), if(has(gui_page, 'on_select_crafting_recipe') && action=='select_recipe', call(gui_page:'on_select_crafting_recipe', player, screen, data:'recipe', data:'craft_all') ), + // Calling 'on_take_book' when player pressed 'Take Book' button in lectern + // Calling 'on_flip_page' when player flips page in lectern inventory_shape=='lectern', if(action=='button', button = data:'button'; @@ -122,6 +135,11 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( call(gui_page:'on_flip_page', player, screen, button, 2*button-3+page) //This looks silly, but the page number is not immediately updated, so I modify it instead ) ), + // Calling 'on_select_banner_pattern' whenever player selects a banner pattern + //Action cache is used because data about which pattern was selected is given in the 'button' action + //But the 'slot_update' action is where the new banner is actually placed in the output slot. + //They happen back to back, and appear simultaneous, but internally they are not. + //See below for more details on action cache inventory_shape=='loom', if(has(gui_page, 'on_select_banner_pattern'), if(action=='button', @@ -134,6 +152,8 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( global_action_cache:'active'=false ) ), + // Calling 'on_select_stonecutting_pattern' when player selects stonecutter recipe + //Same as with loom, there is a separation between selecting recipe, and new item being placed in the output slot inventory_shape=='stonecutter', if(has(gui_page, 'on_select_stonecutting_pattern'), if(action=='button', @@ -146,7 +166,8 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( global_action_cache:'active'=false ) ), - inventory_shape=='enchantment',//'on_select_enchantment' + //'on_select_enchantment', TODO test this properly + inventory_shape=='enchantment', if(has(gui_page, 'on_select_enchantment'), if(action=='button', global_action_cache={ @@ -166,7 +187,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( ), ); - //Saving items in storage and dynamic slots when closing + //Saving items in storage slots and dynamic storage slots when closing the screen if(action=='close', for(gui_page:'storage_slots', gui_page:'storage_slots':_ = inventory_get(screen, _); @@ -184,7 +205,7 @@ __screen_callback(screen, player, action, data, gui_screen, inventory_size)->( //Disabling quick move cos it messes up the GUI, and there's no reason to allow it //Also preventing the player from tampering with button slots - //Unless the slot is marked as a storage slot, in which case we allow it + //Unless the slot is marked as a storage slot or dynamic storage slot, in which case we allow it //Also unless the action is clicking a button within the GUI, cos it has useful functionality //But if the programmer decided to cancel event using the additional screen callback, it will be cancelled regardless if((action=='quick_move'||slot( ); ); +//Action cache allows to store data efficiently and effectively between actions +//This is because sometimes a 'button' event will have later repercussions in a 'slot_update' action +//So we we want information from the 'button' event in the 'slot_update' action, hence the cache +//This basically just stores intermediary data, as well as information on whether or not it is active +//Technically, since the 'slot_update' action immediately follows the 'button' action, the flag is unnecessary +//But nice to have it in case something goes wrong. global_action_cache={ //Sometimes a slot_update with important information comes after the event that triggered it 'data'->null, 'active'->false }; -//If gui supports page functionality, returns current page, else returns the gui screen +//This function checks whether an input GUI screen (in map form) supports page functionality +//If so, it returns the current page, or elst jus the input GUI screen +//The current GUI page refers to the section where information about button layout and slot allocation is displayed _get_gui_page(gui_screen)->if(has(gui_screen, 'pages'), gui_screen:'pages':(gui_screen:'current_page'), gui_screen @@ -263,12 +292,19 @@ __parse_icon(icon)->if(type(icon)=='string', ) ); +//A simple function which allows to switch pages, used for all page-switching functionality, both within this script and outside +//If you want to switch page, import and use this function +//gui_screen argument refers to the big gui_screen map, a variable which should be accessible everywhere, and which contains all the data on the GUI screen +//gui_page refers to the current GUI page open, prior to switching of pages +//new_page_name is the name of the new page +//old_screen refers to the screen variable which corresponded to the old page, and is also accessible everywhere +//player is the player variable, used in the creation of screens. _switch_page(gui_screen, gui_page, new_page_name, old_screen, player)->( gui_screen:'current_page' = new_page_name; //Changing current page for(gui_page:'storage_slots', //Saving storage slots when switching screens gui_page:'storage_slots':_ = inventory_get(old_screen, _); ); - for(gui_page:'dynamic_storage_slots', //Saving dynamic slots when switching screens + for(gui_page:'dynamic_storage_slots', //Saving dynamic storage slots when switching screens gui_page:'dynamic_storage_slots':_:0 = inventory_get(old_screen, _); ); loop(inventory_size, //Clearing inventory before switching @@ -278,5 +314,5 @@ _switch_page(gui_screen, gui_page, new_page_name, old_screen, player)->( new_screen = create_screen(player, __get_screen_shape(gui_screen), __get_screen_title(gui_screen), _(screen, player, action, data, outer(gui_screen))->( __screen_callback(screen, player, action, data, gui_screen, global_inventory_sizes:__get_screen_shape(gui_screen)) )); - __create_gui_screen(new_screen, gui_screen) + __create_gui_screen(new_screen, player, gui_screen) ); From 79d297d4e3044d794ce0b482a29fa904800e4233 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 26 Jun 2023 20:50:14 +0100 Subject: [PATCH 32/35] Added on_init --- programs/fundamentals/gui_menu.scl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index f57bb68b..193f399b 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -84,6 +84,9 @@ __create_gui_screen(screen, player, gui_screen)->( [item, count, nbt] = __parse_icon(gui_page:'navigation_buttons':_:0); inventory_set(screen, _, count, item, nbt) ); + if(has(gui_page, 'on_init'), //Running programmer-defined page initialiser + call(gui_page:'on_init', screen, player) + ); ); From 438cfbdbfbad850872464f0b7a8bc96b4215fec4 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Mon, 26 Jun 2023 22:21:15 +0200 Subject: [PATCH 33/35] Create test_gui_menu.sc --- programs/fundamentals/test_gui_menu.sc | 229 +++++++++++++++++++++++++ 1 file changed, 229 insertions(+) create mode 100644 programs/fundamentals/test_gui_menu.sc diff --git a/programs/fundamentals/test_gui_menu.sc b/programs/fundamentals/test_gui_menu.sc new file mode 100644 index 00000000..dd54dbfc --- /dev/null +++ b/programs/fundamentals/test_gui_menu.sc @@ -0,0 +1,229 @@ +import('gui_menu', 'new_gui_menu', 'call_gui_menu', '_switch_page', '_get_gui_page'); + +__on_player_swings_hand(player, hand)-> ( + item = player~'holds':0; + if(hand=='mainhand', + if(item=='blaze_rod', + call_gui_menu(global_Test_GUI, player), + item=='stick', + call_gui_menu(global_Test_pages_GUI, player) + ) + ) +); + + +global_Test={ + 'inventory_shape'->'generic_3x3', + 'title'->format('db Test GUI menu!'), + 'static_buttons'->{ + 0->['red_stained_glass_pane', _(player, button)->print(player, 'Pressed the red button!')], + 4->['green_stained_glass_pane', _(player, button)->print(player, str('Clicked with %s button', if(button, 'Right', 'Left')))] + }, + 'dynamic_buttons'->{ + 1->[ //Blue button to black button + 'blue_stained_glass_pane', + _(screen, player, button)->inventory_set(screen, 1, 1, if(inventory_get(screen, 1):0=='blue_stained_glass_pane', 'black_stained_glass_pane', 'blue_stained_glass_pane')); + ], + + 6->[ //Turns the slot above purple + ['lime_stained_glass_pane', 'Flicky!'], + _(screen, player, button)->( + inventory_set(screen, 3, 1, if(inventory_get(screen, 3)==null, 'purple_stained_glass_pane', 'air')); + ) + ], + }, + 'storage_slots'->{ //These slots can be used for storage by the player + 8->['stone', 4, null], //This is simply the first item that will be available in the slot, it will subsequently be overwritten by whatever the player places in that slot + 5 //leaving this blank makes the slot blank + }, + 'dynamic_storage_slots'->{ //Whenever the slot is modified, call that function + 2->[[air, 0, null], _(player, screen, slot, item)->( + print(player, str('Modified slot %s, now holds %s', slot, item)) + )] + }, + 'additional_screen_callback'->_(screen, player, action, data, gui_screen)->if(data:'slot'==3, //Printing all actions in slot 3 + print(player, str('Action: %s, Data: %s', action, data)), + data:'slot'==7, //Cancelling all action in slot 7 + 'cancel' + ) +}; + +global_Test_pages={ + 'inventory_shape'->'generic_9x2', + 'title'->format('db Test GUI with pages!'), + 'main_page_title'->'main_page', + 'pages'->{ + 'main_page'->{ + 'title'->format('c Test GUI menu main page'), + 'navigation_buttons'->{ + 0->['anvil', 'anvil_page'], + 1->['beacon', 'beacon_page'], + 2->['blast_furnace', 'blast_furnace_page'], + 3->['brewing_stand', 'brewing_stand_page'], + 4->['cartography_table', 'cartography_table_page'], + 5->['crafting_table', 'crafting_page'], + 6->['enchanting_table', 'enchantment_page'], + 7->['furnace', 'furnace_page'], + 8->['grindstone', 'grindstone_page'], + 9->['hopper', 'hopper_page'], + 10->['lectern', 'lectern_page'], + 11->['loom', 'loom_page'], + 12->['emerald', 'merchant_page'], + 13->['shulker_box', 'shulker_box_page'], + 14->['smithing_table', 'smithing_page'], + 15->['smoker', 'smoker_page'], + 16->['stonecutter', 'stonecutter_page'], + } + }, + 'anvil_page'->{ + 'title'->format('c Test GUI menu anvil page'), + 'inventory_shape'->'anvil', + 'navigation_buttons'->{ + 1->['air', 'main_page'] + }, + 'on_init'->_(screen, player)->print(str('Screen %s, Player %s', screen, player)), + 'storage_slots'->{0, 2}, //Allows player to place item in first slot for renaming, and take modified item out of last slot + 'on_anvil_modify_item'->_(player, screen, item_name, repair_cost)->print(player, str('Renaming item to %s, costing %s levels', item_name, repair_cost)) + }, + 'beacon_page'->{ + 'title'->format('c Test GUI menu beacon page (hidden)'), //You don't see this title + 'inventory_shape'->'beacon', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'blast_furnace_page'->{ + 'title'->format('c Test GUI menu blast_furnace page'), + 'inventory_shape'->'blast_furnace', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'brewing_stand_page'->{ + 'title'->format('c Test GUI menu brewing_stand page'), + 'inventory_shape'->'brewing_stand', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'cartography_table_page'->{ + 'title'->format('c Test GUI menu cartography_table page'), + 'inventory_shape'->'cartography_table', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'crafting_page'->{ + 'title'->format('c Test GUI menu crafting page'), + 'inventory_shape'->'crafting', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + }, + 'on_select_crafting_recipe'->_(player, screen, recipe, craft_all)->print(player, str('Selected %s recipe, %s to craft all', recipe, if(craft_all, 'tried', 'did not try'))) + }, + 'enchantment_page'->{ + 'title'->format('c Test GUI menu enchantment page'), + 'inventory_shape'->'enchantment', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + }, + 'on_init'->_(screen, player)->( + print('Seed: '+screen_property(screen, 'enchantment_seed')); + screen_property(screen, 'enchantment_power_1', 3); + screen_property(screen, 'enchantment_id_1', 3); + screen_property(screen, 'enchantment_level_1', 3); + screen_property(screen, 'enchantment_power_2', 10); + screen_property(screen, 'enchantment_id_2', 0); + screen_property(screen, 'enchantment_level_2', 2); + screen_property(screen, 'enchantment_power_3', 6); + screen_property(screen, 'enchantment_id_3', 7); + screen_property(screen, 'enchantment_level_3', 1), + ), + 'on_select_enchantment'->_(screen, player, cost, enchantment_id, level)->print(player, str('Selected enchantment %s level %s, costing %s', enchantment_id, level, cost)) + }, + 'furnace_page'->{ + 'title'->format('c Test GUI menu furnace page'), + 'inventory_shape'->'furnace', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'grindstone_page'->{ + 'title'->format('c Test GUI menu grindstone page'), + 'inventory_shape'->'grindstone', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'hopper_page'->{ + 'title'->format('c Test GUI menu hopper page'), + 'inventory_shape'->'hopper', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'lectern_page'->{ + 'title'->format('c Test GUI menu lectern page (hidden)'), //You don't see this title + 'inventory_shape'->'lectern', + 'storage_slots'->{ //You can't interact with this slot in a lectern, but this is where the book goes + 0->['written_book', 1, encode_nbt({'title'->'-','author'->'-','pages'->['[{"text":"Hello World"}]','[{"text":"Hello Second Page"}]','[{"text":"Hello Third Page"}]',]})] + }, + 'on_flip_page'->_(player, screen, button, page)->print(player, str('Flipped %s to page %s', if(button==1, 'backwards', 'forwards'), page)), + 'on_take_book'->_(player, screen)->print(player, 'Took the book'), + + 'additional_screen_callback'->_(screen, player, action, data, gui_screen)->if(data:'button'==3, //Using Take Book button to switch back to main page without taking the book + _switch_page(gui_screen, _get_gui_page(gui_screen), 'main_page', screen, player); + 'cancel' + ) + }, + 'loom_page'->{ + 'title'->format('c Test GUI menu loom page'), + 'inventory_shape'->'loom', + 'navigation_buttons'->{ + 2->['air', 'main_page'] //Using banner pattern slot to switch back to main page + }, + 'storage_slots'->{0, 1, 3}, //allowing to put in a banner and dye and take out the output + 'on_select_banner_pattern'->_(player, screen, button, pattern)->print(player, str('Selected pattern %s: %s', button, pattern)) + }, + 'merchant_page'->{ + 'title'->format('c Test GUI menu merchant page'), + 'inventory_shape'->'merchant', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'shulker_box_page'->{ + 'title'->format('c Test GUI menu shulker_box page'), + 'inventory_shape'->'shulker_box', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'smithing_page'->{ + 'title'->format('c Test GUI menu smithing page'), + 'inventory_shape'->'smithing', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'smoker_page'->{ + 'title'->format('c Test GUI menu smoker page'), + 'inventory_shape'->'smoker', + 'navigation_buttons'->{ + 0->['air', 'main_page'] + } + }, + 'stonecutter_page'->{ + 'title'->format('c Test GUI menu stonecutter page'), + 'inventory_shape'->'stonecutter', + 'navigation_buttons'->{ //todo add different way to switch back to main page + //0->['air', 'main_page'] + }, + 'storage_slots'->{0, 1}, + 'on_select_stonecutting_pattern'->_(player, screen, button, pattern)->print(player, str('Selected pattern %s: %s', button, pattern)) + }, + } +}; + +global_Test_GUI = new_gui_menu(global_Test); +global_Test_pages_GUI = new_gui_menu(global_Test_pages); From 0f2d8b92c35754b8e1b4c9ed12dc214b0e27f8e4 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Thu, 3 Aug 2023 13:47:28 +0200 Subject: [PATCH 34/35] Added `on_select_crafting_recipe` event to furnace/blast furnace/smoker pages --- programs/fundamentals/test_gui_menu.sc | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/programs/fundamentals/test_gui_menu.sc b/programs/fundamentals/test_gui_menu.sc index dd54dbfc..3f2d01eb 100644 --- a/programs/fundamentals/test_gui_menu.sc +++ b/programs/fundamentals/test_gui_menu.sc @@ -58,12 +58,12 @@ global_Test_pages={ 'navigation_buttons'->{ 0->['anvil', 'anvil_page'], 1->['beacon', 'beacon_page'], - 2->['blast_furnace', 'blast_furnace_page'], + 2->['blast_', 'blast__page'], 3->['brewing_stand', 'brewing_stand_page'], 4->['cartography_table', 'cartography_table_page'], 5->['crafting_table', 'crafting_page'], 6->['enchanting_table', 'enchantment_page'], - 7->['furnace', 'furnace_page'], + 7->['', '_page'], 8->['grindstone', 'grindstone_page'], 9->['hopper', 'hopper_page'], 10->['lectern', 'lectern_page'], @@ -97,7 +97,8 @@ global_Test_pages={ 'inventory_shape'->'blast_furnace', 'navigation_buttons'->{ 0->['air', 'main_page'] - } + }, + 'on_select_crafting_recipe'->_(player, screen, recipe, craft_all)->print(player, str('Selected %s recipe, %s to craft all', recipe, if(craft_all, 'tried', 'did not try'))) }, 'brewing_stand_page'->{ 'title'->format('c Test GUI menu brewing_stand page'), @@ -146,7 +147,8 @@ global_Test_pages={ 'inventory_shape'->'furnace', 'navigation_buttons'->{ 0->['air', 'main_page'] - } + }, + 'on_select_crafting_recipe'->_(player, screen, recipe, craft_all)->print(player, str('Selected %s recipe, %s to craft all', recipe, if(craft_all, 'tried', 'did not try'))) }, 'grindstone_page'->{ 'title'->format('c Test GUI menu grindstone page'), @@ -211,7 +213,8 @@ global_Test_pages={ 'inventory_shape'->'smoker', 'navigation_buttons'->{ 0->['air', 'main_page'] - } + }, + 'on_select_crafting_recipe'->_(player, screen, recipe, craft_all)->print(player, str('Selected %s recipe, %s to craft all', recipe, if(craft_all, 'tried', 'did not try'))) }, 'stonecutter_page'->{ 'title'->format('c Test GUI menu stonecutter page'), From 6fac30427c0e89d60e346c94bb5ec0b030040b51 Mon Sep 17 00:00:00 2001 From: Ghoulboy Date: Sun, 10 Dec 2023 22:34:06 +0100 Subject: [PATCH 35/35] returning proper icon item array --- programs/fundamentals/gui_menu.scl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/programs/fundamentals/gui_menu.scl b/programs/fundamentals/gui_menu.scl index 193f399b..602b74ab 100644 --- a/programs/fundamentals/gui_menu.scl +++ b/programs/fundamentals/gui_menu.scl @@ -290,8 +290,8 @@ __parse_icon(icon)->if(type(icon)=='string', icon, length(icon)==4, icon:2 = icon:2 || nbt({}); //JIC input nbt was null - put(icon:2, 'display', nbt(str('{display:{Name:\'{"text":"%s"}\'}}', icon:1))); - icon + put(icon:2, 'display', nbt(str('{display:{Name:\'{"text":"%s"}\'}}', icon:3))); + [icon:0, icon:1, icon:2] ) );