Jump to content
  • 0

Help - Array


Davros

Question


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  14
  • Reputation:   0
  • Joined:  04/22/12
  • Last Seen:  

I want know how to show the items that are listed in the array in a list at the npc.

For example:

I have this array:

setarray .itemsids[0],5360,5361,5363,5362,5364;

Would that the items listed in the array appear in the list to select and perform some action.

And every 15 listed items appear the option to turn the page and continue the list.

Link to comment
Share on other sites

14 answers to this question

Recommended Posts


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

// Setting items to show each page
.@list = 15;

// Looking for the arraysize
.@arraysize = getarraysize(.itemsids);

// Setting initial page to 1
.@page = 1;

do {

// Setting the "Previous Page" menu option (only if not the first page)
if( .@page != 1 )
   .@menu$ = "Previous Page";

// Setting the array element 0 otherwise
else
   .@menu$ = "" + .itemsids[0];

// Looping .@list array elements each page
for(.@i = ((.@page - 1)*.@list); .@i < (.@page*.@list); .@i++ ) {

   // Adding to .@menu$ the items
   .@menu$ = .@menu$ + ":" + .itemsids[.@i];

   // Checking if the size has reached the maximum
   if( .@i == (.@arraysize - 1) )
    break;
}

// Setting the "Next Page" menu option (only if not the last page)
if( .@i == (.@arraysize - 1) )
   .@menu$ = .@menu$ + ":Next Page";

// Setting the selected value.
.@s = select( .@menu$ ) - 1;

// Condition 1: first page (so no "previous page" option) - Next Page option
if( (.@page == 1) && (.@s == .@list) )
   .@page++;

// Condition 2: not the first page, not the last page - Next Page option
else if( (.@page != (.@arraysize / .@list )) && (.@s == (.@list + 1)) )
   .@page++;

// Condition 3: not the first page - Previous Page option
else if( (.@page != 1) && (!.@s) )
   .@page--;

// Confition 4: you selected a valid menu
else
   break;
} while(1);

// Recovering the correct array index:
if( .@page == 1 )
   .@index = .@s;
