From de46393592fbebf22dbb57f827c4ae743e02255c Mon Sep 17 00:00:00 2001 From: Euphy Date: Sat, 8 Feb 2014 15:32:28 -0500 Subject: [PATCH] Improved 'client_hash_check' config. (Hercules e4a1ca2) - Added option to disable hash check by GM group_id (specify 'disabled' as hash for a certain group_id to let them log in with any client, even if 'client_hash_check' is enabled. - Updated and reworded related documentation for the feature. Improvements on script command 'axtoi'; added 'strtol'. (Hercules 1cf7c1e) - Added script command 'strtol' (conforming to the ISO C90 function). - Modified script command 'axtoi' to internally use 'strtol' instead of an unnecessary separate implementation. Cleaned up many sections of script documentation, and modernized syntax in examples. Added documentation for 'rentitem2' and 'makeitem2'. (follow-up 339c0a8) Added 'true' (1) and 'false' (2) as script constants. 'freeloop' argument is now optional, and will only return the value of freeloop if no argument is given. (tid:92470) http://rathena.org/board/topic/92470-freeloop-optional-argument/ Added a missing mapflag to custom 'devil_square' script. (bugreport:8611) http://rathena.org/board/tracker/issue-8611-devil-square-bug/ Signed-off-by: Euphy --- conf/login_athena.conf | 14 +- db/const.txt | 3 + doc/item_group.txt | 20 +- doc/md5_hashcheck.txt | 38 +- doc/script_commands.txt | 611 ++++++++++++++--------------- npc/custom/events/devil_square.txt | 1 + src/login/login.c | 46 ++- src/map/script.c | 92 ++--- 8 files changed, 419 insertions(+), 406 deletions(-) diff --git a/conf/login_athena.conf b/conf/login_athena.conf index a9c90af9d1..87f128e191 100644 --- a/conf/login_athena.conf +++ b/conf/login_athena.conf @@ -165,14 +165,20 @@ account.engine: auto // Client MD5 hash check // If turned on, the login server will check if the client's hash matches // the value below, and will not connect tampered clients. -// Note: see doc\md5_hashcheck.txt for more details. +// Note: see 'doc/md5_hashcheck.txt' for more details. client_hash_check: off // Client MD5 hashes -// A player can login with a client hash at or below the account group_id. +// The client with the specified hash can be used to log in by players with +// a group_id equal to or greater than the given value. +// If you specify 'disabled' as hash, players with a group_id greater than or +// equal to the given value will be able to log in regardless of hash (and even +// if their client does not send a hash at all.) // Format: group_id, hash -client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5 -client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae +// Note: see 'doc/md5_hashcheck.txt' for more details. +//client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5 +//client_hash: 10, cb1ea78023d337c38e8ba5124e2338ae +//client_hash: 99, disabled import: conf/inter_athena.conf import: conf/import/login_conf.txt diff --git a/db/const.txt b/db/const.txt index 7ea74e1895..5a5d51d178 100644 --- a/db/const.txt +++ b/db/const.txt @@ -4559,3 +4559,6 @@ VAR_MAX_GUILD_STORAGE 8 VAR_MAX_BG_MEMBERS 9 VAR_VIP_SCRIPT 10 VAR_MIN_STORAGE 11 + +false 0 +true 1 diff --git a/doc/item_group.txt b/doc/item_group.txt index 8b9ab4a47b..4aecea2a63 100644 --- a/doc/item_group.txt +++ b/doc/item_group.txt @@ -13,25 +13,25 @@ and 'getgroupitem' script commands. The table below explains which fields are accessed in each. +===============+====================+================+ -| Field | 'getrandgroupitem' | 'getgroupitem' | +| Field | 'getrandgroupitem' | 'getgroupitem' | +===============+====================+================+ -| GroupID | YES | YES | +| GroupID | YES | YES | +===============+====================+================+ -| ItemID | YES | YES | +| ItemID | YES | YES | +===============+====================+================+ -| Rate | YES | YES | +| Rate | YES | YES | +===============+====================+================+ -| Amount | no | YES | +| Amount | no | YES | +===============+====================+================+ -| Random | no | YES | +| Random | no | YES | +===============+====================+================+ -| isAnnounced | no | YES | +| isAnnounced | no | YES | +===============+====================+================+ -| Duration | no | YES | +| Duration | no | YES | +===============+====================+================+ -| isNamed | no | YES | +| isNamed | no | YES | +===============+====================+================+ -| isBound | no | YES | +| isBound | no | YES | +===============+====================+================+ --------------------------------------- diff --git a/doc/md5_hashcheck.txt b/doc/md5_hashcheck.txt index f1bb857ab9..b119f70d77 100644 --- a/doc/md5_hashcheck.txt +++ b/doc/md5_hashcheck.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= rAthena Dev Team //===== Last Updated: ======================================== -//= 20120921 +//= 20140208 //===== Description: ========================================= //= This file outlines the login server's MD5 hash check. //============================================================ @@ -14,25 +14,41 @@ the client is the one specific to your server. The client can only send the correct MD5 hash to the server on certain server types, so a client diff is required to ensure the hash is sent. -A link containing the required WeeDiffGen plugin can be found at: +Please refer to your client diff tool manual for the appropriate patch, +called "Force Send Client Hash Packet" or a similar name. A link +containing the WeeDiffGen plugin can be found at: http://rathena.org/board/topic/70841-r16771-client-md5-hash-check/ -The settings for the hash check are located in conf\login_athena.conf: +The server-side settings for the hash check are located in +'conf\login_athena.conf': // Client MD5 hash check // If turned on, the login server will check if the client's hash matches // the value below, and will not connect tampered clients. -// Note: see doc\md5_hashcheck.txt for more details. +// Note: see 'doc/md5_hashcheck.txt' for more details. client_hash_check: off // Client MD5 hashes -// A player can login with a client hash at or below the account group_id. +// The client with the specified hash can be used to log in by players with +// a group_id equal to or greater than the given value. +// If you specify 'disabled' as hash, players with a group_id greater than or +// equal to the given value will be able to log in regardless of hash (and even +// if their client does not send a hash at all.) // Format: group_id, hash +// Note: see 'doc/md5_hashcheck.txt' for more details. client_hash: 0, 113e195e6c051bb1cfb12a644bb084c5 -client_hash: 99, cb1ea78023d337c38e8ba5124e2338ae +client_hash: 10, cb1ea78023d337c38e8ba5124e2338ae +client_hash: 99, disabled -To enable MD5 hash checks, set 'client_hash_check' to 'on'. -The 'client_hash' group_id can be any of the groups in conf\groups.conf, -and is particularly useful if you wanted to allow GMs a different client -than normal players; for example, a GM client could be hexed differently -with dual-clienting enabled and chat flood disabled. \ No newline at end of file +To enable MD5 hash checks, set 'client_hash_check' to 'on' and add one +'client_hash' entry for each client you want to use. +The group_id can be any of the groups in 'conf/groups.conf', and it is +useful in case if you want to allow GMs to use a different client +than normal players; for example, a GM client could be hexed +differently, perhaps with dual-clienting enabled and chat flood +disabled. +You will need to replace the example MD5 hashes with the actual hash of +your client. You can use any MD5 hash tools to generate it, e.g.: +- md5sum (command line) on linux +- WinMD5 on Windows +- md5 (command line) on Mac OS X diff --git a/doc/script_commands.txt b/doc/script_commands.txt index 1c5d03062d..74b7e7e936 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -3,7 +3,7 @@ //===== By: ================================================== //= rAthena Dev Team //===== Last Updated: ======================================== -//= 20140129 +//= 20140208 //===== Description: ========================================= //= A reference manual for the rAthena scripting language. //= Commands are sorted depending on their functionality. @@ -1241,10 +1241,10 @@ Examples: getvariableofnpc(.var,"TargetNPC"); //This will set the .v variable to the value of the TargetNPC's .var variable. - set .v,getvariableofnpc(.var,"TargetNPC"); + set .v, getvariableofnpc(.var,"TargetNPC"); //This will set the .var variable of TargetNPC to 1. - set getvariableofnpc(.var,"TargetNPC"),1; + set getvariableofnpc(.var,"TargetNPC"), 1; Note: even though function objects can have .variables, getvariableofnpc will not work on them. @@ -1324,11 +1324,11 @@ to leave any gaps. Normally, you do it with a loop and an extra counter, like this: setarray @possiblemenuitems$[0],; - set @j,0; // That's the menu lines counter. + @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]); + @dummy = select(@menulist$[0],@menulist$[1],....@menulist$[]); For the purposes of the technique described above these two statements are perfectly equivalent. @@ -1437,16 +1437,13 @@ function: mes "Try and guess the number I am thinking of."; mes "The number will be between 1 and 10."; next; - set @number, rand(1,10); - input @guess; - if(@guess==@number) - { + .@number = rand(1,10); + input .@guess; + if (.@guess == .@number) { mes "[Woman]"; - mes "Well done that was the number I was thinking of"; + mes "Well done, that was the number I was thinking of!"; close; - } - else - { + } else { mes "[Woman]"; mes "Sorry, that wasn't the number I was thinking of."; close; @@ -1458,17 +1455,14 @@ allow the player to enter text. Otherwise, only numbers will be allowed. mes "[Woman]"; mes "Please say HELLO"; next; - input @var$; - if(@var$=="HELLO") - { + input .@var$; + if (.@var$ == "HELLO") { mes "[Woman]"; - mes "Well done you typed it correctly"; + mes "Well done, you typed it correctly."; close; - } - else - { + } else { mes "[Woman]"; - mes "Sorry you got it wrong"; + mes "Sorry, you got it wrong."; close; } @@ -1496,16 +1490,16 @@ the place that called it. place,50,50,6%TAB%script%TAB%Woman%TAB%115,{ mes "[Woman]" - mes "Lets see if you win"; + mes "Let's see if you win..."; callfunc "funcNPC"; - mes "Well done you have won"; + mes "Well done, you have won!"; close; } function%TAB%script%TAB%funcNPC%TAB%{ - set @win, rand(2); - if(@win==0) return; - mes "Sorry you lost"; - end; + .@win = rand(2); + if (.@win == 0) return; + mes "Sorry, you lost."; + close; } You can pass arguments to your function - values telling it what exactly to do - @@ -1600,7 +1594,7 @@ S_DunWarp: // getarg(1) = x // getarg(2) = y if (Zeny >= 100) { - set Zeny, Zeny-100; + Zeny -= 100; warp getarg(0),getarg(1),getarg(2); } else { mes "Dungeon warp costs 100 Zeny."; @@ -1622,24 +1616,26 @@ If no such argument was given, a zero is returned. place,50,50,6%TAB%script%TAB%Woman1%TAB%115,{ mes "[Woman]"; - mes "Lets see if you win"; + mes "Let's see if you win..."; callfunc "funcNPC",2; - mes "Well done you have won"; - - ... + mes "Well done, you have won!"; + close; + } place,52,50,6%TAB%script%TAB%Woman2%TAB%115,{ mes "[Woman]"; - mes "Lets see if you win"; + mes "Let's see if you win..."; callfunc "funcNPC",5; - mes "Well done you have won"; - - ... + mes "Well done, you have won!"; + close; + } function%TAB%script%TAB%funcNPC%TAB%{ - set @win, rand(getarg(0)); - if(@win==0) return; - mes "Sorry you lost"; + .@win = rand(getarg(0)); + if (.@win == 0) return; + mes "Sorry, you lost."; + close; + | "woman1" NPC object calls the funcNPC. The argument it gives in this call is stated as 2, so when the random number is generated by the 'rand' function, it @@ -1672,7 +1668,7 @@ Example: callfunc "funcNPC",5,4,3; ... function%TAB%script%TAB%funcNPC%TAB%{ - set .@count, getargcount(); // 3 + .@count = getargcount(); // 3 ... } @@ -1732,7 +1728,7 @@ prontera,154,189,4 script Item Seller 767,{ mes "Would you like to buy a phracon for 50z?"; next; if(select("Yes","No, thanks") == 1) { - set Zeny, Zeny-50; + Zeny -= Zeny; getitem 1010,1; mes "Thank you!"; } @@ -1775,8 +1771,8 @@ Example: } - script test -1,{ - set .@try, is_function("try"); // 1 - set .@not, is_function("not"); // 0 + .@try = is_function("try"); // 1 + .@not = is_function("not"); // 0 } --------------------------------------- @@ -1808,108 +1804,106 @@ More examples of using the 'if' command in the real world: Example 1: - set @var1,1; - input @var2; - if(@var1==@var2) goto L_Same; - mes "Sorry that is wrong"; - close; - L_Same: + .@answer = 1; + input .@input; + if (.@input == .@answer) + close; + mes "Sorry, your answer is incorrect."; close; Example 2: - set @var1,1; - input @var2; - if(@var1!=@var2) mes "Sorry that is wrong"; - close; + .@answer = 1; + input .@input; + if (.@input != .@answer) + mes "Sorry, your answer is incorrect."; + close; -(Notice examples 1 and 2 have the same effect.) +Notice that examples 1 and 2 have the same effect. Example 3: - set @var1,@var1+1; - mes "[Forgetfull Man]"; - if (@var==1) mes "This is the first time you have talked to me"; - if (@var==2) mes "This is the second time you have talked to me"; - if (@var==3) mes "This is the third time you have talked to me"; - if (@var==4) mes "This is the forth time you have talked to me, but I think I am getting amnesia, I have forgotten about you"; - if (@var==4) set @var,0; - close; + @count++; + mes "[Forgetful Man]"; + if (@count == 1) mes "This is the first time you have talked to me."; + if (@count == 2) mes "This is the second time you have talked to me."; + if (@count == 3) mes "This is the third time you have talked to me."; + if (@count == 4) { + mes "This is the fourth time you have talked to me."; + mes "I think I am getting amnesia, I have forgotten about you..."; + @count = 0; + } + close; Example 4: - mes "[Quest Person]"; - if(countitem(512)>=1) goto L_GiveApple; - // The number 512 was found from item_db, it is the item number for the Apple. - mes "Can you please bring me an apple?"; - close; - L_GiveApple: - mes "Oh an apple, I didn't want it, I just wanted to see one"; - close; + mes "[Quest Person]"; + if (countitem(512) < 1) { // 512 is the item ID for Apple, found in item_db + mes "Can you please bring me an apple?"; + close; + } + mes "Oh, you brought an Apple!"; + mes "I didn't want it, I just wanted to see one."; + close; Example 5: - mes "[Person Checker]"; - if($name$!=null) goto L_Check; - mes "Please tell me someones name"; - next; - input $name$; - set $name2$,strcharinfo(0); - mes "[Person Checker]"; - mes "Thank you"; - L_Check: - if($name$==strcharinfo(0) ) goto L_SameName; - mes "[Person Checker]"; - mes "You are not the person that " +$name2$+ " mentioned"; - L_End: - set $name$,null; - set $name2$,null; - close; - L_SameName: - mes "[Person Checker]"; - mes "You are the person that " +$name2$+ " just mentioned"; - mes "nice to meet you"; - goto L_End; + mes "[Person Checker]"; + if ($@name$ == "") { // global variable not yet set + mes "Please tell me someones name"; + next; + input $@name$; + $@name2$ = strcharinfo(0); + mes "[Person Checker]"; + mes "Thank you."; + close; + } + if ($@name$ == strcharinfo(0)) { // player name matches $@name$ + mes "You are the person that " +$@name2$+ " just mentioned."; + mes "Nice to meet you!"; -See 'strcharinfo' for explanation of what this function does. + // reset the global variables + $@name$ = ""; + $@name2$ = ""; + + close; + } + mes "You are not the person that " +$name2$+ " mentioned."; + close; + +See 'strcharinfo' for an explanation of what this function does. Example 6: Using complex conditions. - mes "[Multi Checker]"; - if( (@queststarted==1) && (countitem(512)>=5) ) goto L_MultiCheck; - // Only if the quest has been started AND You have 5 apples will it goto "L_MultiCheck" - mes "Please get me 5 apples"; - set @queststarted,1; - close; - L_MultiCheck: - mes "[Multi Checker]"; - mes "Well done you have started the quest of got me 5 apples"; - mes "Thank you"; - set @queststarted,0; - delitem 512,5; - close; + mes "[Multiple Checks]"; + if ( (@queststarted == 1) && (countitem(512) >= 5) ) { + mes "Well done, you have started the quest and brought me 5 Apples."; + @queststarted = 0; + delitem 512,5; + close; + } + mes "Please bring me 5 apples."; + @queststarted = 1; + close; -With the Advanced scripting engine, we got nested if's. That is: +The script engine also supports nested 'if' statements: -if () - dothis; -else - dothat; - -If the condition doesn't meet, it'll do the action following the else. -We can also group several actions depending on a condition, the following way: + if () + dothis; + else + dothat; -if () { + dothis1; + dothis2; + } else { + dothat1; + dothat2; + dothat3; + } Remember that if you plan to do several actions upon the condition being false, and you forget to use the curly braces (the { } ), the second action will be executed regardless @@ -1919,17 +1913,13 @@ condition is true (that is, in the first grouping using a return; , and end; or Also, you can have multiple conditions nested or chained, and don't worry about limits as to how many nested if you can have, there is no spoon ;) -... -if () - dothis; -else if () -{ - dotheother; - do that; - end; -} else - do this; -... + if () + dothis; + else if () { + dothat; + end; + } else + dothis; --------------------------------------- @@ -1961,19 +1951,22 @@ Multiple statements can be grouped with { }, curly braces, just like with the 'i Example 1: while (switch(select("Yes:No") == 2 )) mes "You picked no."; + close; Example 2: multiple statements while (switch(select("Yes:No") == 2 )) { mes "Why did you pick no?"; mes "You should pick yes instead!"; } + close; Example 3: counter-controlled loop - set .@i, 1; + .@i = 1; while (.@i <= 5) { mes "This line will print 5 times."; - set .@i, .@i +1; + .@i += 1; } + close; Example 4: sentinel-controlled loop mes "Input 0 to stop"; @@ -1998,13 +1991,13 @@ update statement is executed (this usually involves incrementing a variable). Then the condition is reevaluated and the cycle continues. Example 1: - for( set .@i, 1; .@i <= 5; set .@i, .@i +1 ) + for( .@i = 1; .@i <= 5; .@i++ ) mes "This line will print 5 times."; Example 2: mes "This will print the numbers 1 - 5."; - for( set .@i, 1; .@i <= 5; set .@i, .@i +1 ) - mes .@i; + for( .@i = 1; .@i <= 5; .@i++ ) + mes "Number: " + .@i; --------------------------------------- @@ -2019,38 +2012,41 @@ condition is false, control is transferred to the statement following the Example 1: sentinel-controlled loop mes "This menu will keep appearing until you pick Cancel"; do { - set .@menu, select("One:Two:Three:Cancel"); + .@menu = select("One:Two:Three:Cancel"); } while (.@menu != 4); Example 2: counter-controlled loop mes "This will countdown from 10 to 1."; - set .@i, 10; + .@i = 10; do { mes .@i; - set .@i, .@i - 1; + .@i -= 1; } while (.@i > 0); --------------------------------------- -*freeloop() +*freeloop({}) Toggling this to enabled (1) allows the script instance to bypass the infinite loop protection, allowing your script to loop as much as it may need. Disabling (0) will warn you if an infinite loop is detected. +The command will return the state of freeloop for the attached script, even if no +argument is provided. + Example: freeloop(1); // enable script to loop freely - //Be aware with what you do here. - for ( set .@i,0; .@i<.@bigloop; set .@i, .@i+1 ) { + // be careful with what you do here + for ( .@i = 0; .@i < .@bigloop; .@i++ ) { dothis; // will sleep the script for 1ms when detect an infinity loop to - // let rAthena do what it need to do (socket, timer, process, etc.) + // let rAthena do what it needs to do (socket, timer, process, etc.) } - freeloop(0); // disable + freeloop(0); // disable freeloop - for ( set .@i,0; .@i<.@bigloop; set .@i, .@i+1 ) { + for ( .@i = 0; .@i < .@bigloop; .@i++ ) { dothis; // throw an infinity loop error } @@ -2691,8 +2687,8 @@ someone messed up the item database. It will return -1 if there is no such item. Example: -//@slots now has the amount of slots of the item with ID 1205. - set @slots, getItemSlots(1205); +//.@slots now has the amount of slots of the item with ID 1205. + .@slots = getitemslots(1205); --------------------------------------- @@ -2899,17 +2895,10 @@ You need to put a 'close' after that yourself. *getguildname() This function returns a guild's name given an ID number. If there is no such -guild, "null" will be returned; +guild, "null" will be returned. - // Would print what ever guild 10007 is, in my case this would return "AlcoROhics" - mes "The guild "+GetGuildName(10007)+" are all nice people."; - - // This will do the same as above: - set @var,10007; - mes "We have some friends in "+GetGuildName(@var)+", you know."; - -This is used all over the WoE controlling scripts. You could also use it for a -guild-based event. +Example: + mes "The guild "+getguildname(10007)+" are all nice people."; --------------------------------------- @@ -2918,24 +2907,22 @@ guild-based event. This function return the name of the master of the guild which has the specified ID number. If there is no such guild, "null" will be returned. -// Would return the guild master of guild 10007, whatever that might be. -// In this example it would return "MissDjax" cause she owns "AlcoROhics" (10007) - mes getguildmaster(10007)+" runs "+getguildname(10007); +Example 1: + // Prints the guild master of guild 10007, whoever that might be. + mes getguildmaster(10007)+" runs "+getguildname(10007); -Can be used to check if the character is the guild master of the specified guild. - -Maybe you want to make a room only guild masters can enter: - - set @GID,getcharid(2); - if(@GID==0) goto L_NoGuild; - if(strcharinfo(0)==getguildmaster(@GID)) goto L_GuildMaster; - mes "Sorry you don't own the guild you are in"; - close; - L_NoGuild: - mes "Sorry you are not in a guild"; - close; - L_GuildMaster: - mes "Welcome guild master of "+GetGuildName(@GID); +Example 2: + // Checks if the character is the guild master of the specified guild. + .@GID = getcharid(2); + if (.@GID == 0) { + mes "Sorry, you are not in a guild."; + close; + } + if (strcharinfo(0) != getguildmaster(.@GID)) { + mes "Sorry, you don't own the guild you are in."; + close; + } + mes "Welcome, guild master of "+getguildname(.@GID); close; --------------------------------------- @@ -3153,12 +3140,12 @@ Example: // immediately copy global temporary variables into scope variables, // since we don't know when 'getmobdrops' will get called again for // another mob, overwriting your global temporary variables - set .@count, $@MobDrop_count; + .@count = $@MobDrop_count; copyarray .@item[0],$@MobDrop_item[0],.@count; copyarray .@rate[0],$@MobDrop_rate[0],.@count; mes getmonsterinfo(.@mob_id,MOB_NAME) + " - " + .@count + " drops found:"; - for( set .@i,0; .@i < .@count; set .@i,.@i +1 ) { + for( .@i = 0; .@i < .@count; .@i++ ) { mes .@item[.@i] + " (" + getitemname(.@item[.@i]) + ") " + .@rate[.@i]/100 + ((.@rate[.@i]%100 < 10) ? ".0":".") + .@rate[.@i]%100 + "%"; } } else { @@ -3175,15 +3162,12 @@ This command can be used to check the currently attached characters total amount This means the skill points used in skill are counted, and added to SkillPoints (number of skill points not used). This command does not count skills which are set as flag 4 (permament granted) (ALL_BUYING_STORE/ALL_INCCARRY) -Example: +Example 1: + .@skillPoints = skillpointcount(); + mes "You have " + .@skillPoints + " skill points in total!"; -//This will set the temp character variable @skillPoints to the amount of skill points, -//and then tell the player the value. - set @skillPoints, skillPointCount(); - mes "You have "+@skillPoints+" skill points in total!"; - -//Self-explanatory... :P - if (skillPointCount() > 20) +Example 2: + if (skillpointcount() > 20) mes "Wow, you have more then 20 Skill Points in total!"; --------------------------------------- @@ -3723,13 +3707,12 @@ Leader: All party members are warped to the leader's position. The leader If you specify a from_mapname, 'warpparty' will only affect those on that map. Example: - -mes "[Party Warper]"; -mes "Here you go!"; -close2; -set @id,getcharid(1); -warpparty "prontera",150,100,@id; -close; + mes "[Party Warper]"; + mes "Here you go!"; + close2; + .@party_id = getcharid(1); + warpparty "prontera",150,100,.@party_id; + close; --------------------------------------- @@ -3913,7 +3896,7 @@ class number system, but it's one that comes with constants which make it easy to convert among classes. The command will return -1 if you pass it a job number which doesn't have an eA job-number equivalent. - set @eac, eaclass(); + @eac = eaclass(); if ((@eac&EAJ_BASEMASK) == EAJ_SWORDMAN) mes "Your base job is Swordman."; if (@eac&EAJL_UPPER) @@ -3934,13 +3917,13 @@ gender if none is given (if no player is attached, male will be used by default) The command will return -1 if there is no valid class to represent the specified job (for example, if you try to get the baby version of a Taekwon class). - set @eac, eaclass(); + @eac = eaclass(); //Check if class is already rebirth if (@eac&EAJL_UPPER) { mes "You look strong."; close; } - set @eac, roclass(@eac|EAJL_UPPER); + @eac = roclass(@eac|EAJL_UPPER); //Check if class has a rebirth version if (@eac != -1) { mes "Bet you can't wait to become a "+jobname(@eac)+"!"; @@ -4091,8 +4074,8 @@ wall), the character is pushed only up to the obstacle. *get_revision() -This command will return the SVN revision number that the server is -currently running on. +This command will return the SVN revision number that the server is currently +running on. if ( get_revision() >= 15000 ) mes "Welcome to rAthena!"; @@ -4103,8 +4086,7 @@ currently running on. This command will return the Git Hash that the server is currently running on. - set .@gitHash$,get_githash(); - mes "Welcome to rAthena! Git Hash: "+.@gitHash$; + mes "Welcome to rAthena! Git Hash: " + get_githash(); --------------------------------------- \\ @@ -4188,27 +4170,23 @@ this. Careful, minor magic ahead. // First, let's get an ID of a character who's name will be on the item. // Only an existing character's name may be there. // Let's assume our character is 'Adam' and find his ID. - - set @charid,getcharid(0,"Adam"); + @charid = getcharid(0,"Adam"); // Now we split the character ID number into two portions with a binary // shift operation. If you don't understand what this does, just copy it. - - set @card3, @charid & 65535; - set @card4, @charid >> 16; + @card3 = @charid & 65535; + @card4 = @charid >> 16; // If you're inscribing non-equipment, @card1 must be 254. // Arrows are also not equipment. :) - set @card1,254; - + @card1 = 254; + // For named equipment, card2 means the Star Crumbs and elemental // crystals used to make this equipment. For everything else, it's 0. - - set @card2,0; - + @card2 = 0; + // Now, let's give the character who invoked the script some // Adam's Apples: - getitem2 512,1,1,0,0,@card1,@card2,@card3,@card4; This wasn't tested with all possible items, so I can't give any promises, @@ -4221,20 +4199,19 @@ To create equipment, continue this example it like this: // for an Ice Stiletto. // If you're inscribing equipment, @card1 must be 255. - set @card1,255; - + @card1 = 255; + // That's the number of star crumbs in a weapon. - set @sc,2; - + @sc = 2; + // That's the number of elemental property of the weapon. - set @ele,1; + @ele = 1; // And that's the wacky formula that makes them into // a single number. - set @card2,@ele+((@sc*5)<<8); + @card2 = @ele+((@sc*5)<<8); // That will make us an Adam's +2 VVS Ice Stiletto: - getitem2 1216,1,1,2,0,@card1,@card2,@card3,@card4; Experiment with the number of star crumbs - I'm not certain just how much will @@ -4317,25 +4294,24 @@ Note: 'delitem' in an NPC script can still remove rental items. *rentitem2 ,