Jump to content

Ryokem

Members
  • Posts

    205
  • Joined

  • Last visited

Posts posted by Ryokem

  1. @Annie:

    The system above the source is really different from NPC scriptings. You can see yourself you have structures and pointers in the source, for not speaking about the higher variable setups and types, like enumerations, booleans and others.

    Bits are used for different purpose other than for NPC scriptings. Pointers works pretty well with stack, heap, blocks of memory and bits.

  2. True thing about POO and destabilization. But I believe that OOrAthena would simplify every kind of problem about storing variables or using bitmasks (not really used this much lol).

    And good from rAthena if bit-a-bit operations are this fast to compute, 'cause is not really like that in the most part of IPLs actually used...

    Funny to see there is nothing related to bitmask on the wiki °°

    That's exactly why I proposed to open up a thread about bitmasks, I'm sure we can develop it pretty well and fast sharing our knowledges (not me and you only, I mean everyone who is good at it).

  3. Nice try Key, this is a good solution to try to face in my opinion one of the biggest Athena emulation problem: as you work on storage variables and datas from different players, why didn't developers make Athena (both eA and rA) an Object Oriented language? So easy to work between classes and objects, and to store/load them whenever it is necessary... That's the biggest Athena limit in my opinion. Times ago, I was working myself to try to develop and emphatize the concept of class and struct, oriented to a new system of storing datas, based on OOL of course. Had to drop the project 'cause it was pretty long, hard and my time was almost zero.

    Oh and btw, I still believe anyway that the bit process above bitmasks is pretty odd, helps maybe on storing boolean variables or save space, but still slow for the server to compute.

    We should release anyway a thread about bitmasks to teach the new generation of scripters what there is in the deep part of the programming.

  4. Bitmasks can only save up to 2 statements, as you correctly compared them to boolean variables. You can have a chain of tons of bits, each of them storing a boolean for an evaluation of 2^n elements. Shifting the bits or using bitmasks, you can get the boolean reference of overy of them. As this process requires a virtual statement, it needs multiple checkings on the bit of the variable you are checking, plus the operation you run to recover the correct bit, while a normal variable declaration just need the time for conversion. Also, if I want a quest to have multiple steps, you can't updrate the variables with bits as both of the 2 status are taken already. So, you can still operate to integer decimal variables, giving a variable 10 possible values instead of 2. The operations will be the same, just it will skip the part of the bit-catching and will reduce again the number of operation the system has to compute (speaking about IPLs, I'm not really a rA expert, it may be there are some particular mechanics that works better with rA more than in other IPLs, that's my limit after all ^^; )

  5. I don't say it's wrong to use a method or another, I say it's better to not wasting space by creating multiples vars.

    I don't get your sentence about bitmask, the result variable is an INT set by booleans (understand boolean as 0-1 for each bits (0-30) in the INT variable).

    I meant that if you want to "save" space, is still better to use decimal system variables more than bits, as you will need to compute more operations for checking bits while it would be way simpler with decimal sys, if you need to save space.

  6. @Ryokem

    No, I agree again with Annie.

    We are limited with PC variables and have to use some stuff to don't reach the server limit. We don't care about how it's stored in the DB (and even it's always smaller to store 30 booleans into one INT (4 bytes) instead of having 30 INT with values 0-1 (4*30 bytes) ).

    Not really as the space they will placed in is different, unless rAthena didn't really changed it (I just supposed it's like all "normal" IPL's). And as I said before, both ways are correct, but I'd prefer not to use the heap to compute bitmasks, when I can just store values, especially if there can be future updates about the script. Also, are you sure that bitmasks actually set the variable as boolean? I believe that even if it has boolean properties, it's considered as integer, so the memory used won't change, unless you use just one variable and make correspond every bit to a variable value. But the same you can do with integers as well.

    you should try to program on assembly
    hmm I never actually tries to code something outside eathena/rathena

    any example or external links that I can refer on ?

    Assembly language (wikipedia)

    Based on registers and bit-usage. Haha :P

  7. What's up with bitmasks? Why wasting a spot on heap to operate something binary when actually is the same thing?

    The variable is stored in a xBit register, and so it happens when you operate with bitmasks. The thing is actually the same, just without any shift or check operation.

    @Annie: You are a bitmasks-addicted, you should try to program on assembly :P

    EDIT: I believe this thread can still be up without getting on PMs, it can help many people to improve a lot as things has started to be shown.

    Can also be a chance for newbie scripters to learn bitmasks, as the argument has been introduced here.

    Just my belief :P

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

  9. @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.
  10. @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.

    • Upvote 1
  11. // 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.

  12. Yeah, it will delete the item if you set that the item expires after being used.

    And I personally try not to use atcommand command inside scripts unless it's really the only choice I have, mostly 'cause of server runtime.

  13. Yeah, you can add a timer and setting that kinf of command too, exactly in the same way.

    Something like...

    function	script	command__	{
    
    attachnpctimer getcharid(3);
    atcommand "@autoattack";
    initnpctimer;
    return;
    
    OnTimer60000: //60 seconds
    OnTimerQuit:
    atcommand "@autoattack";
       end;
    }

    Note that you have to be careful to use an @command in the OnTimerQuit label, 'cause the player already logged out but it may be still able to run the command.

  14. Just call a function inside the item. Make it an usable item.

    { callfunc "getItem__"; },{},{}

    then the function itself..

    function    script    getItem__    {
    
    mes "input the ID";
    input .@id;
    
    //Code to check if the input is avaible/correct
    
    mes "input the amount";
    input .@amount;
    
    //Code to check if the input is avaible/correct
    
    getitem .@id, .@amount;
    return;
    }

  15. for Auction, you mean a place where people put some items to sell and buyers bet to the highest prize?

    If I am not wrong, there was a sort of released-auction somewhere in the official emulated client...

  16. All room turn to dispell i want only 1 room that what listed on the rooms

    My bad.

    zhakastia,104,68,3	script	PvP Warper	413,{
    
    function dispell__;
    
    mes "[PvP Warper]";
    mes "Which arena do you want to go to?";
    next;
    switch(select("Normal PvP ["+getmapusers("guild_vs5")+"/100]:Dispel PvP ["+getmapusers("guild_vs3")+"/100]:No Healing Potions PvP ["+getmapusers("guild_vs2")+"/100]")) {
    case 1:	// Normal PvP
    	if (getmapusers("prt_are01") > 99) callsub S_full;
    	set .@map$, "guild_vs5";
    	break;
    
    Case 2: // Dispel PvP
    	if (getmapusers("guild_vs3") > 99) callsub S_full;
    	set .@map$, "guild_vs3";
    
    	dispell__();
    
    	break;
    
    Case 3: // No Healing Potions PvP
    	if (getmapusers("guild_vs2") > 99) callsub S_full;
    	set .@map$, "guild_vs2";
    	break;
    }
    
    warp .@map$, 0, 0;
    end;
    
    S_full:
    mes " ";
    mes "I'm sorry, this arena is full.  Please try again later...";
    close;
    
    function	dispell__	{
    
    for( .@i = 0; .@i < 308; .@i++ )
    if( (.@i != 53) && (.@i != 54) && (.@i != 249) && (.@i != 103)  ) //Do not dispell SC_WEIGHT50, SC_WEIGHT90, SC_JAILED, SC_NOCHAT
    	 sc_end .@i;
    return;
    }
    
    
    }
    
    prt_are01,150,130,4	script	PvP Exit	868,{
    warp "prontera",0,0;
    end;
    
    }
    
    
    //============= MAP FLAG ===============
    // Player
    guild_vs3	mapflag	nosave
    guild_vs3	mapflag	noteleport
    guild_vs3	mapflag	nowarpto
    guild_vs3	mapflag	nowarp
    guild_vs3	mapflag	nomemo
    guild_vs3	mapflag	nopenalty
    guild_vs3	mapflag	nobranch
    guild_vs3	mapflag	noicewall
    guild_vs3	mapflag	noreturn
    guild_vs3	mapflag	pvp_noguild
    guild_vs5	mapflag	noteleport
    guild_vs5	mapflag	nowarp
    guild_vs5	mapflag	nosave
    guild_vs5	mapflag	nopenalty
    guild_vs5	mapflag	nobranch
    guild_vs5	mapflag	noicewall
    guild_vs5	mapflag	pvp_noguild
    guild_vs2	mapflag	nopenalty
    guild_vs2	mapflag	nosave	SavePoint
    guild_vs2	mapflag	nowarp
    guild_vs2	mapflag	noteleport
    guild_vs2	mapflag	nomemo
    guild_vs2	mapflag	loadevent
    guild_vs2	mapflag	noreturn
    guild_vs2	mapflag	nobranch
    guild_vs2	mapflag	pvp_noguild

  17. Good to see scripts like this !

    Avoid using "for(; ;)", it's slower than goto/do/while (ugly parsing in src), it will allow you to remove the freeloop() things

    lol, I loved the times on eA where people thought they were pro scripters just by using a for( ; ; ) loop.. That time was pretty funny :P

    Useless command anyway, there are tons of better ways to make an infinite loop, I totally agree with Key.

×
×
  • Create New...