Jump to content

Missingno

Members
  • Posts

    135
  • Joined

  • Last visited

  • Days Won

    4

Everything posted by Missingno

  1. Might want to merge over to rAthena soon, then. For eAthena compatibility, change any occurrences of getgroupid() to getgmlevel(), and change any occurrences of .@var = value; to set .@var, value (keep in mind that the italicised text is pseudocode; it is just an example of similar occurrences). Lastly, change these values to the GM levels that you want to restrict from specified maps: setarray .map_restrict[0], 1, 2, 3; But really, switch over to rAthena already.
  2. I think you'd find your solution with something similar to #3; probably without the for loop, which I added in because I slightly misunderstood your request. // Possible items to receive (ID, amount) setarray .@item_id[0], 909, 2, 909, 3, 909, 3; do { // Randomise index location .@loc = rand(getarraysize(.@item_id)); } while (getitemname(.@item_id[.@loc]) == "null" || .@loc % 2); // Receive item getitem .@item_id[.@loc], .@item_id[.@loc + 1];
  3. Here's three different methods: 1: Completely random IDs; fixed amounts .@min_id = 501; // Minimum item ID .@max_id = 20000; // Maximum item ID .@rand_amt = 2; // Amount of random items .@recv_amt = 1; // Amount to receive // Loop for each item for (.@i = 0; .@i < .@rand_amt; .@i++) { do { // Randomise item ID .@id = rand(.@min_id, .@max_id); } while (getitemname(.@id) == "null"); // Receive item getitem .@id, .@recv_amt; } 2: Controlled random IDs; fixed amounts .@rand_amt = 2; // Amount of random items .@recv_amt = 1; // Amount to receive // Possible items to receive setarray .@item_id[0], 501, 909, 910; // Loop for each item for (.@i = 0; .@i < .@rand_amt; .@i++) { do { // Randomise index location .@loc = rand(getarraysize(.@item_id)); } while (getitemname(.@item_id[.@loc]) == "null"); // Receive item getitem .@item_id[.@loc], .@recv_amt; } 3: Controlled IDs and corresponding amounts .@rand_amt = 2; // Amount of random items // Possible items to receive (ID, amount) setarray .@item_id[0], 501, 2, 909, 5, 910, 3; // Loop for each item for (.@i = 0; .@i < .@rand_amt; .@i++) { do { // Randomise index location .@loc = rand(getarraysize(.@item_id)); } while (getitemname(.@item_id[.@loc]) == "null" || .@loc % 2); // Receive item getitem .@item_id[.@loc], .@item_id[.@loc + 1]; }
  4. Missingno

    mes

    You can use a switch to prompt a menu that can adjust the dialogue without a next button: prontera,160,170,3 script Example NPC 721,{ mes "[Kafra]"; mes "Tell me where you want to go."; switch (select("Here:There:Cancel")) { case 1: // Here mes "If you go here, then you must pay."; break; case 2: // There mes "You can go there for free!"; break; case 3: // Cancel mes "Okay, see you later!"; break; } close; } Because of the way this is written, the script will continue based on which option you chose. If the first option ("Here") was selected, the switch will switch you over to case 1; similarly, if you choose the second option ("There"), you'll be switched over to case 2. Each case serves as a label (of sorts), but allows for a little more flexibility and readability than something like L_LameLabelName. These case labels also correspond to the value sent in the switch, which was returned by the function select(). At the end of each case label, the script should either break, close, or end (but only end in switches without a mes dialogue). Edit: Fixed typo. D:
  5. RMS gets its data from rAthena and Hercules; if anything, RMS is inaccurate. Similarly, both rAthena and Hercules could be incorrect, as the data used to determine monster stats is gathered from kRO (and sometimes, iRO). Here's data on Valkyrie Randgris from the kRO and iRO renewal databases: kRO: http://ro.gnjoy.com/guide/runemidgarts/popup/monsterview.asp?monsterID=RANDGRIS iRO: http://db.irowiki.org/db/monster-info/1751/
  6. I suppose I had meant to say that I intended to replace the need for an SQL table to store access data; the queries in the previous version were to return a specific player's name or ID, for lack of an alternative method. Thanks for the feedback though; I concede that the revised version turned out much better, after some consideration.
  7. These are the Group IDs that cannot access blacklisted maps: // Restricted group IDs setarray .map_restrict[0], 1, 2, 3; This is the Group Level required to use @warp: // Group level command access .cmd_access = 40; See conf/groups.conf for GM levels.
  8. You should avoid using global variables for things like this... Especially if it isn't bitwise or compact string... Reason being it's updated very frequently as opposed to a new sql table which is only used when the script requires it. Soon you'll have a very large set of strings or numbers being constantly updated. You've effectively created an array of many global variables. x_x;; I also recommend you add some kind of clear command to your script. If a GM ever decides to remove your script all your unused variables will litter their server. Ideally you'd save all information into its own sql scheme and load it to the script via temporary global variables when the server starts. In hindsight, using temporary global variables with an SQL table would be more ideal; I guess I overlooked that with the primary objective of replacing the need for an SQL table. I rewrote the script to accommodate this: /*========================================================= SQL table: CREATE TABLE IF NOT EXISTS `guild_storage_access` ( `guild_id` int(11) NOT NULL, `char_id` int(11) NOT NULL, PRIMARY KEY (`char_id`) ) ENGINE=MyISAM; ==========================================================*/ - script guildstorage -1,{ // Function: Return character name of sent ID function getcharname { query_sql "SELECT `name` FROM `char` WHERE `char_id` = '"+ getarg(0) +"'", .@query_name$; return .@query_name$; } OnInit: // Store values from SQL table in temporary global array query_sql "SELECT `guild_id`,`char_id` FROM `guild_storage_access`", $@GS_Guild, $@GS_Member; // Configuration bindatcmd "guildstorage", strnpcinfo(3) +"::OnAtcommand", 0, 0; bindatcmd "gstorage", strnpcinfo(3) +"::OnAtcommand", 0, 0; end; OnAtcommand: // Check if player is in town if (!getmapflag(strcharinfo(3), mf_town)) { message strcharinfo(0), "You may only use guild storage in towns."; // Guild master access } else if (getguildmasterid(getcharid(2)) == getcharid(0)) { while (1) { switch (select("Open storage:Change permissions:End session")) { case 1: // Open storage message strcharinfo(0), "Guild storage opened."; guildopenstorage(); close; case 2: // Clear looped data cleararray .@access_list$[0], "", getarraysize(.@access_list$); cleararray .@member_list$[0], "", getarraysize(.@member_list$); .@j = 0; // Build access list for (.@i = 0; .@i < getarraysize($@GS_Guild); .@i++) { if ($@GS_Guild[.@i] == getcharid(2)) { .@access_list$[.@j++] = getcharname($@GS_Member[.@i]); } } // Inject "Add new member" option .@access_list$[getarraysize(.@access_list$)] = "Add new member"; // Inject "Go back" option .@access_list$[getarraysize(.@access_list$)] = "Go back"; // Select member to modify menu implode(.@access_list$, ":"), -; .@access_choice = @menu - 1; // Check if last option selected if (@menu == getarraysize(.@access_list$)) { break; } // Check if second to last option selected if (@menu == getarraysize(.@access_list$) - 1) { // Build member list query_sql "SELECT `name` FROM `guild_member` WHERE `guild_id` = '"+ getcharid(2) +"'", .@member_list$; // Inject "Go back" option .@member_list$[getarraysize(.@member_list$)] = "Go back"; // Add new member menu implode(.@member_list$, ":"), -; .@member_choice = @menu - 1; // Check if last option selected if (.@member_choice == getarraysize(.@member_list$)) { break; } // Add member's ID to SQL table message strcharinfo(0), "Granted guild storage access for '"+ .@member_list$[.@member_choice] +"'."; query_sql "SELECT `char_id` FROM `guild_member` WHERE `name` = '"+ .@member_list$[.@member_choice] +"'", .@member_id; query_sql "INSERT INTO `guild_storage_access` (`guild_id`, `char_id`) VALUES ('"+ getcharid(2) +"', '"+ .@member_id +"') ON DUPLICATE KEY UPDATE `guild_id` = '"+ getcharid(2) +"'"; // Update existing ID in temporary global array for (.@i = 0; .@i < getarraysize($@GS_Member); .@i++) { if ($@GS_Member[.@i] == .@member_id) { $@GS_Guild[.@i] = getcharid(2); .@updated = 1; break; } } // Add new value in temporary global array if (!.@updated) { $@GS_Guild[getarraysize($@GS_Guild)] = getcharid(2); $@GS_Member[getarraysize($@GS_Member)] = .@member_id; } break; } // Revoke access switch (select("Revoke access:Go back")) { case 1: message strcharinfo(0), "Revoked guild storage access for '"+ .@access_list$[.@access_choice] +"'."; query_sql "SELECT `char_id` FROM `guild_member` WHERE `name` = '"+ .@access_list$[.@access_choice] +"'", .@member_id; query_sql "DELETE FROM `guild_storage_access` WHERE `char_id` = '"+ .@member_id +"'"; // Clear entries in temporary global array for (.@i = 0; .@i < getarraysize($@GS_Member); .@i++) { if ($@GS_Member[.@i] == .@member_id) { deletearray $@GS_Guild[.@i], 1; deletearray $@GS_Member[.@i], 1; } } break; case 2: break; } break; case 3: close; } } // Guild member access } else if (getcharid(2)) { // Check permission for (.@i = 0; .@i < getarraysize($@GS_Member); .@i++) { // Open storage if ($@GS_Member[.@i] == getcharid(0) && $@GS_Guild[.@i] == getcharid(2)) { message strcharinfo(0), "Guild storage opened."; guildopenstorage(); end; } } // Unauthorised access message strcharinfo(0), "You are not authorised to access guild storage."; // No guild } else { message strcharinfo(0), "You are not in a guild."; } // Fail message message strcharinfo(0), .@atcmd_command$ +" failed."; end; } And here's a quick script that'll clean any existing uses of the previous version: - script clean_gs_access -1,{ OnInit: query_sql "SELECT `guild_id` FROM `guild`", .@guild_id; for (.@i = 0; .@i < getarraysize(.@guild_id); .@i++) { for (.@j = 0; .@j < getarraysize(getd("$GS_Auth_"+ .@i)); .@j++) { setd "$GS_Auth_"+ .@i +"["+ .@j +"]", 0; } } end; }
  9. Aside from copying the values into temporary NPC variables (since multiple accesses to this script will continuously change the temporary global variables' values), a couple comparisons could be changed. This would be better written as one comparison: if ($@partymembercount < .MaxMembers || $@partymembercount > .MaxMembers ){ This is a single comparison and reads as "is not equal to": if ($@partymembercount != .MaxMembers ){ This could also be shortened: if ( compare( .@atcmd_parameters$, "A" || compare( .@atcmd_parameters$, "a" ) ) { if ( compare( .@atcmd_parameters$, "A|a" ) { And this line: if ( compare( .@atcmd_parameters$, "B" || compare( .@atcmd_parameters$, "b" ) ) { if ( compare( .@atcmd_parameters$, "B|b" ) {
  10. I left a bunch of comments for the sake of learning purposes; I write my code in sections, so you should have a pretty easy time going over each feature. Read through the documentation and the Wiki for things you don't understand, but a lot of the code is self-explanatory when you get the hang of it. d:
  11. You could also bind a script to @warp to prevent specific groups from accessing maps you want blacklisted. Here's an example: - script at_warp -1,{ OnInit: // Define map blacklist setarray .blacklist[0], "abbey02", "ra_san05", "thor_v03", "lhz_dun01", "lhz_dun02", "lhz_dun03", "payg_cas04", "abbey03", "thana_boss"; // Restricted group IDs setarray .map_restrict[0], 1, 2, 3; // Group level command access .cmd_access = 40; // Bind command to script event bindatcmd "warp", strnpcinfo(3) +"::OnAtcommand", .cmd_access, .cmd_access; end; OnAtcommand: // Loop through restricted group IDs for (.@i = 0; .@i < getarraysize(.blacklist); .@i++) { // Continue if group ID is blacklisted if (getgroupid() == .map_restrict[.@i]) { // Loop through blacklist for (.@j = 0; .@j < getarraysize(.blacklist); .@j++) { // Error if destination is blacklisted if (.@atcmd_parameters$[0] == .blacklist[.@j]) { message strcharinfo(0), "You are not authorised to warp to this map."; end; } } } } // Warp to destination warp .@atcmd_parameters$[0], atoi(.@atcmd_parameters$[1]), atoi(.@atcmd_parameters$[2]); end; }
  12. Here's my method, which uses dynamic global variables in place of an SQL table: - script guildstorage -1,{ // Function: Return character name of sent ID function getcharname { query_sql("SELECT `name` FROM `char` WHERE `char_id` = '"+ getarg(0) +"'", .@query_name$); return .@query_name$; } OnInit: // Configuration bindatcmd "guildstorage", strnpcinfo(3) +"::OnAtcommand", 0, 0; bindatcmd "gstorage", strnpcinfo(3) +"::OnAtcommand", 0, 0; end; OnAtcommand: // Guild master access if (getguildmasterid(getcharid(2)) == getcharid(0)) { while (1) { switch (select("Open storage:Change permissions:End session")) { case 1: // Open storage message strcharinfo(0), "Guild storage opened."; guildopenstorage(); close; case 2: // Clear looped data cleararray .@access_list$[0], "", getarraysize(.@access_list$); cleararray .@member_list$[0], "", getarraysize(.@member_list$); .@j = 0; // Build access list for (.@i = 0; .@i < getarraysize(getd("$GS_Auth_"+ getcharid(2))); .@i++) { .@access_list$[.@j++] = getcharname(getd("$GS_Auth_"+ getcharid(2) +"["+ .@i +"]")); } // Inject "Add new member" option .@access_list$[getarraysize(.@access_list$)] = "Add new member"; // Inject "Go back" option .@access_list$[getarraysize(.@access_list$)] = "Go back"; // Select member to modify menu implode(.@access_list$, ":"), -; .@access_choice = @menu - 1; // Check if last option selected if (@menu == getarraysize(.@access_list$)) { break; } // Check if second to last option selected if (@menu == getarraysize(.@access_list$) - 1) { // Build member list query_sql "SELECT `name` FROM `guild_member` WHERE `guild_id` = '"+ getcharid(2) +"'", .@member_list$; // Inject "Go back" option .@member_list$[getarraysize(.@member_list$)] = "Go back"; // Add new member menu implode(.@member_list$, ":"), -; .@member_choice = @menu - 1; // Check if last option selected if (.@member_choice == getarraysize(.@member_list$)) { break; } // Add member's ID to array query_sql "SELECT `char_id` FROM `guild_member` WHERE `name` = '"+ .@member_list$[.@member_choice] +"'", .@member_id; message strcharinfo(0), "Granted guild storage access for '"+ .@member_list$[.@member_choice] +"'."; setd "$GS_Auth_"+ getcharid(2) +"["+ getarraysize(getd("$GS_Auth_"+ getcharid(2))) +"]", .@member_id; break; } // Revoke access switch (select("Revoke access:Go back")) { case 1: message strcharinfo(0), "Revoked guild storage access for '"+ getcharname(getd("$GS_Auth_"+ getcharid(2) +"["+ .@access_choice +"]")) +"'."; deletearray getd("$GS_Auth_"+ getcharid(2) +"["+ .@access_choice +"]"), 1; break; case 2: break; } break; case 3: close; } } // Guild member access } else if (getcharid(2)) { // Check permission for (.@i = 0; .@i < getarraysize(getd("$GS_Auth_"+ getcharid(2) +"["+ .@i +"]")); .@i++) { // Open storage if (getd("$GS_Auth_"+ getcharid(2) +"["+ .@i +"]") == getcharid(0)) { message strcharinfo(0), "Guild storage opened."; guildopenstorage(); end; } } // Unauthorised access message strcharinfo(0), "You are not authorised to access guild storage."; // No guild } else { message strcharinfo(0), "You are not in a guild."; } message strcharinfo(0), .@atcmd_command$ +" failed."; end; } This supports guildmaster changes and up to 128 members (not sure if rA has limitless arrays), though the typical maximum number of guild members is 76. A guild master can access the control panel and either grant or revoke member access. Edit: Removed debug code.
  13. Typo D: *fixes* prontera,180,180,5 script name 74,{ .@password$ = "ojinioj"; input .@test$; if ( .@test$ != .@password$ ) end; warp "inhuionh",0,0; }
  14. Inject a blacklist to check for items. setarray .@blacklist[0], 1201, 1202, 1203, 607; for (.@i = 0; .@i < getarraysize(.@blacklist); .@i++) { if (countitem(.@blacklist[.@i])) { message strcharinfo(0), getitemname(.@blacklist[.@i]) +" is restricted from this map."; warp "SavePoint", 0, 0; end; } }
  15. Uh...this is still wrong lol; in fact, it wouldn't even work on eAthena or eAmod. The proper conversion would be: set Zeny, Zeny + .gain_zeny;Variables that were set in a similar manner should follow this conversion for the script to run properly; that or just drop eAmod and use a real emulator.
  16. If you read the documentation (or even just look up some of the commands used in this script), you'll find it very easy to decipher. Here's a stripped version of the script with only what you need: - script floating_rates -1,{ OnClock0000: // Configuration .base_rate = rand(10000, 15000); // Base EXP rate .job_rate = rand(10000, 15000); // Job EXP rate // Adjust rates setbattleflag("base_exp_rate", .base_rate); setbattleflag("job_exp_rate", .job_rate); // Reload the database atcommand "@reloadmobdb"; end; OnMinute01: // Announce current rates on the first minute of every hour announce "Double EXP is currently in affect with 1."+ (.base_rate - 100) +"x/1."+ (.job_rate - 10000) +"x rates", bc_all, 0xFF6060; end; } I also removed the temporary global variables and just placed the announcer in the same script. I'm not sure why the original author needed separate scripts for a basic functionality. o_o
  17. Add this under the OnPCLoadMapEvent label to determine whether or not it's Saturday: if (gettime(4) == 6) { end; }
  18. Missingno

    GM Area

    Why are you using a global $ variable? The scope in which the variable ($activeS) is needed would be appropriate as an NPC . variable (.activeS).
  19. Punch this code in after retrieving the desired item ID to be bound: // Item IDs that cannot be bound setarray .@blacklist[0], 1201, 1207, 2301; // Check blacklist for (.@i = 0; .@i < getarraysize(.@blacklist); .@i++) { if (@inventorylist_id[.@item] == .@blacklist[.@i]) { mes "Sorry, but "+ getitemname(@inventorylist_id[.@item]) +" is blacklisted from being bound."; close; } }
  20. Go to your PayPal settings and add the notification URL to your IPNs: http://yourwebsite.com/?module=donate&action=notify
  21. Just change the way that the variables are being set. In rAthena, they can be set two ways: set .var, 0; .var = 0; Both lines in the above example have the same result. In eAthena, the proper way is to use set, so in your case, replace these lines: .string$ = ""; .status = 1; with these lines: set .string$, ""; set .status, 1; If there are any other variables being set in the former manner, simply replace them with set commands as needed.
  22. In conf/groups.conf, add item to your GM commands like this to enable (or disable) the char command: item: [true, true] Remember to set it to false for groups that inherit this group's commands and permissions if you don't intend the inheriting group(s) to have the char command as well.
  23. Might want to upgrade to rAthena if your script parser is so outdated that it doesn't know what to do without using set. Many scripts that are optimised for rAthena will appear to have compatibility issues. There isn't really that great of a reason to continue using eAthena anymore, quite honestly; unless you enjoy the multitude of bugs, of course.
  24. Run an SQL query for each table: DELETE FROM `inventory` WHERE `id` = '7179'; DELETE FROM `cart_inventory` WHERE `id` = '7179'; DELETE FROM `storage` WHERE `id` = '7179'; DELETE FROM `guild_storage` WHERE `id` = '7179';
  25. If they play behind the same router, they'll share their IP. If you're looking for a more "locked-down" solution, you may want to try using Harmony or a similar third-party program that allows for MAC address logging (in which case you'd need a slightly different method of retrieving and comparing computer identities). Even so, this could be bypassed in a matter of seconds by someone savvy enough to look around. You'd be better off logging hardware UIDs (as they are not so simply changed); if you figure that out, do share! ;> The best advice I can offer right now is to just not give anything worthwhile or transferable as a freebie, since such things are exploitable even with good third-party software. There's always the idea of centralised accounts with your website, but again you'd be relying on a third-party source as a comparison and still be vulnerable to exploitation.
×
×
  • Create New...