Jump to content

plankt

Members
  • Posts

    130
  • Joined

  • Last visited

Posts posted by plankt

  1. [AI] Monster Invasion Event

    The monster invasion which will change difficulty depending on how well the players are doing!

    Description:

    This script will allow the users to go through a monster invasion event in three stages, helping a poor Banquet Houseman who can't finish his job. The monsters spawned are first determined by the level of the character, and then adjusted depending on how difficult it was for him/her.

    The player has 10 minutes to clear the three stages. If the player runs out of time, the HP is decreased for the spawned monsters, if the player finishes it in under 5 minutes, the HP is increased for the spawned monsters.

    If the player dies a lot of HP during the event, the damage is decreased for the spawned monsters and likewise if the player don't get hurt that much, the damage is increased.

    It will search for monsters in the table `mob_db` so if you don't want it to find custom mobs, add them to `mob_db2`.

    It will only find monsters who match these criteria:

    • Attack is above 1 and matches the difficulty
    • HP is above 1 and matches the difficulty
    • DEF and MDEF is below the users level
    • The monster can move and attack

    Note: At start it'll be easy for all levels. It will balance over time.

    Requirements:

    This script uses the queue system found here. You need to download and add it.

    You need to set up the config at the top of the script.

    Settings in the script:

    • Name of NPC
    • Which queue number it should have (leave this as 1 if you're unsure)
    • What map the event should use, make sure it's an empty map
    • Where the player enters the map
    • If donators/GMs should have priority in the queue system

    Prize:

    The script will look up the 100 rarest items owned by players on your server and give one of those.

    It determines the rarity by how many is owned overall by the players.

    Download link:

    http://rathena.org/b...58-ai-mobspawn/

    ai.txt

  2. Queue System

    The code is commented all the way through to ease the reading and understanding of it.

    Updates

    25/12: Redownload queue.txt, forgot silly quotation of a query at the bottom during testing.

    25/12: Updated example at the bottom of the post to keep pulling if it gets an error.

    27/12: Fixed a bug and optimized a variable, thanks KeyWorld. New version 1.01

    14/06: Did some minor optimizations and commented better for linked lists. New version 1.02. I decided to stick with getgmlevel since it's a better way to sort influential people out then groupid.

    If your server do not have table creation permission, please execute the query on line 29 separately.

    Please do not use or redistribute this script without giving proper credits. Report all bugs you notice!

    Files

    queue.txt - Version 1.02

    queue.txt - Version 1.01

    queue.txt - Version 1.00

    queuetest.txt - The script I used to bug test, good to check if unsure how to use the functions

    speedtest.txt - Please run this and reply with the values

    Prologue

    When you create a script involving more than one player at a time, you usually have to limit the script or access in an ugly kind of way, or build a kind of waiting hall where the players have to sit until it’s their turn. You never find the time to make a sleek waiting system for every script you make.

    You then remember playing another RPG where you could sign up, even sign up with friends, and you would be paired up with other people who signed up for the same event, battleground or PvP fight.

    Look no further; this Queue system is what you’re looking for!

    What is it?

    This is a system that you embed in to your own script. It’s simple in its function but also powerful to let you customize it exactly to match what you need for the moment.

    It lets you store players, parties or guilds in a queue. You can then retrieve them from that queue. Both actions have their own simple function call; “push” and “pull”.

    You only need the player attached when “pushing” them to the queue and you will receive a list of Account IDs when you “pull” players from the queue.

    Why would you, a mighty coder, use this system when you could just make it yourself? What makes it special enough to actually bother to include?

    This system lets you put players and parties in the same queue. You can then tell it to retrieve, say, 20 players for you. For the current event, you do not care if people join with friends or by themselves so it will put together 20 people within your customizations and makes sure to keep the parties unbroken. It will also make sure that the players, who have waited the most, get picked first.

    Features

    Are there any more awesome features? Yes!

    Full feature list:

    General:

    · Can support infinite amount of queues

    · The list uses MySQL so no queue is lost when restarting the server

    · Supports priority system (will be explained below)

    · Custom error codes so you will know exactly what went wrong

    · Supports linking events together (will be explained below)

    Push:

    · Supports single players, parties and guilds

    · Can set level required for the queue

    Pull:

    · Can return mixed players/parties

    · Can return only players

    · Can return parties only until X players are found

    · Can return a single party of a certain size

    · You can choose how many players to pull from the queue

    · If X players aren’t found, you can set it to return the IDs found or an error

    Priority system:

    If you want to make donators have a perk, if your event requires a champion to join fast or for any reasons don’t want players to wait, the priority system is something to use!

    If you set priority to a player, they will be put first in the queue, bypassing those who have been waiting. This can ONLY be used when pulling players or players and parties. You cannot give parties priority.

    Linked events:

    If you have some events that you want people to be able to queue for at the same time, linking events is for you!

    Say you have two events:

    1. Event 1
    2. Event 2

    You can put a link together in 2 possible ways.

    1) $@queue3[0], 1, 2; This will get players from queue 1 and 2 when asking for event 3.

    2) $@queue1[0], 3; $@queue2[0], 3; This will get players from queue 3 when asking for 1 or 2.

    What can I use it for?

    Say you are making any kind if event, battleground, PvP room or if you just like to put people in to a queue to then announce the time for them.

    All you have to worry about is (1) putting them in the queue and what should I do with the account IDs I’ve received when asking who was next in line. The rest just works.

    How can I use it?

    If you want a simple queue, you can just include the code and then copy/paste one of the examples below. If you want to make it fit perfectly in your script, then you should read up on the two functions described below.

    First of all, there’s a NPC at the top of the script file. If you want to link events (see information about linking above) then you should edit that NPC. The main two functions you will be interacting with are “push” and “pull”.

    The push function

    callfunc("push", arg(0), arg(1), arg(2), arg(3));

    • Type of input
      0. Player
      1. Party
      2. Guild

    • Event number; 0 means all events

    • Level required for the event

    • Should the member get priority?
      0. No
      1. If GM level is above 0
      2. Yes

    Function return values:

    0. Successful

    1. No player attached

    2. Base level too low

    3. Player is missing a party

    4. Party size is too small ( < 2 )

    5. A party member was offline

    6. A party member was too low level

    7. A player/guild was already in the queue

    8. Player is missing a guild

    9. Player is not guild leader

    The pull function

    This function sets two temporary, global variables. Make sure to copy them before the script gets another queue!

    • $@queue[] – Contains all the IDs wanted
    • $@queue_size – Contains the amount of IDs recieved

    callfunc("pull", arg(0), arg(1), arg(2), arg(3));

    • How you would like to search for players
      0. Both players and parties
      1. Only players
      2. Only parties
      3. Only guilds

    • Event number; 0 means all events

    • Amount of players wanted

    • Required to fill the group
      0. Returns the ones found, even if it couldn’t find the amount wanted
      1. Returns an error if it couldn’t find the amount wanted (If you’re searching for parties only, this will search for a party at exactly the size specified)

    Function return values:

    0. Successful

    1. Size wanted was 0

    2. Didn't get the required amount of players from the DB

    3. Didn't get the required amount of players after filtering

    Example:

    // Put the player in to the queue for event 1, lvl 5 is required
    callfunc("push", 0, 1, 5, 0);
    ...
    ...
    ...
    // Now I want to get 5 players for my event 1, I want to make sure I get all 5
    while(callfunc("pull", 0, 1, 5, 1)) sleep 100; // Keep pulling untill we don't have an error
    set .@queue_size, $@queue_size;
    copyarray .@queue[0], $@queue[0], .@queue_size;
    // Here I have all the account IDs in '.@queue' and I can use them as I want!
    

    I have included the NPC I used to bug test the script. It will show how you use the functions described above. It can also erase the content of the table and fill it with dummy data for testing.

    • Upvote 8
  3. Instead of 'dead' and 'dead2', you could have both pointing to 'dead'.

    I think you want 'sleep2 60000;' instead of 'OnMinute1:' (which should be 'OnMinute01:')

    Make sure they can't drop the item '2524' before the scripts tries to delete it, could get ugly.

    Same with '2421'

    Other then that, write down the different values of '#quest' and try to follow the script while you do the quests ingame.

  4. 'escape_sql()' is used on string variables, like '@password$', you want to use within the 'query_sql()' command

    Whenever you let the user provide information that will be used in the database, you should escape it.

    What it does: It makes sure the input is safe from injections, more info on wikipedia

    Example:

    The user inputs: Injecting code "+DELETE...+"
    escape_sql("Injecting code "+DELETE...+"");
    And it will become: Injecting code "+DELETE...+"
    

    And if you have a bug, you should provide more information regarding the bug.

    • Upvote 1
  5. Hey all! (updated 2012-05-26)

    The final exams for this year is finally done, so a lovely three months are free to be dedicated to lots of fun projects! If these competitions are wanted again, PM me the interest, and if three, or more, members are interested, I'll boot them up again.

    Last weeks winner:

    Wat (no winners yet)

    About the contest

    This is a contest which is meant to bring together coders throughout the community and let them try out their imagination, creativity and their ability to get everything down in a script. Also to let them see the mind of their fellow scripters, see how their codes differ to yours, and maybe pick up some hints and ideas on how to improve or solve something you had difficulties with.

    Everyone is welcome to participate, whether you’re a novice or an advanced coder, you can always have a great time and learn something on the way!

    Each week a category with a description and some requirements will be released. All those who want to participate can submit their work. At the end of each week the submissions will be judged based on:

    • Creativity of the finished work.
    • How well it fits in to the category and description provided.
    • How well it fits in to the game itself.
    • How well the code and provided resources are made.

    A winner will be announced with the new category and will also be featured on the post for the week out together with the work he/she made.

    I'll be updating with winners and new categories each week here and keep this topic for suggestions and feedback for the event itself and not for the submissions. Submissions will be delivered by email and released after the winner has been picked, with full credits to the makers.

    I would love to hear feedback on the subject, if there's any interest, what can be improved, what could be ditched, basically anything on your mind.

    Changes:

    10/1 - Elimination - Removed the limit of 60% needed eliminations per round.

    26/5 - Updated thread with new information

    Preview of Events ideas:

    • Artificial Intelligence
      The future is all about machines being able to interact with users.
    • Code obfuscation
      How hard can a Hello World program be to read? Time to find out.

    • Upvote 3
  6. First of all, when changing the time in the script, did you also change the time in 'dbquest_db.txt' for:

    60200,604800,0,0,0,0,0,0,"Endless Tower Effect"
    60201,14400,0,0,0,0,0,0,"Endless Tower Time Limit"
    

    If that didn't work, try this:

    Change this line:

    (Line number 363 @ https://rathena.svn....ndlessTower.txt)

    else if ((.@etower_timer >= 0) && (.@etower_timer < 2) && (.@etower_timer2 == 2)) {
    

    To this:

    else if ((.@etower_timer >= 0) && (.@etower_timer < 2) && (.@etower_timer2 == 2) && (.@dun_ent_t > 0)) {
    

    If it didn't work, does the script work for a new character? It seems the variable 'etower_timer' is messed up on your character from the old script. This leading to a time given which breaks the code.

  7. That depends on what you want to check for, and what you mean with didn't work? What jobs did/didn't work to change from?

    Lets take 'case 1' which is Lord Knight. I'm guessing only Knight should be able to do that change. Knight has the class number (according to 'dbconst.txt') 7 or 'Job_Knight'.

    If we check the users class, when the user is not Job_Knight, we want to jump to L_JbError

    User not Job_Knight -> Jump to L_JbError
    if(Class != Job_Knight) goto L_JbError;
    

  8. Almost everything I thought of has been mentioned, but to add on to the rest:

    When the first screen that meets you on a website is a "please register to see anything regarding the server"

    Badly developed systems such as:

    • WOE malfunctioning
    • Misplaced NPCs
    • Quests ending in nowhere or unsolvable
    • Events crashing

    Or when a GM randomly throws a @reloadscript when you almost killed a MVP, old classic haha

    • Upvote 3
  9. What you do with that check:

    (readparam(Class) < Job_Knight)
    

    Is that you allow all values over (including) 'Job_Knight' which is 7.

    That means that you will be able to change to Lord Knight if your job is above or equal to 7, say 'Job_Priest' which is 8, 'Job_Wizard' which is 9, and so on..

  10. Time sure flies off and it's still as fun to get back here /hmm

    The nick's Plankt, and I live in the cold Sweden... No, we do not have polar bears running on the streets (I got that question when I was in the US /omg)

    Been on and off for the last 5 years when I began writing small silly scripts with simple menus. Always been tinkering on small projects and being around scripting part of the forums whenever I've been able to. Got to say this is what made me start programming from the start, and it didn't take long until I went from language to language, can never get enough haha.

    Had very limited time since I've done military duty for a year and now I'm studying full time, but I tend to come back to this community and notice a lot of people I recognize along with many new faces.

    I love the game itself and will probably never stop tinkering around for as long as this continues and you'll probably find me around the scripting section since I pretty much suck at anything related to graphics or mapping... I'll at least make a shot at making a forum Avatar!

    Hope I'll meet you on the forums!

    • Upvote 1
  11. Jasc, the one who made this topic, should have it if he wants to share with you. Try asking him or do a search on the forums and you might find it.

    If you want to make it yourself, the chips are stored in the permanent char variable 'chips'. You can also try requesting it in the script request forum.

    • Upvote 1
  12. @calciumkid

    What I meant was that it should "sync" with the admin's IP address, not password. The password itself should still be something completely different.

    So that if the admins IP address changes, he/she can just log in to their account with the new IP address before being able to use the master password.

    Then the user have to both gain access to the admins account and try to figure out the master password, and all those attempts should raise a warning flag.

    But as you said, a lot of people have static IP addresses which would rend this unnecessary.

  13. You could save all clicks before the second is over in an array or two (one for the names and one for the times), and then when someone presses after the second is over, you check who's the closest to the time 1000.

    For the times before 1000, you just take (1000 - their time) and for the ones after: (their time - 1000)

    So basically:

    if(still under 1 sec){
    save name and (1000-time), you only need to save the one closest
    } else {
    stop event
    save name and (time-1000)
    check the one with lowest time difference
    announce winner
    }
    

    Commands which could help:

    - If/Else

    - *gettimetick(0)

    EDIT: Easily done w/o arrays.

  14. Combining your NPC with the pseudo-code:


    gm02,94,98,4 script Lower 793,{
    close; //Prevent them from talking to the NPC

    OnInit:

    //Arrays
    setarray .@lowerid[0],25200,25201,25202,25203,25204,25205,25206,25207,25208,25209,25210,25211,25212;
    setarray .@lowername$[0],"Angel Ears","Emperor Shoulders","Gangster Scarf","Ice Cream","Little Devil Tail","Neko no Shippo","Saiyan Tail","Scarlet Angel Ears","Jirachi Rucksack","Angeling Rucksack","ArchAngeling Rucksack","Deviling Rucksack","Pokeball Rucksack";

    //Regular expressions
    defpattern 1, "([^:]+):.*sNone(.*)", "LNone";
    for(set .@i,0; .@i < size(.@lowerid); set .@i, .@i+1){ //For each item
    defpattern 1, "([^:]+):s"+.@lowerid[.@i], getd("L"+.@lowerid[.@i]); //Make a pattern for the id pointing at the label L<id>
    defpattern 1, "([^:]+):s"+.@lowername$[.@i], getd("L"+.@lowerid[.@i]); //Make a pattern for the name pointing at the label L<id>
    }
    activatepset 1;

    end; //Finished with OnInit

    //Label for none
    LNone:
    if(!isequipped(24992)) end;
    setlook 3,0;
    npctalk strcharinfo(0) + " has changed his Dyna Lower Look!";
    end;

    //Label for item ID 25200, repeat for every item
    L25200:
    if(!isequipped(24992)) end; //Make sure they have the item equipped
    setlook 3,1700;
    npctalk strcharinfo(0) + " has changed his Dyna Lower Look!";
    end;
    }
    [/codeBOX]

    Not tested on a server so possible silly errors:

    - Syntax error

    - Wrong regexp

    After some online testing, try these expressions out if the previous don't work:

    [code]
    ([^:]+):.*None(.*) //For None
    //For the item ID
    defpattern 1, "([^:]+):.*"+.@lowerid[.@i], getd("L"+.@lowerid[.@i]);
    //For the item name
    defpattern 1, "([^:]+):.*"+.@lowername$[.@i], getd("L"+.@lowerid[.@i]);
    [/code]

  15. You must actually do a check for each variable.

    You can use AND logic to make sure the value doesn't exist or OR logic to check if any contains the value.

    if(@nx != @n1 && @nx != @n2 && ....)
    if(@nx == @n1 || @nx == @n2 || ...)
    

    Simple variable checks such as 'var && var && var' checks if they are not 0.

    With the first code:

    if (@nx != @n1 && @n2 && @n3 && @n4 && ect....) {
    

    You check if @nx != @n1 and then you check that @n2 != 0, @n3 != 0 and so on.

    • Upvote 1
  16. Did a quick scan of Trojals post and noticed that you have

    { bonus bSpeedRate,25; },{ setoption SC_MISC_RIDE,1; },{ setoption SC_MISC_RIDE,0; }
    

    While he has:

    { bonus bSpeedRate,25; },{ setoption Option_Misc_Ride,1; },{ setoption Option_Misc_Ride,0; }

    Other then that you could be missing the sprites or have a version of the client which doesn't work.

    I think I read that you need a newer then 2010-11-16 or 2011-05-++

    Try reading all the pages to see if someone had the same error as you did.

  17. It could often help to do a flowchart and then pseudo-code when you do a NPC and then turn it, a step at a time, in to code:

    1) What should the NPC do when ...

    Clicked on? -> Nothing -> Put a close/end at the beginning

    Spoken near? -> Register item ID or name and check if it matches a previously created pattern.

    -> We need to make the arrays

    -> We need to make the patterns (there's two ways to handle this, I'll get to that later on)

    2) Pseudo-code

    NPC header {
    (We could if we wanted to, present the user with a list of items so he/she dont have to remember it)
    close; (We do not want the user to click the NPC)
    OnInit: (What do we need to do before using the NPC?)
    1) Arrays for items
    2) Regular expressions
    end; (OnInit done)
    Labels and code for the RegExp (Here we also want to check for the equipped item since the code starts reading from each label)
    }
    

    The arrays are correct for you, I don't see why you put in those two for-loops since they only iterate through the arrays without changing anything.

    And if you want to have a loop inside another, you shouldn't use the same iteration variable for both (in this case .@i)

    Regular Expressions, "defpatterns", works like this:

    You give a pattern for a string to find, the parts that are inside round brackets will be set as a variable you can use! (We like this)

    So you can make 1 expression for each item OR pass the name or ID said and check if those are inside the arrays. (More convenient with larger arrays)

    Example of using names for the patterns: (I'm not showing how to manually make each pattern since everyone likes it dynamic, and also using a bit of lazy coding)

    for(i=0; i < size(.@lowerid); i++){ //For each item (Both lists should be the same size)
    defpattern 1, "([^:]+):s"+.@lowerid[ i ], getd("L"+.@lowerid[ i ]); //Make a pattern for the id pointing at the label L<id>
    defpattern 1, "([^:]+):s"+.@lowername$[ i ], getd("L"+.@lowerid[ i ]); //Make a pattern for the name pointing at the label L<id>
    }
    activatepset 1; //Activate the patterns we did
    end;
    
    //This is where the code starts reading for the user when they say a certain string, you want to check their items equipped etc. after the appropriate label.
    L25200:
    code for item 25200
    end;
    L25201:
    code for item 25201
    end;
    ... and so on
    

    Example of using general pattern for all:

    defpattern 1, "([^:]+).*)", "CheckItem";
    activatepset 1;
    end;
    
    CheckItem:
    set .@name$, $@p2$; (If the player said the item name)
    set .@id, atoi($@p2$); (If the player said the item ID)
    
    Now you loop through the arrays looking for any of those two, if you find a result, then you can do what you need to, otherwise just end;
    

    I'm not 100% sure that the patterns I used above are correct since I can't test them but they should give enough information for you to find the correct one from trial and error.

    There are also a lot of examples in https://rathena.svn....le/npc_pcre.txt

    I hope this all makes sense, otherwise just ask :D

    • Upvote 1
×
×
  • Create New...