else
   .@index == (.@s - 1) + (.@list * (.@page - 1);

// messaging!
mes "You have selected the index " + .@index;
mes "Your value is: " + .itemsids[.@index];

EDIT:

Not tested.

Edited by Ryokem
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  4
  • Topics Per Day:  0.00
  • Content Count:  44
  • Reputation:   48
  • Joined:  11/19/11
  • Last Seen:  

Since rathena added the string commands we can now use the implode function to create dynamic menus.

prontera,156,174,4 script test 100,{

do {
 //Add 'Previous Page' to index 0 if needed
 .@menu$ = (.@page)?"Previous Page:":":";

 //Add menu items
 copyarray .@menuar$[0], .itemsnames$[.@page * .items_per_page], .items_per_page;
 set .@menu$, .@menu$ + implode(.@menuar$, ":");

 //Add 'Next Page' to end if needed
 set .@menu$, .@menu$ + ((.max_page - .@page)?":Next Page":"");

 //Compute number of items (I think this can look better)
 .@num_items_in_menu = .num_items - (.@page * .items_per_page);
 .@num_items_in_menu = (.@num_items_in_menu > .items_per_page)?.items_per_page:.@num_items_in_menu;

 .@menu = select(.@menu$) - 1;

 if(.@menu == .@num_items_in_menu + 1) { //next page
  .@page++;
 } else if (.@menu) { //selected item
  break;
 } else { //previous page
  .@page--;
 }
} while (1);

.@index = .@page * .items_per_page + .@menu - 1;
dispbottom "selected: " + .itemsids[.@index] + ": " + .itemsnames$[.@index];
close;

OnInit:
setarray .itemsids[0],5360,5361,5363,5362,5364;

.items_per_page = 15;
.num_items = getarraysize(.itemsids);
.max_page = .num_items / .items_per_page + ((.num_items % .items_per_page) > 0) - 1;

//Prestore item names
while(.@i < .num_items) {
 setarray .itemsnames$[.@i], getitemname(.itemsids[.@i]);
 .@i++;
}

end;
}

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

heh ... fun XD

prontera,156,179,5    script    kdfhksdfjs    100,{
   while (1) {
       .@menu$ = ( .@currentpage )? "Previous Page:" : ":";
       copyarray .@tmp$, .itemname$[ .@currentpage * .itemperpage ], .itemperpage;
       .@menu$ = .@menu$ + implode( .@tmp$, ":" );
       .@menu$ = .@menu$ + ( ( .@currentpage == .maxpage )? "" : ":Next Page" );
       .@pick = select( .@menu$ ) -1;
       if ( !.@pick )
           .@currentpage--;
       else if ( .@pick == .itemperpage +1 )
           .@currentpage++;
       else
           break;
   }
   .@index =  .@currentpage * .itemperpage + .@pick -1 ;
   dispbottom "selected :"+ .itemid[.@index] +" : "+ .itemname$[.@index];
   close;
OnInit:
   setarray .itemid, 4001,4002,4003,4004,4005,4006,4007,4008,4009;
   .itemperpage = 3;
   .@itemsize = getarraysize( .itemid );
   .maxpage = .@itemsize / .itemperpage + !!( .@itemsize % .itemperpage ) -1; // meh ...
   while ( .@i < .@itemsize ) {
       .itemname$[.@i] = getitemname( .itemid[.@i] );
       .@i++;
   }
   end;
}

still, its a script based on toasty's

EDIT:

damn it ... (!!(<condition>)) doesn't work !

ok it works ... but toasty's line is more efficient

Edited by AnnieRuru
  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  4
  • Topics Per Day:  0.00
  • Content Count:  44
  • Reputation:   48
  • Joined:  11/19/11
  • Last Seen:  

@annie

Looking good =D. Yours definitely runs better. I think if you Put the next/previous lines into the tmp$ array and crunch it all with implode at the End It would make it extra sexy.

tmp$[0] = previous page;

tmp$[.items_per_page + 1] = next page;

Ps: on phone atm so cant script. ^^;

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

prontera,156,179,5	script	kdfhksdfjs	100,{
while (1) {
	deletearray .@tmp$;
	if ( .@currentpage )
		.@tmp$[0] = "Previous Page";
	copyarray .@tmp$[1], .itemname$[ .@currentpage * .itemperpage ], .itemperpage;
	if ( .@currentpage != .maxpage )
		.@tmp$[ .itemperpage +1 ] = "Next Page";
	.@pick = select( implode( .@tmp$, ":" ) ) -1;
	if ( !.@pick )
		.@currentpage--;
	else if ( .@pick == .itemperpage +1 )
		.@currentpage++;
	else
		break;
}
.@index =  .@currentpage * .itemperpage + .@pick -1 ;
dispbottom "selected :"+ .itemid[.@index] +" : "+ .itemname$[.@index];
close;
OnInit:
setarray .itemid, 4001,4002,4003,4004,4005,4006,4007,4008,4009;
.itemperpage = 4;
.@itemsize = getarraysize( .itemid );
.maxpage = .@itemsize / .itemperpage + ( .@itemsize % .itemperpage > 0 ) -1;
while ( .@i < .@itemsize ) {
	.itemname$[.@i] = getitemname( .itemid[.@i] );
	.@i++;
}
end;
}

I almost getting nosebleed ... xD

Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

@Annie:

Won't be this good till you will implement the correct sDoc, as he asked how to do it to learn.

I want know how to show the items that are listed in the array in a list at the npc.

And well, I didn't know really about the implode function honestly.

But still, there is an error in those script tho:

if ( !.@pick )
.@currentpage--;

This is the general case, but it won't be correct for the very first page, 'cause option 0 in the first page is actually a correct element.

Edited by Ryokem
  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  4
  • Topics Per Day:  0.00
  • Content Count:  44
  • Reputation:   48
  • Joined:  11/19/11
  • Last Seen:  

@ryokem

There is a trick where if you leave a menu item blank, it won't show, but it will still use up the index.

if ( .@currentpage )

.@tmp$[0] = "Previous Page";

In this case the first page actually looks something like this

":<item1>:<item2>:<item3>:Next Page"

Note that it starts with a colon ':'. This means index 1 (adjusted to be 0 later) will always correspond to 'Previous Page' regardless of wherever it is shown or not.

Likewise the same thing happens for the 'Next Page' item only with a different index.

This method cuts down on alot of extra math, loops and comparisons. However it leaves a security flaw in that players can possibly get to non wanted menus through packet manipulation. Therefore scripters will need to do further checks in their script after the menu selection depending on the usage to insure that selection is valid.

  • Upvote 1
  • Love 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  1
  • Topics Per Day:  0.00
  • Content Count:  71
  • Reputation:   25
  • Joined:  11/23/11
  • Last Seen:  

prontera,100,100,4    script    items    100,{

   while ( ! .@s || .@s == (.page + 1) )
   {
       set .@index, .@index + 1;
       set .@s, select ( getd ( ".menu"+ .@index +"$" ) );
   }
   set .@item_index, ((.@index - 1) * .@page) + .@s;
   dispbottom getitemname ( .itemsids[.@item_index] );
   close;


OnInit:

   setarray .itemsids[0],5360,5361,5363,5362,5364;
   set .page, 4;

   set .@size, getarraysize ( .itemsids );
   while ( .@i < .@size )
   {
       set .@index, (.@i / .page) + 1;
       setd ".menu"+ .@index +"$", getd ( ".menu"+ .@index +"$" ) + getitemname ( .itemsids[.@i] ) +":";
       if ( ! ( ( .@i + 1 ) % .page ) )
           setd ".menu"+ .@index +"$", getd ( ".menu"+ .@index +"$" ) + "^ff0000Next^000000";
       set .@i, .@i + 1;
   }

}

  • Upvote 2
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

damn it ... >__< ... your script is more sexy than mine !

gives you a rep up

prontera,160,183,5    script    kdfh123ksdfj2s55    100,{
   while (1) {
       .@pick = select( .menu$[ .@currentpage ] ) -1;
       if ( !.@pick )
           .@currentpage--;
       else if ( .@pick == .itemperpage +1 )
           .@currentpage++;
       else
           break;
   }
   .@index =  .@currentpage * .itemperpage + .@pick -1;
   dispbottom "selected :"+ .itemid[.@index] +" : "+ .itemname$[.@index];
   close;
OnInit:
   setarray .itemid, 4001,4002,4003,4004,4005,4006,4007,4008,4009;
   .itemperpage = 3;
   .@itemsize = getarraysize( .itemid );
   .@maxpage = .@itemsize / .itemperpage + ( .@itemsize % .itemperpage > 0 );
   while ( .@i < .@maxpage ) {
       .menu$[ .@i ] = ( .@i )? "Previous Page:" : ":";
       .@j = 1;
       while ( .@j < .itemperpage +1 ) {
           .itemname$[ .@k ] = getitemname( .itemid[ .@k ] );
           .menu$[ .@i ] = .menu$[ .@i ] + .itemname$[ .@k ] +":";
           .@j++;
           .@k++;
       }
       .menu$[ .@i ] = .menu$[ .@i ] +( ( .@i < .@maxpage -1 )? "Next Page" : "" );
       .@i++;
   }
   end;
}

but seriously ... we've gone way too ... hahaha XD

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  6
  • Topics Per Day:  0.00
  • Content Count:  14
  • Reputation:   0
  • Joined:  04/22/12
  • Last Seen:  

It worked.

Thanks guys.

Edited by Davros
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

@ryokem

There is a trick where if you leave a menu item blank, it won't show, but it will still use up the index.

if ( .@currentpage )

.@tmp$[0] = "Previous Page";

In this case the first page actually looks something like this

":<item1>:<item2>:<item3>:Next Page"

Note that it starts with a colon ':'. This means index 1 (adjusted to be 0 later) will always correspond to 'Previous Page' regardless of wherever it is shown or not.

Likewise the same thing happens for the 'Next Page' item only with a different index.

This method cuts down on alot of extra math, loops and comparisons. However it leaves a security flaw in that players can possibly get to non wanted menus through packet manipulation. Therefore scripters will need to do further checks in their script after the menu selection depending on the usage to insure that selection is valid.

I've tried it many times since when on eAthena, and a blank menu was just skipping that index, left-shifting all the followings. Unless rAthena changed it, it still should pop to index 0.

prontera,100,100,4	script	items	100,{

while ( ! .@s || .@s == (.page + 1) )
{
	set .@index, .@index + 1;
	set .@s, select ( getd ( ".menu"+ .@index +"$" ) );
}
set .@item_index, ((.@index - 1) * .@page) + .@s;
dispbottom getitemname ( .itemsids[.@item_index] );
close;


OnInit:

setarray .itemsids[0],5360,5361,5363,5362,5364;
set .page, 4;

set .@size, getarraysize ( .itemsids );
while ( .@i < .@size )
{
	set .@index, (.@i / .page) + 1;
	setd ".menu"+ .@index +"$", getd ( ".menu"+ .@index +"$" ) + getitemname ( .itemsids[.@i] ) +":";
	if ( ! ( ( .@i + 1 ) % .page ) )
		setd ".menu"+ .@index +"$", getd ( ".menu"+ .@index +"$" ) + "^ff0000Next^000000";
	set .@i, .@i + 1;
}

}

Although your script can look "sexy" or h/e Annie called it, it has a slow process and a useless overusage of the heap with the setd/getd command, when not necessary.
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  9
  • Topics Per Day:  0.00
  • Content Count:  379
  • Reputation:   304
  • Joined:  11/10/11
  • Last Seen:  

However it leaves a security flaw in that players can possibly get to non wanted menus through packet manipulation. Therefore scripters will need to do further checks in their script after the menu selection depending on the usage to insure that selection is valid.

As far I know, empty menu are not send to the client, so no hack possible here.

I've tried it many times since when on eAthena, and a blank menu was just skipping that index, left-shifting all the followings. Unless rAthena changed it, it still should pop to index 0.
I never have this problem on eA. Maybe you didn't do it in the good way.

Well even if the topic is resolved (enough examples I think lol), gimme a try.

The script is not tested, but it's the same way than other scripters here :

prontera,100,100,4    script    item_menu    100,{

   do {
       set .@choice, select(.menu$[.@page]) - 1;
       if ( .@choice && .@choice <= .page_size )
           break;
       set .@page,  .@page + (!!.@choice) * 2 - 1;
   } while( 1 );

   set .@index, .@page * .page_size + .@choice - 1;
   dispbottom .item_name$[.@index];
   close;


OnInit:
   set .page_size, 5;
   setarray .item_id, 4001, 4002, 4003, 4004, 4005, 4006, 4007, 4008, 4009;
   set .@size, getarraysize(.item_id);

   while ( .@i<.@size ) {
       set .@offset,          .@i/.page_size;
       set .item_name$[.@i],  getitemname( .item_id[.@i] );

       if ( .@i && !(.@i % .page_size ) )
           set .menu$[.@offset], "Previous";

       set .menu$[.@offset], .menu$[.@offset] + ":" + .item_name$[.@i];
       set .@i, .@i + 1;

       if ( .@i<.@size && !(.@i % .page_size ) )
           set .menu$[.@offset], .menu$[.@offset] + ":Next";
   }
}

  • Upvote 1
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  18
  • Topics Per Day:  0.00
  • Content Count:  2044
  • Reputation:   682
  • Joined:  10/09/12
  • Last Seen:  

However it leaves a security flaw in that players can possibly get to non wanted menus through packet manipulation. Therefore scripters will need to do further checks in their script after the menu selection depending on the usage to insure that selection is valid.

As far I know, empty menu are not send to the client, so no hack possible here.

yeah, the client only send option menu number,

its the server side to calculate the index of the array or the position options of the menu

@Ryokem

http://www.eathena.w...opic=160415&hl= <-- yeah that's the time when eathena updates ..

how long have u disappear ... :ani_swt3: 5 years !?!

another one

http://www.eathena.w...dpost&p=1007391

EDIT: and about 2nd question, yes although runs slower,

but I do understand his technique and made me realize I can made the menu during server start-up

after all, this script support section is a place to discuss and understand each other scripter's technique too

@Keyworld

WAHAHAHA !! script showdown !! feel like old times already ~ :meow:

PS: yeah your script works, tested

Edited by AnnieRuru
Link to comment
Share on other sites


  • Group:  Members
  • Topic Count:  0
  • Topics Per Day:  0
  • Content Count:  205
  • Reputation:   19
  • Joined:  10/12/12
  • Last Seen:  

@Ryokem

http://www.eathena.w...opic=160415&hl= <-- yeah that's the time when eathena updates ..

how long have u disappear ... :ani_swt3: 5 years !?!

another one

http://www.eathena.w...dpost&p=1007391

Woop not really "this" long xD I ended scripting eAthena stuff in 2009-2010, so unless the SVN of the private server I was scripting for was still out-to-date, this problem was still there.

Good if it was corrected anyway.

after all, this script support section is a place to discuss and understand each other scripter's technique too

That's the spirit.

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...