Jump to content

playniks

Members
  • Posts

    46
  • Joined

  • Last visited

Posts posted by playniks

  1. 2 hours ago, Rynbef said:

    Here u can download the clients and some full clients of kro/ sakray.

     

    http://nemo.herc.ws/clients/

     

    Rynbef~

    Hi, Sir! Thank you for the response. But, ragexe clients on my nemo has these problems now (pls refer to the screenshot). I can download the client version on that website but it can't produce / or unpacked the client I needed which is the 20190530. That's why i'm asking for the clean version hoping that people have save a backup file of this said version of ragexe.image.png.6c828d48e4dd0047518cd6ec156a8d9e.png

  2. Hello! Could someone help me or share me a patch for gunslinger.

    When soul link it enables the use of any weapon-specific skills by using revolver and remove cast time of skill Tracking?

     

    Head's been aching finding a source file ☹️ with no luck at all. Please help! Please . . .😵

  3. 3 minutes ago, Poring King said:

    I don't have much time to dig in forum but i give you the idea already . If you want your asura be like old RO that so fast like WPE . You need to mess around with your SRC and you need Config file on your server .. . Or you can just use the old emulator to get that i think it will be around 2013 rAthena emulator but that's too old meaning lot of bugs 

    Alright, sir! thank you ^_^! Appreciate your time and effort on this. More power to you 🫡

  4. 11 hours ago, Poring King said:

    Seems like you are referring to old asura strike which is like High Rate server play style .There is a lot of things to do to fix this .. All you need is to make 0 all the delay , cast and after cast of the skill . The only problem that you will encounter here when you try to fix this is the Asura slide . Because it will look like a teleport asura with a delay because of the slide unless you know how to mess around with the SRC to fix it

    Hi, @Poring King! Thank you for that. I tried to remove the cast time, delay and after cast time of the skill not just by making them 0, but  the problem still persist.  I tried the ragexe version from 20190109 up to 2022 most of them have the same problem asura strike can't go instant casting, some of them can't be accessed due to this error about externsettings and was not able to proceed aside from this very one ragexe 20190703 which were able to resolved my problem. But sadly can't use a much earlier version, than 2019. I am still looking for a better resolution of this hoping that I could use an earlier version of ragexe, as well as resolving the externsettings error that I really am unable to figure out how to fix.
    I believe I am using a latest version of rathena emulator which I downloaded from github.

  5. 24 minutes ago, Winterfox said:

    To remove the cast fixed cast time you need to edit the skill_db.yml and remove this from the asura strike entry:

        FixedCastTime:
          - Level: 1
            Time: 2000
          - Level: 2
            Time: 1750
          - Level: 3
            Time: 1500
          - Level: 4
            Time: 1250
          - Level: 5
            Time: 1000

     

    Hi, thank you for responding! Fixed cast time is not included on the file of my asura strike.  Here's the data about my asura strike. I also tried to remove the casttime format on that file and still the issue persist. This asura strike is the only skill i know that won't go instant cast even when I maxed out the dex to 999.  A SUPER DUPER FAST CAST IS ALWAYS SHOWN. 😞 ;(

    - Id: 271
        Name: MO_EXTREMITYFIST
        Description: Asura Strike
        MaxLevel: 5
        Type: Weapon
        TargetType: Attack
        DamageFlags:
          IgnoreDefense: true
          IgnoreFlee: true
        Flags:
          TargetTrap: true
        Range: -2
        Hit: Single
        HitCount: 1
        CopyFlags:
          Skill:
            Plagiarism: true
            Reproduce: true
        CastCancel: true
        CastTime:
          - Level: 1
            Time: 4000
          - Level: 2
            Time: 3500
          - Level: 3
            Time: 3000
          - Level: 4
            Time: 2500
          - Level: 5
            Time: 2000
        AfterCastActDelay:
          - Level: 1
            Time: 3000
          - Level: 2
            Time: 2500
          - Level: 3
            Time: 2000
          - Level: 4
            Time: 1500
          - Level: 5
            Time: 1000
        Duration2: 300000
        Requires:
          SpCost: 1
          Weapon:
            Fist: true
            Dagger: true
            1hSword: true
            2hSword: true
            1hSpear: true
            2hSpear: true
            1hAxe: true
            2hAxe: true
            Mace: true
            2hMace: true
            Staff: true
            Knuckle: true
            Musical: true
            Whip: true
            Book: true
            Katar: true
            Revolver: true
            Rifle: true
            Gatling: true
            Shotgun: true
            Grenade: true
            Huuma: true
          Status:
            Explosionspirits: true
          SpiritSphereCost: 5
        Status: ExtremityFist

     

    EVEN WHEN DOING COMBO, THERE IS STILL CAST TIME WITH A SUPER DUPER FAST CAST.

  6. On 6/23/2023 at 4:45 AM, Hyoru said:

    Remove the Renewal Cast.

    src/config/renewal.hpp

    change:
    #define RENEWAL_CAST
    to this:
    //#define RENEWAL_CAST

    and then recompile.

    edit: if you wish to remove ONLY Asura Strike cast:
    Find on skill_db.yml:
      - Id: 271
        Name: MO_EXTREMITYFIST
        Description: Asura Strike
        FixedCastTime:
          - Level: 1
            Time: 2000
          - Level: 2
            Time: 1750
          - Level: 3
            Time: 1500
          - Level: 4
            Time: 1250
          - Level: 5
            Time: 1000


    Delete the fixed cast time.

    Hi, sir! Thank you for your response. I tried your ways however, the problem still exist. The skill_db.yml that I have doesn't have fixedcasttime format but instead casttime which I also tried to delete those.  If I were to check the source files for asura strike. Where do you think I should look for?

  7. Hello! I really need help about this ASURA STRIKE. My asura strike doesn't seem to activate instant cast even when dex reach x+y=150, I even maxed it out to 999 but still casting is  super duper fast cast.  All other skills working fine, doing insta cast when dex reach 150.  
    Tried to reduce the casting of Asura Strike level 5 in skill_db.yml to 1 and 0, but problem still persist.

    Please help, how do I resolve this issue?

  8. Bump!
    Hi! I manage to follow the steps add and remove some lines on the diff patch. However, I got this error and don't have any Idea what source file to look to debug the issue. I believe I correctly patch the file.

    what to do? Please help me, please.
    image.thumb.png.c61084ad9feb62477d1c9c701c6af7c2.png

     

    Disregard. Just missed some lines. Solve!

  9. 3 hours ago, paxtonleiny said:

     

    Whether or not I eliminate the map's mvp has no effect.
    for Mistress, check the following example:      I only want a kill to count when I am killing gon mvp in his original hideout (I've tried killing MISTRESS in its map at mjolnir_04 and pvp_n_2-2 and there's no purpose at all).  Where do we go from here?

    Hi! I actually made a separate script to count a kill on the specific hide out of certain mvp while waiting for somebody's help and manage to resolve my own issue. However, I had to make a custom file for each mvp (duplicate each mvp) and remove the MVP experience on each duplicates.

  10. 4 minutes ago, Chaos92 said:

    need to git commit for current changes if you didnt done it yet, and also git pull to latest rathena. 

    I didnt know whether this video might help or not but its similar to this.

     

    Awesome! Checking on it, sir! Thanks a lot!

  11. 1 hour ago, Chaos92 said:

    if your older rathena revision already using git, then u might git pull and maybe fix any conflicts if needed.

    How would I do that? Is there some guide that I could look? Haven't tried doing some pull actually.

  12. 2 hours ago, Chaos92 said:

    use latest rathena and its already in status.yml.

    status yml already implemented around last year https://github.com/rathena/rathena/pull/1685

    I see! Thanks a lot for your response sir, @Chaos92. As I check on the link you've provided, I'm not quite sure what specific file to pick to specifically get what I wanted.  I am actually trying to build a new server or technically speaking, I am now working on going back to zero, you know (setting up rathena-emulator, client and stuff). If I may ask, would it be possible to update my current rathena revision to the latest without affecting the changes I've made on my current rathena?

    Highly appreciated your time and effort on your response sir, Chaos92!. TY!

  13. Hi, Everyone especially to those experts of rAthena! xD How are you?

    I was wondering why my source rathena emulator doesn't have "STATUS.YML".  And when I found the file somewhere around rathena, add it inside my

    "trunk/ rathena pre-re/db"  ,  "trunk/ rathena pre-re/db/pre-re" and even in import-tmpl folder and run my server, my emulator doesn't seem to reload the file status.yml.

    May I ask for the source file/diff or some guide to activate or enable this status.yml file on my server?

    I badly needed the settings inside status.yml .  

    I would highly appreciate any help about this, I've been searching for it  and I'm so drained already. Posting really is my last resort I hope someone could help me about this. Thanks a lot, rAthena.
    Attached is the status.yml file.

    status.yml

  14. Permission to post admin, I hope I posted on the right section. Thank you!

    Hi can somebody help me how to do some src modification to colored the gray cell underneath the trap sprite below.
    "please see pic below."

    This trap sprite does have its cell colored "gray" underneath it aside from customizing the trap itself. 
    Can someone help me how to modify it or share a file for it, please? Thank you.

    image.png.58af1ba2ee8cd76cfad8f9171742b17d.png
    image.png.054e637c5d2c0553d827ca2b62f4ab72.png

  15. On 4/25/2023 at 3:46 PM, Emistry said:
    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0 && strcharinfo(3) == "YOUR_MAP_NAME"){

     

    conf/battle/drops.conf#L143-L150

    Hi @Emistry thank you so much for your response and I really appreciate it. However, as I try to follow your instruction about this "

    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0 && strcharinfo(3) == "YOUR_MAP_NAME"){


    It does not register whether I kill the mvp on its map or not.
    see example below for Mistress:      (tried killing MISTRESS in it's map at mjolnir_04 and pvp_n_2-2 and no point at all) and I only want a kill to register when killin gon mvp's original hideout..  What to do?

    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0 && strcharinfo(3) == "mjolnir_04"){
  16. Hi, this is the first time me posting, I just hope I am on the right path.
    Anyways, can anyone help edit this script

    1st. that could only announce mob being killed on mvp maps, 

    2nd.  register ranking that are killed only in mvp maps as well? 

    3rd and lastly broadcast rare drops (1%)

    Thank you guys!

    Quote

     //====== rAthena Script ======================================================
    //= MVP ladder script
    //===== By: ==================================================================
    //= Rokimoki but edited and adapted from AnnieRuru PVP Ladder
    //= https://herc.ws/board/topic/18871-dota-pvp-ladder/
    //= Mark Script fixed and adapted some small things
    //===== Current Version: =====================================================
    //= 2.1
    //===== Compatible With: =====================================================
    //= rAthena 2020-10-20, with MySQL 8.0
    //===== Description: =========================================================
    //= MVP ladder store in SQL table
    //= Requested by DevThor
    //===== Additional Comments: =================================================
    //= 1.0 initial version
    //= 2.0 added total kill count and fixed some sql bugs
    //= 2.1 fixed sql sorting rank
    //============================================================================

    /*
    CREATE TABLE `mvpladder` (
    	`id` int(11) NOT NULL AUTO_INCREMENT,
    	`char_id` int(11) unsigned NOT NULL default '0',
    	`mob_id` INT NOT NULL,
    	`kills` INT DEFAULT 0,
      	PRIMARY KEY (`id`),
    	INDEX (`char_id`),
    	INDEX (`mob_id`),
    	INDEX (`kills`)
    ) ENGINE=MyISAM AUTO_INCREMENT=1;
    */

    //---- MvP Ladder Logic Script

    -    script    MVPLadder    -1,{

    OnInit:
    // Config
        .map_killannounce = 1; // announce when MVP is dead on the map where the MVP was killed : 0 - off, 1 - on
        .killannounce = 1; // announce when MVP is dead globally : 0 - off, 1 - on
        .gmnokill = 0; // GMs are not suppose to kill MVP. A GM with <this number> level or higher will do nothing. IF set to 60, GM60 and above kill any player will not get anything : 0 - off

    //    .min_gm_menu = 90; // minimum level of GM can use the GM menu on ladder npc

        .showtotal = 20; // show the length of ladder.
        .showpage = 10;    // set the views per page.

        .showstatue = 5; // number of statues. This number must match with the number of duplicates at the end of the script
        .fix_custom_sprite = false; // if your server has custom animated sprite that overlaps the sprite animation repeatedly on the statues, enable this

    // Config ends ------------------------------------------------------------------------------------------

    //    to prevent bug happen
        if (.gmnokill <= 0) .gmnokill = 100;

        sleep 1;
        
    OnTimer1000: // refresh statues every 30 seconds. Note the `char` table is unrealiable, player still need to perform certain task to save the character -> see 'save_settings' in conf\map-server.conf
        .@query$ = "SELECT `char`.`char_id`, `char`.`name`, `char`.`guild_id`, `char`.`class`, "
                 + "`char`.`sex`, `char`.`hair`, `char`.`hair_color`, `char`.`clothes_color`, "
                 + "`char`.`body`, `char`.`head_top`, `char`.`head_mid`, `char`.`head_bottom`, `char`.`robe`, "
                 + "SUM(`mvpladder`.`kills`) as `orderKills` "
                 + "FROM `char` RIGHT JOIN `mvpladder` ON `char`.`char_id` = `mvpladder`.`char_id` GROUP BY `char`.`char_id` ORDER BY `orderKills` DESC LIMIT " + .showstatue;
        .@nb = query_sql(.@query$, .@cid, .@name$, .@guild_id, .@class, .@sex$, .@hair, .@hair_color, .@clothes_color, .@body, .@head_top, .@head_mid, .@head_bottom, .@robe, .@kills);
        if (.fix_custom_sprite) {
            for (.@i = 0; .@i < .@nb; ++.@i) {
                setunitdata .statue[.@i +1], UNPC_HEADTOP, 0;
                setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, 0;
                setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, 0;
                setunitdata .statue[.@i +1], UNPC_ROBE, 0;
            }
        }
        for (.@i = 0; .@i < .@nb; ++.@i) {
            setunitdata .statue[.@i +1], UNPC_CLASS, .@class[.@i];
            setunitdata .statue[.@i +1], UNPC_SEX, (.@sex$[.@i] == "F")? SEX_FEMALE:SEX_MALE;
            setunitdata .statue[.@i +1], UNPC_HAIRSTYLE, .@hair[.@i];
            setunitdata .statue[.@i +1], UNPC_HAIRCOLOR, .@hair_color[.@i];
            setunitdata .statue[.@i +1], UNPC_CLOTHCOLOR, .@clothes_color[.@i];
            setunitdata .statue[.@i +1], UNPC_BODY2, .@body[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADTOP, .@head_top[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, .@head_mid[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, .@head_bottom[.@i];
            setunitdata .statue[.@i +1], UNPC_ROBE, .@robe[.@i];
            setnpcdisplay "mvp_ladder_statue#"+(.@i +1), .@name$[.@i];
            .statue_name$[.@i +1] = .@name$[.@i];
            .statue_guild$[.@i +1] = getguildname(.@guild_id[.@i]);
            .statue_kills[.@i +1] = .@kills[.@i];
        }
        for (.@i = .@nb; .@i < .showstatue; ++.@i)
            setunitdata .statue[.@i +1], UNPC_CLASS, HIDDEN_WARP_NPC;
        initnpctimer;
        end;

    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0){
            .@selectIfKillExistQuery$ = "SELECT char_id, mob_id, kills FROM mvpladder WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "';";
            if (query_sql(.@selectIfKillExistQuery$) > 0) { // Exist a kill of that MVP so +1 to kill count
                .@updateLadderQuery$ = "UPDATE mvpladder SET kills = kills + 1 WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "'";
            } 
            else { // Create a new kill of specific MVP
                //.@updateLadderQuery$ = "INSERT INTO mvpladder (char_id, mob_id, kills) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
                .@updateLadderQuery$ = "INSERT INTO mvpladder (`char_id` , `mob_id` , `kills`) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
            }
            query_sql(.@updateLadderQuery$);
        }
        if ( getmonsterinfo(killedrid,MOB_MVPEXP) && (getgmlevel() < 99) )
            announce strcharinfo(0)+" has defeated "+getmonsterinfo(killedrid,0)+" at "+strcharinfo(3),0,0xFF0101;

    end;
    }
    //---- MvP Ladder Info NPC

    skycity,137,241,5    script    MVP Ladder    120,{
        .@npcname$ = strnpcinfo(0);
        while (1) {
            mes "["+ .@npcname$ +"]";
            mes "Hello "+ strcharinfo(0) +"...";
            mes "If you want to I can show you your MVP stats.";
            next;
            switch (select("Most MVP killer list","Most MVP killed list","Own Information")) {
            mes "["+ .@npcname$ +"]";
            case 1:
                .@queryKillerList$ = "SELECT t1.char_id, SUM(t1.kills) as `orderKills`, t2.name " +
                                     "FROM `mvpladder` t1 " +
                                     "INNER JOIN `char` t2 " +
                                     "ON t1.char_id = t2.char_id " +
                                     "GROUP BY t1.char_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKillerList$, .@charid, .@kills, .@name$);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i)
                        mes "^996600" + (.@i+1) + ": ^006699" + .@name$[.@i] + " ^00AA00[^FF0000" + .@kills[.@i] + " MvP^00AA00 killed]^000000";
                    next;
                }
                break;
                
            case 2:
                .@queryKilledList$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                     "FROM `mvpladder` " +
                                     "GROUP BY mob_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKilledList$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i) {
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                    }
                    next;
                }
                query_sql("SELECT SUM(kills) FROM mvpladder;", .@killCount);
                mes "^996600==> ^006699Total MvP Kills [^FF0000" + .@killCount[0] + " ^00AA00kills]^000000";
                break;
                
            case 3:
                .@queryOwnLadder$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                    "FROM `mvpladder` " +
                                    "WHERE char_id = '" + getcharid(0) + "'" +
                                    "ORDER BY `orderKills` DESC;";
                .@nb = query_sql(.@queryOwnLadder$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                .@totalKillCount = 0;
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i ) {    
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                        .@totalKillCount = .@totalKillCount + .@kills[.@i];
                    }
                    next;
                }
                mes "^996600==> ^006699Total Own MvP Kills [^FF0000" + .@totalKillCount + " ^00AA00kills]^000000";
                break;
            }
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("MVP Ladder");
        setnpctimer 0;
        end;
        }
    close;

    }

    //---- MSG board NPCs

    -    script    mvp_ladder_statue    -1,{
        .@id = getelementofarray(getvariableofnpc(.npcgid, "MVPLadder"), getnpcid(0));
        mes "^996600[TOP "+ .@id +"]";
        mes "^006699Name : "+ getelementofarray(getvariableofnpc(.statue_name$, "MVPLadder"), .@id);
        .@guildname$ = getelementofarray(getvariableofnpc(.statue_guild$, "MVPLadder"), .@id);
        mes "^00AAAAGuild : "+((.@guildname$ == "null")? "^AAAAAANone": .@guildname$);
        mes "^00AA00Total MVP Kills : ["+ getelementofarray(getvariableofnpc(.statue_kills, "MVPLadder"), .@id) +"]";
        close;

    OnInit:
        .@id = strnpcinfo(2);
        set getvariableofnpc(.statue[.@id], "MVPLadder"), getnpcid(0);
        set getvariableofnpc(.npcgid[getnpcid(0)], "MVPLadder"), .@id;
        end;
    }

    skycity,145,234,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#1    844
    skycity,145,230,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#2    844
    skycity,145,226,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#3    844
    //1@dth3,54,91,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#4    1_F_MARIA
    //1@dth3,47,83,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#5    1_F_MARIA

    skycity,145,234,5    script     #top1    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-1 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,230,5    script     #top2    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-2 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,226,5    script     #top3    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-3 MVP Killer");
        setnpctimer 0;
        end;
    }

    //1@dth3,54,91,5    script     #top4    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-4 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //}
    //
    //1@dth3,47,83,5    script     #top5    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-5 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //
    //}

    //====== rAthena Script ======================================================
    //= MVP ladder script
    //===== By: ==================================================================
    //= Rokimoki but edited and adapted from AnnieRuru PVP Ladder
    //= https://herc.ws/board/topic/18871-dota-pvp-ladder/
    //= Mark Script fixed and adapted some small things
    //===== Current Version: =====================================================
    //= 2.1
    //===== Compatible With: =====================================================
    //= rAthena 2020-10-20, with MySQL 8.0
    //===== Description: =========================================================
    //= MVP ladder store in SQL table
    //= Requested by DevThor
    //===== Additional Comments: =================================================
    //= 1.0 initial version
    //= 2.0 added total kill count and fixed some sql bugs
    //= 2.1 fixed sql sorting rank
    //============================================================================

    //---- MvP Ladder Logic Script

    -    script    MVPLadder    -1,{

    OnInit:
    // Config
        .map_killannounce = 1; // announce when MVP is dead on the map where the MVP was killed : 0 - off, 1 - o
        .killannounce = 1; // announce when MVP is dead globally : 0 - off, 1 - on
        .gmnokill = 0; // GMs are not suppose to kill MVP. A GM with <this number> level or higher will do nothing. IF set to 60, GM60 and above kill any player will not get anything : 0 - off

    //    .min_gm_menu = 90; // minimum level of GM can use the GM menu on ladder npc

        .showtotal = 20; // show the length of ladder.
        .showpage = 10;    // set the views per page.

        .showstatue = 5; // number of statues. This number must match with the number of duplicates at the end of the script
        .fix_custom_sprite = false; // if your server has custom animated sprite that overlaps the sprite animation repeatedly on the statues, enable this

    // Config ends ------------------------------------------------------------------------------------------

    //    to prevent bug happen
        if (.gmnokill <= 0) .gmnokill = 100;

        sleep 1;
        
    OnTimer1000: // refresh statues every 30 seconds. Note the `char` table is unrealiable, player still need to perform certain task to save the character -> see 'save_settings' in conf\map-server.conf
        .@query$ = "SELECT `char`.`char_id`, `char`.`name`, `char`.`guild_id`, `char`.`class`, "
                 + "`char`.`sex`, `char`.`hair`, `char`.`hair_color`, `char`.`clothes_color`, "
                 + "`char`.`body`, `char`.`head_top`, `char`.`head_mid`, `char`.`head_bottom`, `char`.`robe`, "
                 + "SUM(`mvpladder`.`kills`) as `orderKills` "
                 + "FROM `char` RIGHT JOIN `mvpladder` ON `char`.`char_id` = `mvpladder`.`char_id` GROUP BY `char`.`char_id` ORDER BY `orderKills` DESC LIMIT " + .showstatue;
        .@nb = query_sql(.@query$, .@cid, .@name$, .@guild_id, .@class, .@sex$, .@hair, .@hair_color, .@clothes_color, .@body, .@head_top, .@head_mid, .@head_bottom, .@robe, .@kills);
        if (.fix_custom_sprite) {
            for (.@i = 0; .@i < .@nb; ++.@i) {
                setunitdata .statue[.@i +1], UNPC_HEADTOP, 0;
                setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, 0;
                setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, 0;
                setunitdata .statue[.@i +1], UNPC_ROBE, 0;
            }
        }
        for (.@i = 0; .@i < .@nb; ++.@i) {
            setunitdata .statue[.@i +1], UNPC_CLASS, .@class[.@i];
            setunitdata .statue[.@i +1], UNPC_SEX, (.@sex$[.@i] == "F")? SEX_FEMALE:SEX_MALE;
            setunitdata .statue[.@i +1], UNPC_HAIRSTYLE, .@hair[.@i];
            setunitdata .statue[.@i +1], UNPC_HAIRCOLOR, .@hair_color[.@i];
            setunitdata .statue[.@i +1], UNPC_CLOTHCOLOR, .@clothes_color[.@i];
            setunitdata .statue[.@i +1], UNPC_BODY2, .@body[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADTOP, .@head_top[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, .@head_mid[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, .@head_bottom[.@i];
            setunitdata .statue[.@i +1], UNPC_ROBE, .@robe[.@i];
            setnpcdisplay "mvp_ladder_statue#"+(.@i +1), .@name$[.@i];
            .statue_name$[.@i +1] = .@name$[.@i];
            .statue_guild$[.@i +1] = getguildname(.@guild_id[.@i]);
            .statue_kills[.@i +1] = .@kills[.@i];
        }
        for (.@i = .@nb; .@i < .showstatue; ++.@i)
            setunitdata .statue[.@i +1], UNPC_CLASS, HIDDEN_WARP_NPC;
        initnpctimer;
        end;

    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0){
            .@selectIfKillExistQuery$ = "SELECT char_id, mob_id, kills FROM mvpladder WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "';";
            if (query_sql(.@selectIfKillExistQuery$) > 0) { // Exist a kill of that MVP so +1 to kill count
                .@updateLadderQuery$ = "UPDATE mvpladder SET kills = kills + 1 WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "'";
            } 
            else { // Create a new kill of specific MVP
                //.@updateLadderQuery$ = "INSERT INTO mvpladder (char_id, mob_id, kills) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
                .@updateLadderQuery$ = "INSERT INTO mvpladder (`char_id` , `mob_id` , `kills`) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
            }
            query_sql(.@updateLadderQuery$);
        }
        if ( getmonsterinfo(killedrid,MOB_MVPEXP) && (getgmlevel() < 99) )
            announce strcharinfo(0)+" has defeated "+getmonsterinfo(killedrid,0)+" at "+strcharinfo(3),0,0xFF0101;

    end;
    }
    //---- MvP Ladder Info NPC

    skycity,137,241,5    script    MVP Ladder    120,{
        .@npcname$ = strnpcinfo(0);
        while (1) {
            mes "["+ .@npcname$ +"]";
            mes "Hello "+ strcharinfo(0) +"...";
            mes "If you want to I can show you your MVP stats.";
            next;
            switch (select("Most MVP killer list","Most MVP killed list","Own Information")) {
            mes "["+ .@npcname$ +"]";
            case 1:
                .@queryKillerList$ = "SELECT t1.char_id, SUM(t1.kills) as `orderKills`, t2.name " +
                                     "FROM `mvpladder` t1 " +
                                     "INNER JOIN `char` t2 " +
                                     "ON t1.char_id = t2.char_id " +
                                     "GROUP BY t1.char_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKillerList$, .@charid, .@kills, .@name$);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i)
                        mes "^996600" + (.@i+1) + ": ^006699" + .@name$[.@i] + " ^00AA00[^FF0000" + .@kills[.@i] + " MvP^00AA00 killed]^000000";
                    next;
                }
                break;
                
            case 2:
                .@queryKilledList$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                     "FROM `mvpladder` " +
                                     "GROUP BY mob_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKilledList$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i) {
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                    }
                    next;
                }
                query_sql("SELECT SUM(kills) FROM mvpladder;", .@killCount);
                mes "^996600==> ^006699Total MvP Kills [^FF0000" + .@killCount[0] + " ^00AA00kills]^000000";
                break;
                
            case 3:
                .@queryOwnLadder$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                    "FROM `mvpladder` " +
                                    "WHERE char_id = '" + getcharid(0) + "'" +
                                    "ORDER BY `orderKills` DESC;";
                .@nb = query_sql(.@queryOwnLadder$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                .@totalKillCount = 0;
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i ) {    
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                        .@totalKillCount = .@totalKillCount + .@kills[.@i];
                    }
                    next;
                }
                mes "^996600==> ^006699Total Own MvP Kills [^FF0000" + .@totalKillCount + " ^00AA00kills]^000000";
                break;
            }
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("MVP Ladder");
        setnpctimer 0;
        end;
        }
    close;

    }

    //---- MSG board NPCs

    -    script    mvp_ladder_statue    -1,{
        .@id = getelementofarray(getvariableofnpc(.npcgid, "MVPLadder"), getnpcid(0));
        mes "^996600[TOP "+ .@id +"]";
        mes "^006699Name : "+ getelementofarray(getvariableofnpc(.statue_name$, "MVPLadder"), .@id);
        .@guildname$ = getelementofarray(getvariableofnpc(.statue_guild$, "MVPLadder"), .@id);
        mes "^00AAAAGuild : "+((.@guildname$ == "null")? "^AAAAAANone": .@guildname$);
        mes "^00AA00Total MVP Kills : ["+ getelementofarray(getvariableofnpc(.statue_kills, "MVPLadder"), .@id) +"]";
        close;

    OnInit:
        .@id = strnpcinfo(2);
        set getvariableofnpc(.statue[.@id], "MVPLadder"), getnpcid(0);
        set getvariableofnpc(.npcgid[getnpcid(0)], "MVPLadder"), .@id;
        end;
    }

    skycity,145,234,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#1    844
    skycity,145,230,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#2    844
    skycity,145,226,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#3    844
    //1@dth3,54,91,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#4    1_F_MARIA
    //1@dth3,47,83,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#5    1_F_MARIA

    skycity,145,234,5    script     #top1    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-1 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,230,5    script     #top2    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-2 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,226,5    script     #top3    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-3 MVP Killer");
        setnpctimer 0;
        end;
    }

    //1@dth3,54,91,5    script     #top4    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-4 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //}
    //
    //1@dth3,47,83,5    script     #top5    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-5 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //
    //}

    //====== rAthena Script ======================================================
    //= MVP ladder script
    //===== By: ==================================================================
    //= Rokimoki but edited and adapted from AnnieRuru PVP Ladder
    //= https://herc.ws/board/topic/18871-dota-pvp-ladder/
    //= Mark Script fixed and adapted some small things
    //===== Current Version: =====================================================
    //= 2.1
    //===== Compatible With: =====================================================
    //= rAthena 2020-10-20, with MySQL 8.0
    //===== Description: =========================================================
    //= MVP ladder store in SQL table
    //= Requested by DevThor
    //===== Additional Comments: =================================================
    //= 1.0 initial version
    //= 2.0 added total kill count and fixed some sql bugs
    //= 2.1 fixed sql sorting rank
    //============================================================================

    //---- MvP Ladder Logic Script

    -    script    MVPLadder    -1,{

    OnInit:
    // Config
        .map_killannounce = 1; // announce when MVP is dead on the map where the MVP was killed : 0 - off, 1 - o
        .killannounce = 1; // announce when MVP is dead globally : 0 - off, 1 - on
        .gmnokill = 0; // GMs are not suppose to kill MVP. A GM with <this number> level or higher will do nothing. IF set to 60, GM60 and above kill any player will not get anything : 0 - off

    //    .min_gm_menu = 90; // minimum level of GM can use the GM menu on ladder npc

        .showtotal = 20; // show the length of ladder.
        .showpage = 10;    // set the views per page.

        .showstatue = 5; // number of statues. This number must match with the number of duplicates at the end of the script
        .fix_custom_sprite = false; // if your server has custom animated sprite that overlaps the sprite animation repeatedly on the statues, enable this

    // Config ends ------------------------------------------------------------------------------------------

    //    to prevent bug happen
        if (.gmnokill <= 0) .gmnokill = 100;

        sleep 1;
        
    OnTimer1000: // refresh statues every 30 seconds. Note the `char` table is unrealiable, player still need to perform certain task to save the character -> see 'save_settings' in conf\map-server.conf
        .@query$ = "SELECT `char`.`char_id`, `char`.`name`, `char`.`guild_id`, `char`.`class`, "
                 + "`char`.`sex`, `char`.`hair`, `char`.`hair_color`, `char`.`clothes_color`, "
                 + "`char`.`body`, `char`.`head_top`, `char`.`head_mid`, `char`.`head_bottom`, `char`.`robe`, "
                 + "SUM(`mvpladder`.`kills`) as `orderKills` "
                 + "FROM `char` RIGHT JOIN `mvpladder` ON `char`.`char_id` = `mvpladder`.`char_id` GROUP BY `char`.`char_id` ORDER BY `orderKills` DESC LIMIT " + .showstatue;
        .@nb = query_sql(.@query$, .@cid, .@name$, .@guild_id, .@class, .@sex$, .@hair, .@hair_color, .@clothes_color, .@body, .@head_top, .@head_mid, .@head_bottom, .@robe, .@kills);
        if (.fix_custom_sprite) {
            for (.@i = 0; .@i < .@nb; ++.@i) {
                setunitdata .statue[.@i +1], UNPC_HEADTOP, 0;
                setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, 0;
                setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, 0;
                setunitdata .statue[.@i +1], UNPC_ROBE, 0;
            }
        }
        for (.@i = 0; .@i < .@nb; ++.@i) {
            setunitdata .statue[.@i +1], UNPC_CLASS, .@class[.@i];
            setunitdata .statue[.@i +1], UNPC_SEX, (.@sex$[.@i] == "F")? SEX_FEMALE:SEX_MALE;
            setunitdata .statue[.@i +1], UNPC_HAIRSTYLE, .@hair[.@i];
            setunitdata .statue[.@i +1], UNPC_HAIRCOLOR, .@hair_color[.@i];
            setunitdata .statue[.@i +1], UNPC_CLOTHCOLOR, .@clothes_color[.@i];
            setunitdata .statue[.@i +1], UNPC_BODY2, .@body[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADTOP, .@head_top[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, .@head_mid[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, .@head_bottom[.@i];
            setunitdata .statue[.@i +1], UNPC_ROBE, .@robe[.@i];
            setnpcdisplay "mvp_ladder_statue#"+(.@i +1), .@name$[.@i];
            .statue_name$[.@i +1] = .@name$[.@i];
            .statue_guild$[.@i +1] = getguildname(.@guild_id[.@i]);
            .statue_kills[.@i +1] = .@kills[.@i];
        }
        for (.@i = .@nb; .@i < .showstatue; ++.@i)
            setunitdata .statue[.@i +1], UNPC_CLASS, HIDDEN_WARP_NPC;
        initnpctimer;
        end;

    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0){
            .@selectIfKillExistQuery$ = "SELECT char_id, mob_id, kills FROM mvpladder WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "';";
            if (query_sql(.@selectIfKillExistQuery$) > 0) { // Exist a kill of that MVP so +1 to kill count
                .@updateLadderQuery$ = "UPDATE mvpladder SET kills = kills + 1 WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "'";
            } 
            else { // Create a new kill of specific MVP
                //.@updateLadderQuery$ = "INSERT INTO mvpladder (char_id, mob_id, kills) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
                .@updateLadderQuery$ = "INSERT INTO mvpladder (`char_id` , `mob_id` , `kills`) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
            }
            query_sql(.@updateLadderQuery$);
        }
        if ( getmonsterinfo(killedrid,MOB_MVPEXP) && (getgmlevel() < 99) )
            announce strcharinfo(0)+" has defeated "+getmonsterinfo(killedrid,0)+" at "+strcharinfo(3),0,0xFF0101;

    end;
    }
    //---- MvP Ladder Info NPC

    skycity,137,241,5    script    MVP Ladder    120,{
        .@npcname$ = strnpcinfo(0);
        while (1) {
            mes "["+ .@npcname$ +"]";
            mes "Hello "+ strcharinfo(0) +"...";
            mes "If you want to I can show you your MVP stats.";
            next;
            switch (select("Most MVP killer list","Most MVP killed list","Own Information")) {
            mes "["+ .@npcname$ +"]";
            case 1:
                .@queryKillerList$ = "SELECT t1.char_id, SUM(t1.kills) as `orderKills`, t2.name " +
                                     "FROM `mvpladder` t1 " +
                                     "INNER JOIN `char` t2 " +
                                     "ON t1.char_id = t2.char_id " +
                                     "GROUP BY t1.char_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKillerList$, .@charid, .@kills, .@name$);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i)
                        mes "^996600" + (.@i+1) + ": ^006699" + .@name$[.@i] + " ^00AA00[^FF0000" + .@kills[.@i] + " MvP^00AA00 killed]^000000";
                    next;
                }
                break;
                
            case 2:
                .@queryKilledList$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                     "FROM `mvpladder` " +
                                     "GROUP BY mob_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKilledList$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i) {
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                    }
                    next;
                }
                query_sql("SELECT SUM(kills) FROM mvpladder;", .@killCount);
                mes "^996600==> ^006699Total MvP Kills [^FF0000" + .@killCount[0] + " ^00AA00kills]^000000";
                break;
                
            case 3:
                .@queryOwnLadder$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                    "FROM `mvpladder` " +
                                    "WHERE char_id = '" + getcharid(0) + "'" +
                                    "ORDER BY `orderKills` DESC;";
                .@nb = query_sql(.@queryOwnLadder$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                .@totalKillCount = 0;
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i ) {    
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                        .@totalKillCount = .@totalKillCount + .@kills[.@i];
                    }
                    next;
                }
                mes "^996600==> ^006699Total Own MvP Kills [^FF0000" + .@totalKillCount + " ^00AA00kills]^000000";
                break;
            }
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("MVP Ladder");
        setnpctimer 0;
        end;
        }
    close;

    }

    //---- MSG board NPCs

    -    script    mvp_ladder_statue    -1,{
        .@id = getelementofarray(getvariableofnpc(.npcgid, "MVPLadder"), getnpcid(0));
        mes "^996600[TOP "+ .@id +"]";
        mes "^006699Name : "+ getelementofarray(getvariableofnpc(.statue_name$, "MVPLadder"), .@id);
        .@guildname$ = getelementofarray(getvariableofnpc(.statue_guild$, "MVPLadder"), .@id);
        mes "^00AAAAGuild : "+((.@guildname$ == "null")? "^AAAAAANone": .@guildname$);
        mes "^00AA00Total MVP Kills : ["+ getelementofarray(getvariableofnpc(.statue_kills, "MVPLadder"), .@id) +"]";
        close;

    OnInit:
        .@id = strnpcinfo(2);
        set getvariableofnpc(.statue[.@id], "MVPLadder"), getnpcid(0);
        set getvariableofnpc(.npcgid[getnpcid(0)], "MVPLadder"), .@id;
        end;
    }

    skycity,145,234,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#1    844
    skycity,145,230,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#2    844
    skycity,145,226,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#3    844
    //1@dth3,54,91,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#4    1_F_MARIA
    //1@dth3,47,83,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#5    1_F_MARIA

    skycity,145,234,5    script     #top1    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-1 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,230,5    script     #top2    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-2 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,226,5    script     #top3    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-3 MVP Killer");
        setnpctimer 0;
        end;
    }

    //1@dth3,54,91,5    script     #top4    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-4 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //}
    //
    //1@dth3,47,83,5    script     #top5    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-5 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //
    //}

     

    Quote

    //====== rAthena Script ======================================================
    //= MVP ladder script
    //===== By: ==================================================================
    //= Rokimoki but edited and adapted from AnnieRuru PVP Ladder
    //= https://herc.ws/board/topic/18871-dota-pvp-ladder/
    //= Mark Script fixed and adapted some small things
    //===== Current Version: =====================================================
    //= 2.1
    //===== Compatible With: =====================================================
    //= rAthena 2020-10-20, with MySQL 8.0
    //===== Description: =========================================================
    //= MVP ladder store in SQL table
    //= Requested by DevThor
    //===== Additional Comments: =================================================
    //= 1.0 initial version
    //= 2.0 added total kill count and fixed some sql bugs
    //= 2.1 fixed sql sorting rank
    //============================================================================

    //---- MvP Ladder Logic Script

    -    script    MVPLadder    -1,{

    OnInit:
    // Config
        .map_killannounce = 1; // announce when MVP is dead on the map where the MVP was killed : 0 - off, 1 - o
        .killannounce = 1; // announce when MVP is dead globally : 0 - off, 1 - on
        .gmnokill = 0; // GMs are not suppose to kill MVP. A GM with <this number> level or higher will do nothing. IF set to 60, GM60 and above kill any player will not get anything : 0 - off

    //    .min_gm_menu = 90; // minimum level of GM can use the GM menu on ladder npc

        .showtotal = 20; // show the length of ladder.
        .showpage = 10;    // set the views per page.

        .showstatue = 5; // number of statues. This number must match with the number of duplicates at the end of the script
        .fix_custom_sprite = false; // if your server has custom animated sprite that overlaps the sprite animation repeatedly on the statues, enable this

    // Config ends ------------------------------------------------------------------------------------------

    //    to prevent bug happen
        if (.gmnokill <= 0) .gmnokill = 100;

        sleep 1;
        
    OnTimer1000: // refresh statues every 30 seconds. Note the `char` table is unrealiable, player still need to perform certain task to save the character -> see 'save_settings' in conf\map-server.conf
        .@query$ = "SELECT `char`.`char_id`, `char`.`name`, `char`.`guild_id`, `char`.`class`, "
                 + "`char`.`sex`, `char`.`hair`, `char`.`hair_color`, `char`.`clothes_color`, "
                 + "`char`.`body`, `char`.`head_top`, `char`.`head_mid`, `char`.`head_bottom`, `char`.`robe`, "
                 + "SUM(`mvpladder`.`kills`) as `orderKills` "
                 + "FROM `char` RIGHT JOIN `mvpladder` ON `char`.`char_id` = `mvpladder`.`char_id` GROUP BY `char`.`char_id` ORDER BY `orderKills` DESC LIMIT " + .showstatue;
        .@nb = query_sql(.@query$, .@cid, .@name$, .@guild_id, .@class, .@sex$, .@hair, .@hair_color, .@clothes_color, .@body, .@head_top, .@head_mid, .@head_bottom, .@robe, .@kills);
        if (.fix_custom_sprite) {
            for (.@i = 0; .@i < .@nb; ++.@i) {
                setunitdata .statue[.@i +1], UNPC_HEADTOP, 0;
                setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, 0;
                setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, 0;
                setunitdata .statue[.@i +1], UNPC_ROBE, 0;
            }
        }
        for (.@i = 0; .@i < .@nb; ++.@i) {
            setunitdata .statue[.@i +1], UNPC_CLASS, .@class[.@i];
            setunitdata .statue[.@i +1], UNPC_SEX, (.@sex$[.@i] == "F")? SEX_FEMALE:SEX_MALE;
            setunitdata .statue[.@i +1], UNPC_HAIRSTYLE, .@hair[.@i];
            setunitdata .statue[.@i +1], UNPC_HAIRCOLOR, .@hair_color[.@i];
            setunitdata .statue[.@i +1], UNPC_CLOTHCOLOR, .@clothes_color[.@i];
            setunitdata .statue[.@i +1], UNPC_BODY2, .@body[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADTOP, .@head_top[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADMIDDLE, .@head_mid[.@i];
            setunitdata .statue[.@i +1], UNPC_HEADBOTTOM, .@head_bottom[.@i];
            setunitdata .statue[.@i +1], UNPC_ROBE, .@robe[.@i];
            setnpcdisplay "mvp_ladder_statue#"+(.@i +1), .@name$[.@i];
            .statue_name$[.@i +1] = .@name$[.@i];
            .statue_guild$[.@i +1] = getguildname(.@guild_id[.@i]);
            .statue_kills[.@i +1] = .@kills[.@i];
        }
        for (.@i = .@nb; .@i < .showstatue; ++.@i)
            setunitdata .statue[.@i +1], UNPC_CLASS, HIDDEN_WARP_NPC;
        initnpctimer;
        end;

    OnNPCKillEvent: // Logic to detect when a MvP is killed
        if (getmonsterinfo(killedrid, MOB_MVPEXP) > 0){
            .@selectIfKillExistQuery$ = "SELECT char_id, mob_id, kills FROM mvpladder WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "';";
            if (query_sql(.@selectIfKillExistQuery$) > 0) { // Exist a kill of that MVP so +1 to kill count
                .@updateLadderQuery$ = "UPDATE mvpladder SET kills = kills + 1 WHERE char_id = '" + getcharid(0) + "' AND mob_id = '" + killedrid + "'";
            } 
            else { // Create a new kill of specific MVP
                //.@updateLadderQuery$ = "INSERT INTO mvpladder (char_id, mob_id, kills) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
                .@updateLadderQuery$ = "INSERT INTO mvpladder (`char_id` , `mob_id` , `kills`) VALUES ('" + getcharid(0) + "','" + killedrid + "','1');";
            }
            query_sql(.@updateLadderQuery$);
        }
        if ( getmonsterinfo(killedrid,MOB_MVPEXP) && (getgmlevel() < 99) )
            announce strcharinfo(0)+" has defeated "+getmonsterinfo(killedrid,0)+" at "+strcharinfo(3),0,0xFF0101;

    end;
    }
    //---- MvP Ladder Info NPC

    skycity,137,241,5    script    MVP Ladder    120,{
        .@npcname$ = strnpcinfo(0);
        while (1) {
            mes "["+ .@npcname$ +"]";
            mes "Hello "+ strcharinfo(0) +"...";
            mes "If you want to I can show you your MVP stats.";
            next;
            switch (select("Most MVP killer list","Most MVP killed list","Own Information")) {
            mes "["+ .@npcname$ +"]";
            case 1:
                .@queryKillerList$ = "SELECT t1.char_id, SUM(t1.kills) as `orderKills`, t2.name " +
                                     "FROM `mvpladder` t1 " +
                                     "INNER JOIN `char` t2 " +
                                     "ON t1.char_id = t2.char_id " +
                                     "GROUP BY t1.char_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKillerList$, .@charid, .@kills, .@name$);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i)
                        mes "^996600" + (.@i+1) + ": ^006699" + .@name$[.@i] + " ^00AA00[^FF0000" + .@kills[.@i] + " MvP^00AA00 killed]^000000";
                    next;
                }
                break;
                
            case 2:
                .@queryKilledList$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                     "FROM `mvpladder` " +
                                     "GROUP BY mob_id " +
                                     "ORDER BY `orderKills` DESC " +
                                     "LIMIT " + getvariableofnpc(.showtotal, "MVPLadder") + ";";
                .@nb = query_sql(.@queryKilledList$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i) {
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                    }
                    next;
                }
                query_sql("SELECT SUM(kills) FROM mvpladder;", .@killCount);
                mes "^996600==> ^006699Total MvP Kills [^FF0000" + .@killCount[0] + " ^00AA00kills]^000000";
                break;
                
            case 3:
                .@queryOwnLadder$ = "SELECT char_id, mob_id, SUM(kills) as `orderKills` " +
                                    "FROM `mvpladder` " +
                                    "WHERE char_id = '" + getcharid(0) + "'" +
                                    "ORDER BY `orderKills` DESC;";
                .@nb = query_sql(.@queryOwnLadder$, .@charid, .@mobid, .@kills);
                if (!.@nb) {
                    mes "The ladder currently is empty.";
                    next;
                }
                .@totalKillCount = 0;
                for (.@j = 0; .@j < .@nb; .@j += getvariableofnpc(.showpage,"MVPLadder")) {
                    for (.@i = .@j; .@i < (getvariableofnpc(.showpage,"MVPLadder") + .@j) && .@i < .@nb; ++.@i ) {    
                        mes "^996600" + (.@i+1) + ": ^006699" + strmobinfo(1, .@mobid[.@i]) + " ^FF0000MvP ^00AA00[Killed ^FF0000" + .@kills[.@i] + " ^00AA00times]^000000";
                        .@totalKillCount = .@totalKillCount + .@kills[.@i];
                    }
                    next;
                }
                mes "^996600==> ^006699Total Own MvP Kills [^FF0000" + .@totalKillCount + " ^00AA00kills]^000000";
                break;
            }
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("MVP Ladder");
        setnpctimer 0;
        end;
        }
    close;

    }

    //---- MSG board NPCs

    -    script    mvp_ladder_statue    -1,{
        .@id = getelementofarray(getvariableofnpc(.npcgid, "MVPLadder"), getnpcid(0));
        mes "^996600[TOP "+ .@id +"]";
        mes "^006699Name : "+ getelementofarray(getvariableofnpc(.statue_name$, "MVPLadder"), .@id);
        .@guildname$ = getelementofarray(getvariableofnpc(.statue_guild$, "MVPLadder"), .@id);
        mes "^00AAAAGuild : "+((.@guildname$ == "null")? "^AAAAAANone": .@guildname$);
        mes "^00AA00Total MVP Kills : ["+ getelementofarray(getvariableofnpc(.statue_kills, "MVPLadder"), .@id) +"]";
        close;

    OnInit:
        .@id = strnpcinfo(2);
        set getvariableofnpc(.statue[.@id], "MVPLadder"), getnpcid(0);
        set getvariableofnpc(.npcgid[getnpcid(0)], "MVPLadder"), .@id;
        end;
    }

    skycity,145,234,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#1    844
    skycity,145,230,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#2    844
    skycity,145,226,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#3    844
    //1@dth3,54,91,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#4    1_F_MARIA
    //1@dth3,47,83,5    duplicate(mvp_ladder_statue)    mvp_ladder_statue#5    1_F_MARIA

    skycity,145,234,5    script     #top1    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-1 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,230,5    script     #top2    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-2 MVP Killer");
        setnpctimer 0;
        end;
    }

    skycity,145,226,5    script     #top3    111,{
    OnInit:
        initnpctimer;
        end;
    OnTimer1000:
        showscript("Top-3 MVP Killer");
        setnpctimer 0;
        end;
    }

    //1@dth3,54,91,5    script     #top4    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-4 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //}
    //
    //1@dth3,47,83,5    script     #top5    111,{
    //OnInit:
    //    initnpctimer;
    //    end;
    //OnTimer1000:
    //    showscript("Top-5 MVP Killer");
    //    setnpctimer 0;
    //    end;
    //
    //}

     

     

×
×
  • Create New...