Jump to content
  • 0

[Help with script] Create custom menu by user


Phenomena

Question


  • Group:  Members
  • Topic Count:  14
  • Topics Per Day:  0.00
  • Content Count:  94
  • Reputation:   4
  • Joined:  10/31/12
  • Last Seen:  

prontera,150,150,5	script	Testing01	100,{

	mes "Some text here...";
	next;
	switch( select( "Show current list", "Create/Add menu", "Cancel" ) ) {
		
		case 1:
		mes "This show current list of menu";
		/* In this part of script will be switch( select( LIST OF CURRENT MENU )) */
		close;
		
		case 2:
		mes "Please, input name of your menu";
		input .@input_name$;
		set .@my_menu$, .@input_name$;
		/* Store .@input_name$ in NPC Memory */
		close;
		
		case 3:
		close;
	}
}
/* So, when player create .@input_menu$, its store in NPC memory. Then, when he click on "Show current list" he see just created menu .@input_name$. Another player also can see menu .@input_name$ in list what was created by another player. */ 

Dear Scripting Community, i need you help in unrelesed script.

 

I will try to explane what my script must do:

1. Player start speaking with NPC, example Testing01

2. Player shows menu: "Current Menu List", "Create/Add Menu", "Cancel"

3. Player click on "Current Menu List", its empty because no one create menu

4. Then player click on "Create/Add Menu" and create one menu (only one menu player can create), for example "Test", maximum 10 custom menus

5. Then player click on "Current Menu List" and see only 1 created menu "Test"

6. Another player start speak with this NPC and he also see in "Current Menu List" menu "Test"

 

In script like this:

Link to comment
Share on other sites

3 answers to this question

Recommended Posts


  • Group:  Members
  • Topic Count:  31
  • Topics Per Day:  0.01
  • Content Count:  666
  • Reputation:   93
  • Joined:  04/27/12
  • Last Seen:  

That's easy to do however, what happens once that is done? What happens once all 10 slots are used up? What is available for selection in each ' custom ' menu?

 

A little bit further in detail would be nice. We understand the ' need ' to be obscure, because you don't want your ideas leaked, but keep in mind we can't provide adequate help without enough information :/

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  44
  • Reputation:   5
  • Joined:  12/06/11
  • Last Seen:  

You should read the 'menu' command doc ;)

*menu "<option_text>",<target_label>{,"<option_text>",<target_label>,...};

This command will create a selectable menu for the invoking character. Only one 
menu can be on screen at the same time.

Depending on what the player picks from the menu, the script execution will 
continue from the corresponding label. (it's string-label pairs, not label-
string)

Options can be grouped together, separated by the character ':'.

	menu "A:B",L_Wrong,"C",L_Right;

It also sets a special temporary character variable @menu, which contains the 
number of option the player picked. (Numbering of options starts at 1.)
This number is consistent with empty options and grouped options.

       menu "A::B",L_Wrong,"",L_Impossible,"C",L_Right;
    L_Wrong:
       // If they click "A" or "B" they will end up here
	   // @menu == 1 if "A"
	   // @menu == 2 will never happen because the option is empty
	   // @menu == 3 if "B"
	L_Impossible:
	   // Empty options are not displayed and therefore can't be selected
	   // this label will never be reached from the menu command
    L_Right:
       // If they click "C" they will end up here
	   // @menu == 5

If a label is '-', the script execution will continue right after the menu 
command if that option is selected, this can be used to save you time, and 
optimize big scripts.

        menu "A::B:",-,"C",L_Right;
        // If they click "A" or "B" they will end up here
		// @menu == 1 if "A"
		// @menu == 3 if "B"
    L_Right:
        // If they click "C" they will end up here
		// @menu == 5

Both these examples will perform the exact same task.

If you give an empty string as a menu item, the item will not display. This
can effectively be used to script dynamic menus by using empty string for
entries that should be unavailable at that time.

You can do it by using arrays, but watch carefully - this trick isn't high 
wizardry, but minor magic at least. You can't expect to easily duplicate it 
until you understand how it works.

Create a temporary array of strings to contain your menu items, and populate it 
with the strings that should go into the menu at this execution, making sure not 
to leave any gaps. Normally, you do it with a loop and an extra counter, like 
this:

	setarray @possiblemenuitems$[0],<list of potential menu items>;
	set @j,0; // That's the menu lines counter.
	
	// We loop through the list of possible menu items.
	// @i is our loop counter.
	for( set @i,0; @i<getarraysize(@possiblemenuitems$) ; set @i,@i+1 )
	{
		// That 'condition' is whatever condition that determines whether 
		// a menu item number @i actually goes into the menu or not.
		
		if (<condition>)
		{
			// We record the option into the list of options actually available.
			
			set @menulist$[@j],@possiblemenuitems$[@i];
			
			// We just copied the string, we do need its number for later 
			// though, so we record it as well.
			
			set @menureference[@j],@i;
			
			// Since we've just added a menu item into the list, we increment 
			// the menu lines counter.
			
			set @j,@j+1;
		}
		
		// We go on to the next possible menu item.
	}

