//===== rAthena Script =======================================
//= Automated MVP Ladder and reward system
//===== By: ==================================================
//= pajodex
//===== Current Version: =====================================
//= 4.3
//===== Compatible With: =====================================
//= rAthena Project (pajodex)
//===== Description: =========================================
/*
- MVP Ladder which is fully automated.
- Just leave it on and NPC will do the rest.
- Easy configure
- Added @mvpreset command to reset the ladder. It will also reset the
monthly and weekly if it is on the '.day' and '.week' at settings
- Updated with latest mail command https://github.com/rathena/rathena/commit/5b13dc7009e312585bba0ea55d77fc5afa8aecad
New Feature:
* Event will only trigger to MVPs in their respective maps..
* If amon ra is killed outside moc_pryd06, script wont trigger..
*/
//=====******** Note ********=================================
//= if you find bugs or problem, please do tell DM me at
//= Discord (pajodex#1328) or rAthena (pajodex)
//= open for suggestions
//===== Additional Comments: =================================
// 1.0 - Initial release (MVP Kill standalone)
// 2.0 - Added SQL based with ladder
// Added automatic reward system
// Added functions
// Added bitwise variables
// Optimization
// 2.1 - Cleaned the script
// updated title
// 2.2 - Fixed error on reward if players are offline
// 2.3 - Added nobranch mapflags to all maps listed (Sukea23 via discord)
// 2.4 - Ranking fixed (reported by Sukea23)
// 3.0 - Script optimization and re-work
// added new ranker feature : view your rank
// added mvp ladder points system
// added simple mvp ladder shop
// 3.1 - Fix ranking issues on tie-cases (reported by Heikenz) https://rathena.org/board/topic/114565-utility-automated-mvp-ladder-reward-system/?do=findComment&comment=344981
// added item as currency support in ladder shop (Heikenz)
// modified F_CheckMvpLadder function
// Special Thanks to : AnnieRuru for mentoring me.
// 4.0 - Updated to latest svn
// Now uses *mail script command. You must UPDATE your trunk
// or apply this commit https://github.com/rathena/rathena/commit/5b13dc7009e312585bba0ea55d77fc5afa8aecad
// Script Optimization
// Script Rework
// Now uses a new SQL table that utilizes InnoDB instead of MyISAM
// 4.1 - Fix repeat reward issue. Reported by Emperor via Discord
// 4.2 - Fix loop reports.
// 4.3 - Fix missing MVP Shop
// -------------------------------------------------------
// How to use F_MVPReward:
// F_MVPReward ( <tablename>, <Num of players to get reward (default : 10)>, <rewardarrays> )
// This will allow you to set the number of players to receive
// the rewards. For small population server, you can set this to 5 or
// any amount as you wish.
// This update is in-response to Holograma's question in the post:
// https://rathena.org/board/topic/114565-utility-automated-mvp-ladder-reward-system/?tab=comments#comment-341725
//===== Credits goes to: =====================================
//= hurtsky
//= secret
//= sader1992
//= Stolao
//= Euphy
//= AnnieRuru
//=============================================================
prontera,165,104,3 script MVP Ranking 923,{
function F_CheckMvpLadder;
function F_CheckRank;
function F_MVPReset;
function F_MVPReward;
mes "How may I help you?";
switch(select("My Status",
(.
Option&1) ?
"Daily Ranking":"" ,
(.
Option&2) ?
"Weekly Ranking":"",
(.
Option&4) ?
"Monthly Ranking":"",
"All Time Ranking",
( getgmlevel() >
= 99 ) ?
"^ff0000[ GM ] Reset ladder^000000":"" ,
(.
Option&16) ?
"Open MVP Ladder Shop":"",
"Information",
"Nothing...")) {
case 1:
if(.Option&1)
{
query_sql("SELECT `day_kills`, 1+(SELECT COUNT(1) FROM `mvp_ladder_rank` t1 WHERE t1.day_kills > t2.day_kills) FROM `mvp_ladder_rank` t2 WHERE `char_id` = "+ getcharid(0), .@dkill_count, .@rank
);
if (.@dkill_count == 0) {
F_CheckRank ( "daily" );
} else {
mes " ~ ^FF0000" +.@dkill_count
+ "^000000 kills and ranks ^FF0000" +.@rank
+ "^000000 place today.";
}
}
if(.Option&2)
{
query_sql("SELECT `week_kills`, 1+(SELECT COUNT(1) FROM `mvp_ladder_rank` t1 WHERE t1.week_kills > t2.week_kills) FROM `mvp_ladder_rank` t2 WHERE `char_id` = "+ getcharid(0), .@wkill_count, .@rank
);
if (.@wkill_count
== 0) {
F_CheckRank ( "weekly" );
} else {
mes " ~ ^FF0000" +.@wkill_count
+ "^000000 kills and ranks ^FF0000" +.@rank
+ "^000000 place this week.";
}
}
if(.Option&4)
{
query_sql("SELECT `month_kills`, 1+(SELECT COUNT(1) FROM `mvp_ladder_rank` t1 WHERE t1.month_kills > t2.month_kills) FROM `mvp_ladder_rank` t2 WHERE `char_id` = "+ getcharid(0), .@mkill_count, .@rank
);
if (.@mkill_count
== 0) {
F_CheckRank ( "monthly" );
} else {
mes " ~ ^FF0000" +.@mkill_count
+ "^000000 kills and ranks ^FF0000" +.@rank
+ "^000000 place this month.";
}
}
query_sql( "SELECT all_kills, find_in_set( all_kills, ( SELECT group_concat( all_kills order by all_kills desc ) from mvp_ladder_rank ) ) from mvp_ladder_rank where char_id = "+ getcharid(0), .@akill_count, .@rank
);
mes " ~ Over all score of ^FF0000" +.@akill_count
+ "^000000 kills and ranks ^FF0000" +.@rank
+ "^000000 place all time.";
case 2:
F_CheckMvpLadder ( "day_kills" );
case 3:
F_CheckMvpLadder ( "week_kills" );
case 4:
F_CheckMvpLadder ( "month_kills" );
case 5:
F_CheckMvpLadder ( "all_kills" );
case 6:
switch(select((.
Option&1) ?
"Reset daily records":"",
(.
Option&2) ?
"Reset weekly records":"",
(.
Option&4) ?
"Reset monthly records":"",
"Reset everything")) {
case 1:
F_MVPReset ( "day_kills" );
case 2:
F_MVPReset ( "week_kills" );
case 3:
F_MVPReset ( "month_kills" );
case 4:
if ( select( "Confirm",
"Cancel" ) == 1 ) {
query_sql "TRUNCATE TABLE `mvp_ladder_rank`";
}
}
case 7:
if ( !.ladderitem ) {
if(!#MVPLADPOINTS) {
mes "You don't have any mvp points, you cant purchase anything.";
}
mes "You currently have "+ #MVPLADPOINTS
+" mvp ladder points.";
} else {
mes "You don't have any ^FF0000"+ getitemname( .
item ) +"^000000, you cant purchase anything.";
}
}
case 8:
// Information menu part
mes "Mvp ladder will automatically reset every day, week, and month.";
mes "Before the ladder resets, the TOP MVP Hunter will be rewarded via ^FF0000RODex^000000 (mail) during the next day 12:00 A.M.";
mes "Note that only MVPs on their respective maps will be counted in the ladder. MVP Arena or else where will not.";
if(.Option&16) {
mes "You can also gain 'MVP ladder points' for killing mvps for "+ .
point +" points per kill";
mes "If you are in a party, points will be divided equally to each party members.";
mes "Points can be used in MVP Ladder shop to buy items.";
}
default:
}
OnBuyItem:
if (@bought_nameid[.@i] == .Shop[.@j]) {
set .@cost, .@cost
+(.
Shop[.@j
+1]*@bought_quantity
[.@i
]);
}
if ( checkweight2 ( @bought_nameid, @bought_quantity ) == false ) {
mes "It appears you cant carry them all";
}
if ( !.ladderitem ) {
if (.@cost > #MVPLADPOINTS) {
mes "You don't have enough points to purchase anything in ladder shop.";
mes "You only have "+ #MVPLADPOINTS
+" points left.";
}
else {
mes "-----------------------------------";
getitem @bought_nameid
[.@i
], @bought_quantity
[.@i
];
mes " ^777777"+@bought_quantity
[.@i
]+"x "+getitemname(@bought_nameid
[.@i
])+"^000000";
}
mes "-----------------------------------";
#MVPLADPOINTS -= .@cost;
mes "You only have "+ #MVPLADPOINTS
+" points left.";
}
}
else {
mes "You don't have enough ^FF0000"+ getitemname( .
item ) +"^000000 to purchase anything in ladder shop.";
}
else {
mes "-----------------------------------";
getitem @bought_nameid
[.@i
], @bought_quantity
[.@i
];
mes " ^777777"+@bought_quantity
[.@i
]+"x "+getitemname(@bought_nameid
[.@i
])+"^000000";
}
mes "-----------------------------------";
}
}
OnNPCKillEvent:
.@solopoints = .mvp_id[.@i+1];
.@partypoints = .mvp_id[.@i+2];
if( .haltevent ) { // temporarily disable while giving away rewards to avoid bugs
dispbottom "Event is still giving away rewards. This kill wont not recorded.", 0xff0000;
}
query_sql( "INSERT INTO `mvp_ladder_rank` SET `char_id`='"+ getcharid(0) +"', `name`='"+ strcharinfo(0) +"', `day_kills` = '1', `week_kills` = '1', `month_kills` = '1', `all_kills` = '1' ON DUPLICATE KEY UPDATE `day_kills` = `day_kills` + 1, `week_kills`=`week_kills` + 1, `month_kills` = `month_kills` + 1,`all_kills` = `all_kills` + 1" );
if(.
Option&8 && rand(100) < .
chance)
{
.@annouce = true;
getitem .
solo_reward[.@p
], .
solo_reward[.@p
+1];
}
if(.Option&16) {
#MVPLADPOINTS += .@solopoints;
dispbottom "You got "+ .@solopoints
+" ladder points. Total: "+ #MVPLADPOINTS;
}
if ( .@annouce )
else
} else {
if ( rand(100) < .
chance )
.@chance = true;
if ( .@chance )
else
for ( .@q = 0; .@q < $@partymembercount; ++.@q ) {
if ( isloggedin( $@partymemberaid
[.@q
], $@partymembercid
[.@q
] ) ) {
if(.Option&16) {
#MVPLADPOINTS += .@partypoints / $@partymembercount;
dispbottom "--------------------------------------------";
dispbottom "You got "+ (.@partypoints
/ $@partymembercount
) +" mvp ladder points. Total: "+ #MVPLADPOINTS;
dispbottom "--------------------------------------------";
}
.@partymemberaid[.@c] = $@partymemberaid[.@q];
++.@c;
}
}
if ( .Option&8 && .@chance ) {
getitem .
party_reward[.@p
], .
party_reward[.@p
+1];
}
}
}
}
OnReward:
OnClock0000:
.haltevent = 1; // temporarily stops the event while giving of rewards.. (to avoid bugs)
if(.
Option&4 && gettime(DT_DAYOFMONTH
) == .
day ) {
F_MVPReward( "month_kills", 10, "Monthly", .monthly_rwd[.@i * 3], .monthly_rwd[.@i * 3 + 1], .monthly_rwd[.@i * 3 + 2] );
query_sql("UPDATE `mvp_ladder_rank` SET `month_kills` = '0'");
}
if(.
Option&2 && gettime(DT_DAYOFWEEk
) == .
week ) {
F_MVPReward( "week_kills", 10, "Weekly", .weekly_rwd[.@i * 3], .weekly_rwd[.@i * 3 + 1], .weekly_rwd[.@i * 3 + 2] );
query_sql("UPDATE `mvp_ladder_rank` SET `week_kills` = '0'");
}
if(.Option&1) {
F_MVPReward( "day_kills", 10, "Daily", .daily_rwd[.@i * 3], .daily_rwd[.@i * 3 + 1], .daily_rwd[.@i * 3 + 2] );
query_sql("UPDATE `mvp_ladder_rank` SET `day_kills` = '0'");
}
.haltevent = 0; // start again after..
OnInit:
query_sql("CREATE TABLE IF NOT EXISTS `mvp_ladder_rank` (`char_id` int(11) unsigned NOT NULL DEFAULT '0', `name` varchar(30) NOT NULL DEFAULT '',`day_kills` int(11) unsigned NOT NULL default '0',`week_kills` int(11) unsigned NOT NULL default '0',`month_kills` int(11) unsigned NOT NULL default '0',`all_kills` int(11) unsigned NOT NULL default '0', PRIMARY KEY (`char_id`)) ENGINE=InnoDB");
// Bitwise Variables
// 1 = enable daily reward and record
// 2 = enable weekly reward and record
// 4 = enable monthly reward and record
// 8 = enable mvp ladder item reward when killing MVP
// 16 = enable mvp ladder points when killing MVP & MVP Ladder shop
.Option = 1|2|4|8|16;
// NPC Name
.nm$ = "[ ^FF0000MVP Ranker^000000 ]";
// Point rewarded when mvp is killed (if Option 16 is enabled)
// This points is earned on ordinary mvps
.point = 100;
// Chance of getting an item (if Option 8 is enabled)
.chance = 10;
// Day of the month to automatically get reward
// Day of the week
.week = SUNDAY;
// Items for sale in MVP Shop
// <ID>, <PRICE>
13989, 1,
14004, 1,
17071, 8,
42091, 8,
42094, 20,
6228, 1000,
6232, 1000,
20431, 500,
20450, 500,
20031, 500,
20318, 500,
20406, 500,
20440, 500,
20737, 500,
20439, 500,
41001, 500,
41002, 500,
41003, 500,
41004, 500,
41005, 500,
41006, 500,
41007, 500,
41008, 500,
41009, 500,
41010, 500,
41011, 500,
41012, 500,
41013, 500,
41014, 500,
41015, 500,
41016, 500,
41017, 500,
41018, 500,
41053, 250,
41054, 250,
41055, 250,
41056, 250,
41057, 250;
setarray .
solo_reward,
// rewards for mvp killing
7712, 1, // Solo reward <item>, <amt>
7819, 1;
setarray .
party_reward,
// rewards for mvp killing
7712, 1, // Party reward <item>, <amt>
7819, 1;
// daily top 10 reward <ID>,<AMOUNT>,<ZENY>
14232,3,100000, // top 1
14232,2,90000,
14232,2,80000,
14232,2,70000,
14232,2,60000,
14232,2,50000,
14232,2,40000,
14232,2,30000,
14232,2,20000,
14232,1,10000; // top 10
// weekly top 10 reward <ID>,<AMOUNT>,<ZENY>
14232,3,100000, // top 1
14232,2,90000,
14232,2,80000,
14232,2,70000,
14232,2,60000,
14232,2,50000,
14232,2,40000,
14232,2,30000,
14232,2,20000,
14232,1,10000; // top 10
// monthly top 10 reward <ID>,<AMOUNT>,<ZENY>
14232,3,100000, // top 1
14232,2,90000,
14232,2,80000,
14232,2,70000,
14232,2,60000,
14232,2,50000,
14232,2,40000,
14232,2,30000,
14232,2,20000,
14232,1,10000; // top 10
// use @mvpreset command to reset the ladder. It will also reset the ...
// ... montly and weekly if it is on the .day and .week settings from above
// No branch mapflags on the maps listed..
// ladder shop
// ---------------------------------------------------------------------
// Don't touch anything from here or else you will ruin the whole script
// Unless you know what you are doing
// ---------------------------------------------------------------------
//
// IF YOU WANT TO ADD MORE MVP, MATCH THE MVP TO THE MAP TO MAKE IT WORK
// SAMPLE: >>> 1511, // AMON RA == "moc_pryd06" <<<
// If you are confused, contact me.
"moc_pryd06",
"lhz_dun03",
"ra_fild03",
"ra_fild04",
"ve_fild01",
"ve_fild02",
"lou_dun03",
"prt_maze03",
"bra_dun02",
"lhz_dun04",
"lhz_dun04",
"lhz_dun04",
"gld2_pay",
"gl_chyard",
"abyss_03",
"gef_dun02",
"gef_dun01",
"treasure02",
"pay_fild10",
"gon_dun03",
"abbey02",
"xmas_fild01",
"gld_ald",
"ra_san05",
"dic_dun03",
"prt_sewb4",
"mosk_dun03",
"lhz_dun04",
"lhz_dun03",
"lhz_dun03",
"thor_v03",
"ama_dun03",
"gld2_gef",
"kh_dun02",
"teg_dun02",
"xmas_dun02",
"iz_dun05",
"ice_dun03",
"ayo_dun02",
"dew_dun01",
"lhz_dun03",
"niflheim",
"anthell02",
"gld_dun02",
"mjolnir_04",
"gld_dun01",
"pay_dun04",
"gef_fild03",
"gef_fild10",
"moc_pryd04",
"lhz_dun04",
"in_sphinx5",
"moc_fild17",
"lhz_dun04",
"gld2_prt",
"dic_dun02",
"ein_dun02",
"moc_fild21",
"lhz_dun03",
"lhz_dun04",
"beach_dun",
"thana_boss",
"teg_dun01",
"tur_dun04",
"odin_tem03",
"jupe_core",
"lhz_dun03",
"moc_fild22",
"lhz_dun02",
"moc_prydn2",
"abbey03",
"abbey03",
"c_tower3_",
"prt_mz03_i",
"tur_d03_i",
"ein_d02_i",
"ein_d02_i",
"pay_d03_i",
"pay_d03_i",
"ice_d03_i",
"com_d02_i";
// <MVP ID>, <Solo Points>, <Party Points>
1511, 1, 12, // AMON RA
1647, 4, 12, // B_ERMES
1785, 2, 12, // ATROCE
1785, 2, 12, // ATROCE
1785, 2, 12, // ATROCE
1785, 2, 12, // ATROCE
1630, 1, 12, // BASCOJIN
1039, 2, 12, // BAPHOMET
2068, 1, 12, // BOITATA
2238, 1, 12, // B_CHEN
2240, 1, 12, // B_ALPHOCCIO
2236, 1, 12, // B_FLAMMEL
2253, 1, 12, // DAEHYON
1272, 1, 12, // DARK LORD
1719, 2, 12, // DETALE
1046, 1, 12, // DOPPELGANGER
1389, 1, 12, // DRACULA
1112, 1, 12, // DRAKE
1115, 1, 12, // EDDGA
1418, 1, 12, // EVIL SNAKE LORD
1871, 3, 12, // FALLEN BISHOP
1252, 1, 12, // GARM
2251, 1, 12, // GIOIA
1768, 3, 12, // GLOOMUNDERNIGHT
2165, 1, 12, // GOLDQUEENSCARABA
1086, 1, 12, // GTB
1885, 1, 12, // GOPINICH
2241, 1, 12, // B_TRENITI
1649, 4, 12, // B_MAGALETA
1651, 4, 12, // B_KATRIN
1832, 3, 12, // IFRIT
1492, 2, 12, // INCANTATION SAMURAI
2255, 1, 12, // KADES
1734, 3, 12, // KIEL
2442, 1, 12, // B_SUPERNOVICE
1251, 1, 12, // STORMY KNIGHT
2202, 1, 12, // KRAKKEN
1779, 2, 12, // KTULLANUX
1688, 2, 12, // LADY TANEE
2156, 1, 12, // LEAK
1646, 4, 12, // B_SEYREN
1373, 1, 12, // LORD OF DEATH
1147, 1, 12, // MAYA
1059, 1, 12, // MISTRESS
1059, 1, 12, // MISTRESS
1150, 1, 12, // MOONLIGHTFLOWER
1150, 1, 12, // MOONLIGHTFLOWER
1087, 1, 12, // ORC HERO
1190, 1, 12, // ORC LORD
1038, 1, 12, // OSIRIS
2235, 1, 12, // B_RANDEL
1157, 1, 12, // PHAROAH
1159, 1, 12, // PHREEONI
2237, 1, 12, // B_CELIA
2249, 1, 12, // ANGRYSTUDENY PYURIEL
2087, 1, 12, // GOLDEN QUEEN SCARAB
1623, 1, 12, // RSX12312
1916, 3, 12, // SATAN MORROC
1650, 4, 12, // B_CECIL
2239, 1, 12, // B_GERTIE
1583, 1, 12, // TAOGUNKA
1708, 1, 12, // THANATOS
2441, 1, 12, // B_NOVICE
1312, 1, 12, // TURTLE GEN
1751, 4, 12, // RANDGRIS
1685, 2, 12, // VESPER
1648, 4, 12, // B_HOWARD
1917, 4, 12, // WOUNDED MORROC
1658, 2, 12, // B_YGNIZEM
2362, 2, 12, // N_AMON_RA
1874, 2, 12, // BEELZEBUB
1873, 2, 12, // BEELZEBUB
3074, 2, 12, // Time Holder
20520, 2, 12, // Chaotic Baphomet
3804, 2, 12, // Ominous Turtle General
20260, 2, 12, // Shining Teddy Bear
3757, 2, 12, // Angry Dracula
3758, 2, 12, // Angry Moonlight
20273, 2, 12, // Ancient Tao Gunka
3796, 2, 12, // Awaken Ktullanux
20277, 2, 12; // Ancient Wootan Defender
function F_CheckMvpLadder {
if ( !(.@nb
= query_sql("SELECT `name`, `" + getarg(0) + "`, FIND_IN_SET(`" + getarg(0) + "`, (SELECT GROUP_CONCAT(`" + getarg(0) + "` ORDER BY `" + getarg(0) + "` DESC) FROM `mvp_ladder_rank`)) FROM `mvp_ladder_rank` ORDER BY `" + getarg(0) + "` DESC LIMIT 20", .@name$, .@value, .@rank
) ) ) {
mes "The rankings are empty.";
}
for ( .@i = 0; .@i < .@nb; ++.@i )
mes "["+ .@rank
[.@i
] +"] "+ .@name$
[.@i
] +" ~ ^FF0000"+ .@value
[.@i
] +"^000000 kills";
return;
}
function F_MVPReset {
if ( select( "Confirm",
"Cancel" ) == 1 ) {
}
return;
}
function F_CheckRank {
return;
}
function F_MVPReward {
query_sql("SELECT `char_id` FROM `mvp_ladder_rank` WHERE `"+ getarg(0) +"` ORDER BY CAST(`"+ getarg(0) +"` AS SIGNED) DESC LIMIT "+ getarg(1) +" ", .@cid
);
.@title$
= getarg(2)+" MVP Ladder reward";
.@body$
= "Congratulations! You have ranked #"+ (.@i
+1) +" in the "+ getarg(2) +" MVP ladder rankings!";
mail .@cid[.@i], "GM", .@title$, .@body$, .@zeny, .@mailitem, .@mailamount;
}
announce "Congratulations to our "+ getarg(1) +" TOP "+ getarg(2) +" MVP Hunters! Check your mails for rewards.",
bc_blue|
bc_all;
return;
}
}
- shop mvp_ladder_shop_q -1,607:-1 // dummyshop