This will create you an array @menulist$ which contains the text of all items 
that should actually go into the menu based on your condition, and an array 
@menureference, which contains their numbers in the list of possible menu items. 
(Remember, arrays start with 0.) There's less of them than the possible menu 
items you've defined, but the menu command can handle the empty lines - only if 
they are last in the list, and if it's made this way, they are. Now comes a 
dirty trick:

	// X is whatever the most menu items you expect to handle.
	menu @menulist$[0],-,@menulist$[1],-,....@menulist$[<X>],-;

This calls up a menu of all your items. Since you didn't copy some of the 
possible menu items into the list, its end is empty and so no menu items will 
show up past the end. But this menu call doesn't jump anywhere, it just 
continues execution right after the menu command. (And it's a good thing it 
doesn't, cause you can only explicitly define labels to jump to, and how do you 
know which ones to define if you don't know beforehand which options will end up 
where in your menu?)
But how do you figure out which option the user picked? Enter the @menu.

@menu contains the number of option that the user selected from the list, 
starting with 1 for the first option. You know now which option the user picked 
and which number in your real list of possible menu items it translated to:

    mes "You selected "+@possiblemenuitems$[@menureference[@menu-1]]+"!";

@menu is the number of option the user picked.
@menu-1 is the array index for the list of actually used menu items that we 
made.
@menureference[@menu-1] is the number of the item in the array of possible menu 
items that we've saved just for this purpose.

And @possiblemenuitems$[@menureference[@menu-1]] is the string that we used to 
display the menu line the user picked. (Yes, it's a handful, but it works.)

You can set up a bunch of 'if (@menureference[@menu-1]==X) goto Y' statements to 
route your execution based on the line selected and still generate a different 
menu every time, which is handy when you want to, for example, make users select 
items in any specific order before proceeding, or make a randomly shuffled menu.

Kafra code bundled with the standard distribution uses a similar array-based 
menu technique for teleport lists, but it's much simpler and doesn't use @menu, 
probably since that wasn't documented anywhere.

See also 'select', which is probably better in this particular case. Instead of 
menu, you could use 'select' like this:

    set @dummy,select(@menulist$[0],@menulist$[1],....@menulist$[<X>]);
    
For the purposes of the technique described above these two statements are 
perfectly equivalent.
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  14
  • Topics Per Day:  0.00
  • Content Count:  94
  • Reputation:   4
  • Joined:  10/31/12
  • Last Seen:  


prontera,150,150,5 script Testing01 100,{

mes "Welcome to Custom PvP Arena!";

next;

switch( select( "Show current list", "Create/Add arena", "Delete own arena", "Cancel" ) ) {

/* Current list of arenas */

case 1:

mes "This show current list of menu";

/* There will be 3 permanent arenas for public AND maximum 10 arenas created by players */

switch( select( "Public Arena#1 " + getmapusers("force_1-1") + " / 40", "Public Arena#2 " + getmapusers("force_1-2") + " / 40", "IF EXIST - Players custom created Arena#1 - Arena #10" )) {

/* Public Arena #1 */

case 1:

if( getmapusers("force_1-1") == 40 ) mes "Sorry, but Arena #1 is full."; close;

mes "Do you want go to Public Arena #1?";

if( select( "No", "Yes" ) == 1 ) close;

warp "force_1-1",0,0;

close;

/* Public Arena #2 */

case 2:

if( getmapusers("force_1-2") == 40 ) mes "Sorry, but Arena #2 is full."; close;

mes "Do you want go to Public Arena #2?";

if( select( "No", "Yes" ) == 1 ) close;

warp "force_1-1",0,0;

close;

/* If user create own Arena it will shown there like case3 */

/* And maximum 2 public + 10 custom arenas */

}

/* Create own arena */

case 2:

if( /* Arena limit riched - 10 */ ) mes "Sorry, but maximum number of custom arenas already created, what until it will be destroyed or expired"; close;

mes "Please, input name of your Arena";

input .@arena_name$;

next;

mes "Please, input number of parcticipants for each side (Maximum 10 for each side)";

input .playersForEachSide;

if( .playersForEachSide < 1 || .playersForEachSide > 10 ) mes "You must input number from 1 to 10 only!"; close;

next;

mes "Please, select type of Arena";

next;

if( select( "Public", "Privet" ) == 2 ) {

mes "Please, input password for arena";

input .password_arena;

next;

mes "Okey, lets check your info:";

mes "Arena: " + .@arena_name$;

mes "Mode: " + .playersForEachSide + " vs " +.playersForEachSide;

mes "Type: Privet";

mes "Is this correct?";

next;

if( select( "No", "Yes" ) == 1 ) close;

mes "Arena created! Now it will shown in Current List of main Menu!"

close;

}

next;

mes "Okey, lets check your info:";

mes "Arena: " + .@arena_name$;

mes "Mode: " + .playersForEachSide + " vs " +.playersForEachSide;

mes "Type: Public";

mes "Is this correct?";

next;

if( select( "No", "Yes" ) == 1 ) close;

mes "Arena created! Now it will shown in Current List of main Menu!"

close;

/* Delete own arena */

case 3:

close;

/* Cancel */

case 4:

close;

}

}

/* Have idea to make this like Instance */

10,Instanced PvP,360,1@cata,100,224,1@cata,1@cata,1@cata,1@cata,1@cata,1@cata,1@cata,1@cata

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Answer this question...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...