//===== rAthena Script ======================================= //= Status/Weapon & MvP Mastery System //===== By =================================================== //= llchrisll //===== Version ============================================== //= 1.0 - Initial Version //= 2.0 - Major Update and bug fixes: // - Added the forgotten GM Setting > .gm // - Removed SQL Support // - Removed Custom Mobs // - Removed Mastery Bounding // - Removed Settings for using global cooardintes or specific // - Changed Map to 06guild_01 // - Added Training Fee/Requirement // - Added seperate Training Limit // - Simplified Delay for Status Mastery // - Removed nude; and Full Strip Debuffs at STR Training // - Removed Class Restriction // - Added Mob Spawn Quantity depending on Mastery Level // for Weapon and VIT Mastery // - Added setting how many different mobs should spawn at once // for Weapon and VIT Mastery // - Added more questions to INT Mastery // - Added ATK/MATK Formula Setting for the Weapon Boost // - Renamed a few variables // - Removed MVP Usage in Weapon Mastery // - Removed Debug Lines // - Merged StatusBonus NPC with the Mastery Trainer // - Changed the Mastery Boost to use an timer, so no need to recall it // - Added some npctalk in the DEX Training // - Added Mapflags: mf_nobaseexp, mf_nojobexp, mf_nocommand, mf_nopenalty // - Added an check to prevent boost message spams // - Added custom command to see your mastery levels // - Added MvP Mastery and MvP Ladder via SQL // - Removed the GM Panel // - Added an feature to only show the mastery of equipable weapons //= 2.1 - Fixxed an bug with the Mastery Boost //= 2.2 - Fixxed missing Limit Reset //===== Tested With ========================================= //= rAthena 12/24/2017 Revision //= GIT Hash: ae69e506263f9b183c945f49b1d88c5fc2b73a6a //===== Description ========================================== //= Handles a mastery system, which gives you extra bonuses // depending on the mastery level. //= There are Status and Weapon Mastery: // - Each Status Mastery has it's own training program // - Weapon Mastery is about killing Monsters //===== Comments ============================================= //= Thanks to GM Akira from AkiraRO for providing ideas and bug reports //===== SQL Tables ============================================= /* DROP TABLE IF EXISTS `swm_mvpladder`; CREATE TABLE `swm_mvpladder` ( `pty_mem1` varchar(255) default NULL, `pty_mem2` varchar(255) default NULL, `pty_mem3` varchar(255) default NULL, `pty_mem4` varchar(255) default NULL, `pty_mem5` varchar(255) default NULL, `pty_mem6` varchar(255) default NULL, `pty_mem7` varchar(255) default NULL, `pty_mem8` varchar(255) default NULL, `pty_mem9` varchar(255) default NULL, `pty_mem10` varchar(255) default NULL, `pty_mem11` varchar(255) default NULL, `pty_mem12` varchar(255) default NULL, `mvp_mobid` int(10) unsigned default NULL, `mvp_killtime` int(10) unsigned default NULL ) ENGINE=MyISAM; */ //===== ToDo List =========================================== //= None //=========================================================== prontera,150,180,4 script Mastery Trainer 110,{ mes .n$; mes "Welcome, "+strcharinfo(0)+"!"; if(getgroupid() >= .gm) switch(select("- Player Menu:- Reset Training Delay:- Delete Mastery Levels:- Give Fee Amount:- Set Mastery Levels")) { case 2: callfunc "DATA_D-M",1,.delay_type,1,0,1; callfunc "DATA_D-M",1,.delay_type,2,0,1; callfunc "DATA_D-M",1,.delay_type,3,0,1; set SWM_Status_Limit,0; set SWM_Weapon_Limit,0; mes "Delay reseted."; next; mes .n$; break; case 3: // Resetting Status for ( set .@st,0; .@st < 6; set .@st,.@st + 1) callfunc("DATA_D-M",2,1,.@st,1,0,2); // Resetting Weapons for ( set .@w,1; .@w < getarraysize(.eq_n$); set .@w,.@w + 1) if(.@w != 9) callfunc("DATA_D-M",2,2,.@w,1,0,2); // Resetting MvP Training callfunc("DATA_D-M",2,3,0,1,0,2); callfunc("DATA_D-M",2,3,1,1,0,2); mes "Deletion completed."; set SWM_Sys,0; next; mes .n$; break; case 4: switch(.train_fee) { case 0: break; case 1: // Zeny set Zeny,Zeny + .train_req_am; mes .train_req_am+"x Zeny recieved."; break; case 2: // Custom Points setd(""+.train_req_varn$),getd(""+.train_req_varn$) + .train_req_am; mes .train_req_am+"x "+.train_req_vard$+" recieved."; break; case 3: // Item mes .train_req_am+"x "+getitemname(.train_req_item)+" recieved."; getitem .train_req_item,.train_req_am; break; case 4: // Quest if(checkquest(.train_req_quest) != 2) { setquest .train_req_quest; completequest .train_req_quest; } mes "Quest has been completed."; break; } next; mes .n$; break; case 5: mes "Please choose which Status Mastery you want to change:"; next; set @p,select("- STR:- AGI:- VIT:- INT:- DEX:- LUK") - 1; mes .n$; mes "Now choose the Amount:"; mes "Note this will overwrite your current level and you can't go over "+.s_level+"!"; next; if(input(.@gm_st,0,.s_level) != 0) { mes .n$; mes "Invalid Amount."; close; } mes .n$; mes "The chosen Status Mastery has been changed."; callfunc("DATA_D-M",2,1,@p,1,.@gm_st,2); next; mes .n$; mes "Now put in the amount for the Weapon Mastery:"; mes "Note this will overwrite your current level and you can't go over "+.w_level+"!"; if(getequipid(9) == -1) { mes "But it seems like you didn't equip an weapon."; close; } next; if(input(.@gm_weap,0,.w_level) != 0) { mes .n$; mes "Invalid Amount."; close; } mes .n$; mes "The Weapon Mastery has been changed."; callfunc("DATA_D-M",2,2,getiteminfo(getequipid(9),11),1,.@gm_weap,2); next; mes .n$; break; default: break; } if(.delay_type) { mes "Status Mastery Limit: "+SWM_Status_Limit+"/"+.train_statlimit+" times"; mes "Weapon Mastery Limit: "+SWM_Weapon_Limit+"/"+.train_weaplimit+" times"; mes " "; } mes "These are your current levels:"; mes "[ === Status Mastery === ]"; setarray .@st_txt$[0],"STR","AGI","VIT","INT","DEX","LUK"; for ( set .@st,0; .@st < getarraysize(.@st_txt$); set .@st,.@st + 1) mes .@st_txt$[.@st]+" = "+callfunc("DATA_D-M",2,1,.@st,2); mes " "; mes "[ === Weapon Mastery === ]"; switch(BaseJob) { case Job_Novice: setarray .@weap_list[0],1,2,8; break; case Job_Swordman: case Job_Knight: case Job_Crusader: setarray .@weap_list[0],1,2,3,4,5,6,8; break; case Job_Mage: setarray .@weap_list[0],1,10; break; case Job_Wizard: setarray .@weap_list[0],1,10,23; break; case Job_Sage: setarray .@weap_list[0],1,10,15; break; case Job_Acolyte: setarray .@weap_list[0],8,10; break; case Job_Priest: setarray .@weap_list[0],8,10,15; break; case Job_Monk: setarray .@weap_list[0],8,10,12; break; case Job_Archer: case Job_Hunter: setarray .@weap_list[0],1,11; break; case Job_Bard: setarray .@weap_list[0],1,11,13; break; case Job_Dancer: setarray .@weap_list[0],1,11,14; break; case Job_Thief: case Job_Rogue: setarray .@weap_list[0],1,2,11; break; case Job_Assassin: setarray .@weap_list[0],1,2,6,8,16; break; case Job_Merchant: case Job_Blacksmith: case Job_Alchemist: setarray .@weap_list[0],1,2,6,7,8; break; case Job_Ninja: setarray .@weap_list[0],1,22; break; case Job_Gunslinger: setarray .@weap_list[0],17,18,19,20,21; break; } for ( set .@w,1; .@w < getarraysize(.eq_n$); set .@w,.@w + 1) { if(.@w == 9) continue; for ( set .@j,0; .@j < getarraysize(.@weap_list); set .@j,.@j + 1) if(.@w == .@weap_list[.@j]) mes .eq_n$[.@w]+" = "+callfunc("DATA_D-M",2,2,.@w,2); } mes " "; mes "[ === MvP Mastery === ]"; mes "MvP Mastery = "+callfunc("DATA_D-M",2,3,0,2); mes "MvP Kills = "+callfunc("DATA_D-M",2,3,1,2); mes " "; mes "How can I be of service to you?"; next; switch(select("- Mastery Training:- Information:- Apply Equip Bonus:- MvP Training:- Nothing")) { case 1: mes .n$; if(SWM_Sys == 0) { mes "Ahah a newcomer, welcome!!"; mes "Do you want to participate in my training programs?"; next; if(select("- Yes:- No") - 1) { mes .n$; mes "That's too bad, if you should change your mind by any chance, don't hesitate to come back."; close; } mes .n$; switch(.train_fee) { case 0: break; case 1: // Zeny mes "But I need an requirement from you first, which is to pay "+.train_req_am+"x Zeny."; mes "Do you agree?"; if(select("- Yes:- No") - 1) close; next; mes .n$; if(Zeny < .train_req_am) { mes "I'm sorry, you don't have enough Zeny."; close; } set Zeny,Zeny - .train_req_am; break; case 2: // Custom Points mes "But I need an requirement from you first, which is to pay "+.train_req_am+"x "+.train_req_vard$+"."; mes "Your current Balance is: "+getd(""+.train_req_varn$)+" "+.train_req_vard$; mes "Do you agree?"; if(select("- Yes:- No") - 1) close; next; mes .n$; if(getd(""+.train_req_varn$) < .train_req_am) { mes "I'm sorry, you don't have enough "+.train_req_vard$+"."; close; } setd(""+.train_req_varn$),getd(""+.train_req_varn$) - .train_req_am; mes "Your new Balance is: "+getd(""+.train_req_varn$)+" "+.train_req_vard$; break; case 3: // Item mes "But I need an requirement from you first, which is to pay "+.train_req_am+"x "+getitemname(.train_req_item)+" (ID: "+.train_req_item+"."; mes "Do you agree?"; if(select("- Yes:- No") - 1) close; next; mes .n$; if(countitem(.train_req_item) < .train_req_am) { mes "I'm sorry, you don't have enough "+getitemname(.train_req_item)+"."; close; } delitem .train_req_item,.train_req_am; break; case 4: // Quest mes "But I need an requirement from you first, you need the "+.train_req_quest_n$+" Quest completed."; mes "Do you agree?"; if(select("- Yes:- No") - 1) close; next; mes .n$; if(checkquest(.train_req_quest) != 2) { mes "I'm sorry, you didn't complete the "+.train_req_quest_n$+" Quest."; close; } break; } mes "Which Mastery do you want to start with?"; set SWM_Sys,1; } else mes "Which mastery do you want to try to improve this time?"; next; switch( set(@mastery,select("- Status Mastery:- Weapon Mastery")) ) { case 1: mes .n$; mes "What do you like to train?"; if(.train_s) { mes "^FF0000Note: The status mastery limit is active, so you can only train one status at once, if you want to train an another one you will lose the other ones.^000000"; next; for ( set .@s,0; .@s < 6; set .@s,.@s + 1) { if(set(.@s_c,callfunc("DATA_D-M",2,1,.@s,2)) > 0) { setarray .@s_s[.@s],.@s_c; set .@s_ct,.@s_ct + 1; } } if(.@s_ct > 1) { mes .n$; mes "You have more than one mastery training running."; mes "Please select the one you want to continue the training."; mes "Any other will be reseted afterwards."; } } set @p,select("- STR:- AGI:- VIT:- INT:- DEX:- LUK") - 1; if(.train_s) { mes .n$; mes "Chosen Status Mastery:"; switch(@p) { case 0: mes "STR"; break; case 1: mes "AGI"; break; case 2: mes "VIT"; break; case 3: mes "INT"; break; case 4: mes "DEX"; break; case 5: mes "LUK"; break; } mes "Is that correct?"; if(select("- Yes:- No") - 1) close; set .@p,.@s_s[@p]; for ( set .@o,0; .@o < 6; set .@o,.@o + 1) if(.@o == @p) callfunc "DATA_D-M",2,1,.@o,1,.@p,2; else callfunc "DATA_D-M",2,1,.@o,1,0,2; } next; mes .n$; if(callfunc("DATA_D-M",1,.delay_type,1,0,2) > gettimetick(2)) { mes "I'm sorry, but you are still exhausted from your previous training."; mes "Come back in "+callfunc("Time2Str",callfunc("DATA_D-M",1,.delay_type,1,0,2)); close; } else callfunc "DATA_D-M",1,.delay_type,1,0,3; set @stat,callfunc("DATA_D-M",2,1,@p,2); if(@stat >= .s_level) { mes "I'm sorry, but you have achieved the max level for this mastery already."; close; } switch(@p) { // ========= STR Training ========= case 0: if(getmapusers(.map$) != 0) { mes "I'm sorry, but there is someone practicing already."; mes "Please be patient."; close; } set @str_am,@stat/10; // Deciding Mob ID and Mob Name if(@stat <= 10) set @str_am,1; else if(@stat > 10 && @stat <= 20) set @str_am,2; else if(@stat > 20 && @stat <= 30) set @str_am,3; else if(@stat > 30 && @stat <= 40) set @str_am,4; else if(@stat > 40 && @stat <= 50) set @str_am,5; else if(@stat > 50 && @stat <= 60) set @str_am,6; else if(@stat > 60 && @stat <= 70) set @str_am,7; else if(@stat > 70 && @stat <= 80) set @str_am,8; else if(@stat > 80 && @stat <= 90) set @str_am,9; else if(@stat > 90 && @stat <= 100) set @str_am,10; mes "[ === STR Training === ]"; mes "This will be done by hitting on a single mob which always recieves 1 damage per attack, like a Plant would."; mes "Every 10th Level the Mob will respawn once more."; next; mes .n$; mes "I will now warp you to the practice map."; mes "Good luck."; close2; set @train,1; // In case there are still mobs left killmonsterall .map$; monster .map$,.str_mx,.str_my,"STR Training",.str_mid,@str_am,""+strnpcinfo(0)+"::OnStrMobDead"; warp .map$,.map_x,.map_y; end; // ========= AGI Training ========= case 1: // Setting countdown set @time,.agi_b_time - (@stat/.agi_x_red); // Getting random array index set @txt,rand(getarraysize(.agi_txt$)); mes "[ === AGI Training === ]"; mes "This will be done by typing an random text in "+@time+" seconds."; mes "The text is case-sensitive, be sure to write it correctly."; next; mes .n$; mes "Here is the text you need to type:"; mes "\""+.agi_txt$[@txt]+"\""; mes "The countdown will start after you press \"next\"."; next; set @a_t,0; // Resetting Counter attachnpctimer; initnpctimer; input @i_txt$; if(@i_txt$ != .agi_txt$[@txt]) { mes .n$; mes "The text you have input is wrong."; stopnpctimer; callfunc "DATA_D-M",1,.delay_type,1,.delay_time,1; close; } stopnpctimer; break; // ========= VIT Training ========= case 2: if(getmapusers(.map$) != 0) { mes "I'm sorry, but there is someone practicing already."; mes "Please be patient."; close; } // Calculating countdown if(@stat >= 10) set .@calc,.vit_inc*(@stat/10); set .cd,.vit_cd+.@calc; mes "[ === VIT Training === ]"; mes "This will be done by staying alive for "+.cd+" seconds."; mes "Also you are not allowed to kill any mob while the training is running."; mes "If you try you will not recieve any EXP and items, also you will be warped back to your savepoint."; // Setting Mob ID's depending on your Level if(BaseLevel >= 1 && BaseLevel <= 25) setarray .@mob[0],1023, // Orc Warrior 1015;// Zombie else if(BaseLevel >= 26 && BaseLevel <= 50) setarray .@mob[0],1028, // Soldier Skeleton 1033, // Elder Willow 1026, // Munak 1071, // Pirate Skeleton 1077, // Poison Spore 1100, // Argos 1169; // Skeleton Worker else if(BaseLevel >= 51 && BaseLevel <= 75) setarray .@mob[0],1036, // Ghoul 1029, // Isis 1041, // Mummy 1037, // Siderwinder 1061, // Nightmare 1065, // Strouf 1129, // Horong 1140, // Marduk 1069, // Swordfish 1119, // Frilldora 1152, // Orc Skeleton 1153, // Orc Zombie 1180, // Nine Tails 1188, // Bongun 1195; // Rideword else if(BaseLevel >= 76 && BaseLevel <= 90) setarray .@mob[0],1102, // Bathory 1099, // Argiope 1117, // Evil Druid 1143, // Marionette 1131, // Joker 1154, // Pasana 1155, // Petite Green 1156, // Petite Blue 1193, // Alarm 1192, // Wraith 1199, // Punk 1209, // Cramp 1256, // Pest 1263, // Wind Ghost 1269; // Clock else if(BaseLevel >= 91 && BaseLevel <= 99) setarray .@mob[0],1401, // Shinobi 1622, // Teddy Bear 1109, // Deviruchi 1408, // Bloody Butterfly 1692, // Breeze 1302, // Dark Illusion 1378, // Demon Pungus 1319, // Freezer 1318, // Heater 1515, // Garm Baby 1255, // Neraid 1257; // Injustice else if(BaseLevel >= 100 && BaseLevel <= 125) setarray .@mob[0],1668, // Archdam 1701, // Shelter 1627, // Anopheles 1736, // Aliot 1735, // Alicel 2016, // Aqua Elemental 1367, // Blazer 1268, // Bloody Knight 1738, // Constant 2015; // Dark Pinguicula else if(BaseLevel >= 126 && BaseLevel <= 150) setarray .@mob[0],1870, // Necromancer 1754, // Skeggiold 1918, // Incarnation of Morroc (Randgris) 1716, // Acidus Blue 1713, // Acidus Yellow 1769, // Agav 1654, // Armeyer Dinze 1753, // Frus 2132, // Pom Spider 1653; // Wickebine Tres else if(BaseLevel >= 151 && BaseLevel <= 175) setarray .@mob[0],2917, // Big Bell 2133, // Angra Mantis 1634, // Seyron Windsor 1636, // Howard Alt-Eisen 1637, // Margaretha Sorin 2367, // Blue Lichtern 2365, // Cenere 2371; // Faithful Manager set .@m_b,.vit_mob_am[@stat]; mes "These are the mobs, which will attack you:"; if(.vit_mob_s == 1) // Multiply Mobs while(set(.@c,.@c + 1) <= .vit_mob_spawn) { set .@a,0; set .@i,rand(getarraysize(.@mob)); while( set(.@a,.@a + 1) <= .@m_b) monster .map$,rand(.mob_x[0],.mob_x[1]),rand(.mob_y[0],.mob_y[1]),getmonsterinfo(.@mob[.@i],0),.@mob[.@i],1,strnpcinfo(1)+"::OnVitMobKill"; mes " > "+.@m_b+"x "+getmonsterinfo(.@mob[.@i],0); } else { // Single Mob set .@i,rand(getarraysize(.@mob)); while( set(.@a,.@a + 1) <= .@m_b) monster .map$,rand(.mob_x[0],.mob_x[1]),rand(.mob_y[0],.mob_y[1]),getmonsterinfo(.@mob[.@i],0),.@mob[.@i],1,strnpcinfo(1)+"::OnVitMobKill"; mes " > "+.@m_b+"x "+getmonsterinfo(.@mob[.@i],0); } mes "I will now warp you to the practice map."; mes "Good luck."; close2; addtimer(.cd*1000),strnpcinfo(0)+"::OnVitEnd"; set @train,1; setmapflag .map$,mf_noskill; warp .map$,.map_x,.map_y; end; // ========= INT Training ========= case 3: mes "[ === INT Training === ]"; mes "This will be done via a quiz about Ragnarok Online."; mes "You always have four answers available."; mes "Let's get started, should we?"; mes "Good luck."; set @int,0; // Reseting points // Every 10th level you need one more question to answer set @req,.int_pt + (@stat/10); // Creating question catalog & Counter set .@f,getarraysize(.int_quest$); while(.@c != .@f) { set .@x,rand(getarraysize(.int_quest$)); set .@rep,0; for ( set .@q,0; .@q < getarraysize(.@q_id); set .@q,.@q + 1) // Checking if the question has been put already if(.@q_id[.@q] == .@x) { set .@rep,1; break; } if(!.@rep) { setarray .@q_id[getarraysize(.@q_id)],.@x; set .@c,.@c + 1; } continue; } set .@q,0; while(.@q != .@f) { next; set .@ans$,""; // Creating Answers for ( set .@a,1; .@a <= 4; set .@a,.@a + 1) set .@ans$,.@ans$ + .@a+". "+getd(".int_ans"+.@a+"$["+.@q_id[.@q]+"]")+ ( (.@a < 4)?":":""); mes "Question #"+(.@q+1)+":"; mes "=================="; mes .int_quest$[.@q_id[.@q]]; // Selecting Answer next; set .@sel,select(.@ans$); // Correct Answer if(.@sel == .int_right[.@q_id[.@q]]) { set @int,@int + 1; mes .n$; mes "Correct Answer!!! +1 Point!!!"; mes "Current Points: "+@int; mes "Required Points: "+@req; } // Enough points to pass if(@int >= @req) break; set .@q,.@q + 1; } break; // ========= DEX Training ========= case 4: if(getmapusers(.map$) != 0) { mes "I'm sorry, but there is someone practicing already."; mes "Please be patient."; close; } mes "[ === DEX Training === ]"; mes "This will be done by clicking on the NPC, which moves to random spots around you."; mes "You won't be able to move during the training."; mes "I will now warp you to the practice map."; mes "Good luck."; close2; set @train,1; enablenpc "DEX Training"; doevent "DEX Training::OnPrepare"; warp .map$,.map_x,.map_y; end; // ========= LUK Training ========= case 5: mes "[ === LUK Training === ]"; mes "This will be done by guessing numbers from 1-10,"; set .@no,(@stat/10) + 1; // Numbers required mes "you have "+.luk_que+" chances where "+ .@no+" have to be correct."; mes "Good luck."; while( set(.@c_t,.@c_t + 1) != .luk_gue) { next; set .@c_no,rand(1,10); // Randomize input @g_no; if(@g_no == .@c_no) set .@ct,.@ct + 1; // Guessed number is the same as the randomed one, increase this counter mes .n$; mes "Number #"+.@c_t+":"; mes "Chosen number: "+@g_no; mes "Required number: "+.@c_no; mes "Correct numbers so far: "+.@ct; mes "Chances left: "+(.luk_gue-.@c_t); if(.@ct == .@no) break; // If the quantity of the corrected guesses is the same as the required one, continue } if(.@c_t == .luk_gue && .@ct != .@no) { mes "I'm sorry, but you have failed this training."; close; } break; } OnComplete: callfunc "DATA_D-M",2,1,@p,1,1,1; set SWM_Status_Limit,SWM_Status_Limit + 1; if(SWM_Status_Limit >= .train_statlimit) { callfunc "DATA_D-M",1,.delay_type,1,.delay_time,1; set SWM_Status_Limit,0; } dispbottom .n$+":The training has been completed, your mastery level has increased by 1."; set @train,0; set @p,0; set @SWMLogin,0; end; case 2: mes .n$; if(callfunc("DATA_D-M",1,.delay_type,2,0,2) > gettimetick(2)) { mes "I'm sorry, but you are still exhausted from your previous training."; mes "Come back in "+callfunc("Time2Str",callfunc("DATA_D-M",1,.delay_type,2,0,2)); close; } else callfunc "DATA_D-M",1,.delay_type,2,0,3; if(getmapusers(.map$) != 0) { mes "I'm sorry, but there is someone practicing already."; mes "Please be patient."; close; } if(getequipid(9) == -1) { mes "Hmm, I can't train your weapon since you don't have any equipped."; mes "Please make sure you have a weapon equipped before coming back."; close; } mes "Let's see, which weapon you have."; next; mes .n$; mes "\""+getequipname(9)+"\" is your current weapon."; mes "Do you want to train with it?"; if(select("- Yes:- No") - 1) close; next; mes .n$; for ( set .@e,0; .@e < getarraysize(.kill_weap); set .@e,.@e + 1) if(getiteminfo(getequipid(9),11) == .kill_weap[.@e]) { mes "I'm sorry, but I can't train your weapon, since it's forbidden."; close; } mes "Okay, I will now take a closer look at your weapon and then I will decide your enemies."; next; set @e,getiteminfo(getequipid(9),11); set @weap,callfunc("DATA_D-M",2,2,@e,2); if(@weap >= .w_level) { mes .n$; mes "I'm sorry, but you already achieved the max level of this mastery."; close; } // Setting Mob ID's depending on your Level if(BaseLevel >= 1 && BaseLevel <= 25) if(BaseClass == Job_Novice) setarray .@mob[0],1002, // Poring 1010, // Willow 1008, // Pupa 1007, // Fabre 1049; // Picky else setarray .@mob[0],1023, // Orc Warrior 1015, // Zombie 1014, // Spore 1013, // Wolf 1094, // Ambernite 1013, // Caramell 1011, // Chonchon 1005, // Familiar 1019; // Peco Peco else if(BaseLevel >= 26 && BaseLevel <= 50) setarray .@mob[0],1028, // Soldier Skeleton 1033, // Elder Willow 1026, // Munak 1071, // Pirate Skeleton 1077, // Poison Spore 1100, // Argos 1169, // Skeleton Worker 1095, // Andre 1060, // Bigfoot 1214, // Choco 1246, // Christmas Cookie 1121; // Giearth else if(BaseLevel >= 51 && BaseLevel <= 75) if(BaseClass == Job_Acolyte) setarray .@mob[0],1036, // Ghoul 1041, // Mummy 1152, // Orc Skeleton 1153; // Orc Zombie else setarray .@mob[0],1029, // Isis 1037, // Siderwinder 1061, // Nightmare 1065, // Strouf 1129, // Horong 1140, // Marduk 1069, // Swordfish 1119, // Frilldora 1180, // Nine Tails 1188, // Bongun 1195, // Rideword 1271, // Alligator 1415, // Baby Leopard 1110, // Dokebi 1118, // Flora 1126, // Goblin (Mace) 1369; // Grand Peco else if(BaseLevel >= 76 && BaseLevel <= 90) if(BaseClass == Job_Acolyte) setarray .@mob[0],1117, // Evil Druid 1192, // Wraith 1197; // Zombie Prisoner else setarray .@mob[0],1102, // Bathory 1099, // Argiope 1143, // Marionette 1131, // Joker 1154, // Pasana 1155, // Petite Green 1156, // Petite Blue 1193, // Alarm 1199, // Punk 1209, // Cramp 1256, // Pest 1263, // Wind Ghost 1269, // Clock 2152, // Comodo 1372; // Goat else if(BaseLevel >= 91 && BaseLevel <= 99) if(BaseClass == Job_Acolyte) setarray .@mob[0],1302, // Dark Illusion 1196, // Skeleton Prisoner 1198; // Dark Priest else setarray .@mob[0],1401, // Shinobi 1622, // Teddy Bear 1109, // Deviruchi 1408, // Bloody Butterfly 1692, // Breeze 1378, // Demon Pungus 1319, // Freezer 1318, // Heater 1515, // Garm Baby 1255, // Neraid 1257, // Injustice 1782, // Roween 1410; // Peach Tree else if(BaseLevel >= 100 && BaseLevel <= 125) if(BaseClass == Job_Acolyte) setarray .@mob[0],1699, // Ancient Mimic 1297, // Ancient Mummy 1098; // Anubis else setarray .@mob[0],1668, // Archdam 1701, // Shelter 1627, // Anopheles 1736, // Aliot 1735, // Alicel 2016, // Aqua Elemental 1367, // Blazer 1268, // Bloody Knight 1738, // Constant 2015, // Dark Pinguicula 1030, // Anacondaq 1992; // Cornus else if(BaseLevel >= 126 && BaseLevel <= 150) if(BaseClass == Job_Acolyte) setarray .@mob[0],1870, // Necromancer 2360, // Nightmare Ancient Mummy 2480; // Fallen Priest (Nightmare Evil Druid) else setarray .@mob[0],1754, // Skeggiold 1918, // Incarnation of Morroc (Randgris) 1716, // Acidus Blue 1713, // Acidus Yellow 1769, // Agav 1654, // Armeyer Dinze 1753, // Frus 2132, // Pom Spider 1653, // Wickebine Tres 2133, // Angra Mantis 2306, // Antique Book 2085; // Antler Scaraba else if(BaseLevel >= 151 && BaseLevel <= 174) if(BaseClass == Job_Acolyte) setarray .@mob[0],2283, // Abysmal Dark Priest 2990; // Corrupt Cruiser else setarray .@mob[0],2917, // Big Bell 2133, // Angra Mantis 1634, // Seyron Windsor 1636, // Howard Alt-Eisen 1637, // Margaretha Sorin 2367, // Blue Lichtern 2365, // Cenere 2371; // Faithful Manager else if(BaseLevel >= 175) if(BaseClass == Job_Acolyte) setarray .@mob[0],3018, // Corrupt Megalodon 3016, // Corrupt Orc Zombie 3017; // Corrupt Verit else setarray .@mob[0],3001, // Morroc's Ghoul 3002, // Morroc's Osiris 2919, // Neo Punk 2477, // Cursed Wanderer 3089, // Frenzied Kasa 3090, // Frenzied Salamander 3014, // Corrupt Desert Wolf 2920, // Arc Elder 3015, // Corrupt Phen 3013, // Corrupt Orc Warrior 3088, // Frost Spider 2916; // Big Ben set .@mob_am,.w_mob_am[@weap]; mes .n$; mes "Your enemies will be:"; if(getarraysize(.@mob) <= .w_mob_spawn) { // Currently only Acolyte Classes for ( set .@m,0; .@m < getarraysize(.@mob); set .@m,.@m + 1) { mes "> "+.@mob_am+"x "+getmonsterinfo(.@mob[.@m],MOB_NAME); setarray .@mob_c[getarraysize(.@mob_c)],.@mob[.@m]; } } else while(getarraysize(.@mob_c) < .w_mob_spawn) { set .@f,0; set .@r,rand(getarraysize(.@mob)); for ( set .@c,0; .@c < getarraysize(.@mob_c); set .@c,.@c + 1) if(.@mob_c[.@c] == .@mob[.@r]) set .@f,1; if(.@f) continue; mes "> "+.@mob_am+"x "+getmonsterinfo(.@mob[.@r],MOB_NAME); setarray .@mob_c[getarraysize(.@mob_c)],.@mob[.@r]; } mes " "; mes "Do you want to accept this challenge?"; if(select("- Yes:- No") - 1) close; next; mes .n$; mes "Then I will warp you to the practice map."; close2; // Cleaning map in case mobs are still on it if(mobcount(.map$,"all") > 0 && getmapusers(.map$) == 0) killmonsterall .map$; for ( set .@m,0; .@m < getarraysize(.@mob_c); set .@m,.@m + 1) { set .@a,0; while( set(.@a,.@a + 1) <= .@mob_am) monster .map$,rand(.mob_x[0],.mob_x[1]),rand(.mob_y[0],.mob_y[1]),getmonsterinfo(.@mob_c[.@m],MOB_NAME),.@mob_c[.@m],1,strnpcinfo(1)+"::OnMobTrainDead"; } set @train,2; warp .map$,.map_x,.map_y; end; } // ========== Information ============ case 2: mes .n$; mes "I will now explain you about this training system."; mes "Let's start with \"Weapon Mastery\"."; next; mes "[ === Weapon Mastery === ]"; mes "There are "+(getarraysize(.eq_n$) - 1)+" weapons you can master, which are:"; for ( set .@w,1; .@w < getarraysize(.eq_n$); set .@w,.@w + 1) if(.@w != 9) mes "- "+.eq_n$[.@w]; next; mes "[ === Weapon Mastery === ]"; mes "The maximum level you can achieve with each weapon is "+.w_level+"."; mes "The training itself is killing monsters on the practice map."; mes "The monsters will be chosen based on your Base Level and Class."; mes " "; mes "There will be "+.w_mob_spawn+" different mobs to kill."; mes "The Spawn Amount of these Mobs will depend on your Mastery Level."; next; mes .n$; mes "So that was the Weapon Mastery, let's move straight to the \"Status Mastery\"."; next; mes "[ === Status Mastery === ]"; mes "The maximum level you can achieve with each Status is "+.s_level+"."; mes " "; mes "===== [STR] ====="; mes "Defeating a Mob which always recieves 1 damage, like a plant does."; mes "Every 10th Mastery Level the mob will spawn one more."; mes "===== [AGI] ====="; mes "Typing an random text as fast as you can in a calculated time."; mes "===== [VIT] ====="; mes "Survival Mode. Skills are blocked, Item Usage is allowed"; mes "There will be "+.vit_mob_spawn+" different mobs to kill."; mes "The Spawn Amount of these Mobs will depend on your Mastery Level."; mes "===== [INT] ====="; mes "Quiz about the world of Ragnarok Online."; mes "===== [DEX] ====="; mes "Clicking an NPC which moves to random spots around you in a limited time."; mes "===== [LUK] ====="; mes "Guessing numbers, every 10th level you need to have one number more correct than before."; mes " "; mes "The training progams for STR, VIT and DEX will take place on the practice map."; mes "You can always see your current Mastery Levels by using the custom command \"@swmstatus\"."; next; mes .n$; mes "[ === Mastery Boost === ]"; mes "The Mastery of your Status will grant you an respective Boost on the specific Status."; mes "The Mastery of your Weapon will grant you an Boost in % of ATK and MATK on your Weapon."; mes "This boost also depends on the refine level of the weapon."; mes "The calculation of the boost is:"; switch(.w_boost_f) { case 1: mes "Mastery Level * (Weapon Refine/3)"; break; case 2: mes "Mastery Level * (Weapon Refine/2)"; break; case 3: mes "Mastery Level * Weapon Refine"; break; case 4: mes "Mastery Level * (Weapon Refine*2)"; break; } mes "^FF0000Note: The Weapon Bonus will only be calculated using the Main Weapon (Right Hand).^000000"; mes "The Mastery Boost activates itself on login and everytime something changes your stats."; if(.delay_type) { mes " "; mes "===== Training Delay ===="; mes "You can train your Status Mastery up to "+.train_statlimit+" times and your Weapon Mastery up to "+.train_weaplimit+" times per "+( (.delay_time < 86400)?(.delay_time/3600)+" Hour(s)":(.delay_time/3600)/24+" Day(s)")+"."; if(.delay_type == 1) mes "Note: That once you reach one of these limits, the exhaustion will also affect your other Mastery."; } next; mes .n$; mes "[ ==== MvP Training ==== ]"; mes "This Training is only for those available, which have reached Max Base Level and their Weapon Mastery on "+.w_level+" and at least one status mastery at "+.s_level+"."; mes "In this Training you have to face an MvP of choice, which can be spawned once, with the party of your choice."; if(.mvp_party == 1) mes "You can't do this training alone and all of your party members also have to meet the requirements!"; next; mes .n$; mes "[ == MvP Training Restriction == ]"; mes "The maximum mastery level you can achieve is "+.mvp_level+"."; mes "While in this training you won't get any loot or experience from the MvP's themself."; mes "This is only to train your strategies and skills before facing an actual MvP on the field."; mes "Also you can't use any commands like \"@go\"."; mes "After completing or failing an training you'll have to wait for the next "+( (.delay_time < 86400)?(.delay_time/3600)+" Hour(s)":(.delay_time/3600)/24+" Day(s)")+" to pass before trying again."; next; mes .n$; mes "[ ==== MvP Training Benefit ==== ]"; mes "But you can get an benefit of course:"; mes "First, I will list your party in the time ladder for of an specific MvP, how long your party needed to kill the chosen MvP's."; mes "Also you and you're party members can get an damage amplifier on the weapon boost against MvP's, which is based on your Mastery Level in percent."; mes "As well as an DEF % MDEF Ignorance in percent, which is based on your \"Mastery Level/2\"."; mes " "; mes "But you need to kill an specific Amount of MvP's before gaining this boost."; mes "The higher your Mastery gets, the more MvP's you have to kill before leveling up."; if(!.equip_b) break; next; mes .n$; mes "Also there is an Equip Bonus, which depends on your Class and only your highest refine will be used."; mes "Examples:"; mes "+4 Muffler[1] > Swordman Class > +2% DEF & 8% MDEF"; mes "+4 Muffler[1] > Mage Class > +8% DEF & 2% MDEF"; mes " "; mes "For this Bonus to become active, you need to "+ ( (.equip_req == 0)?"only ":"pay "+.equip_r_am+"x "+ ( (.equip_req == 1)?"Zeny":"Cash Points") +" and ")+"talk to me, also you must have joined my training program."; mes "The Equip Bonus will be usable for exactly 1 day after payment. After that you have to pay again to use it, the boosts have an duration of "+(.equip_time/1000/60)+" Minutes, after that you have to talk to me again to re-apply them."; break; case 3: mes .n$; if(.equip_b == 0) break; if(.equip_req == 0) { set SWM_EQ_PAY,1; set SWM_EQ_TIMER,gettimetick(2)+.equip_time; } if( SWM_EQ_PAY == 1 && SWM_EQ_TIMER >= gettimetick(2) ) { OnEquipBonus: // Stats Applying from Equip for ( set @i,0; @i < 20; set @i,@i + 1) { // Equipment slot is empty, skip it obviously. if(getequipid(@i) == 0) continue; // Accessories don't have refines, skip 'em... if(@i == 0 || @i == 1 || @i == 14) continue; // Weapon Boost happens via OnPCStatCalcEvent if(@i == 9) continue; if(getequiprefinerycnt(@i) > .@ref) // When an refine is higher than the previous one, set .@ref,getequiprefinerycnt(@i); // set it to the new one } if(!.@ref) { mes .n$; mes "Either you don't have any equip upgraded or you don't wear anything."; close; } sc_end SC_DEF_RATE; sc_end SC_MDEF_RATE; switch(BaseClass) { case Job_Swordman: set .@def,.@ref/2; set .@mdef,.@ref*2; break; case Job_Mage: set .@def,.@ref*2; set .@mdef,.@ref/2; break; case Job_Archer: set .@def,.@ref; set .@mdef,.@ref; break; case Job_Acolyte: set .@def,.@ref; set .@mdef,.@ref; break; case Job_Merchant: set .@def,.@ref*2; set .@mdef,.@ref/2; break; case Job_Thief: set .@def,.@ref; set .@mdef,.@ref; break; } sc_start SC_DEF_RATE,.boost_dur,.@def; sc_start SC_MDEF_RATE,.boost_dur,.@mdef; dispbottom .n$+": + "+.@def+" DEF & + "+.@mdef+" MDEF Equip-Boost applied."; specialeffect2 EF_GUARD; mes .n$; mes "This Boosts will be active for "+(.boost_dur/1000/60)+" Minutes, if you want to re-apply the boost talk to me again."; } else { mes .n$; mes "To use the Equip Bonus, you have to pay for it:"; mes "Costs: "+.equip_r_am+"x "+( (.equip_req == 1)?"Zeny":"Cash Points"); mes "You have "+((.equip_req == 1)?Zeny:#CASHPOINTS)+"x "+( (.equip_req == 1)?"Zeny":"Cash Points"); mes "Do you want to use the Equip Bonus?"; mes "^FF0000Note: Only your highest refine will be used.^000000"; next; if(select("- Yes:- No") - 1) close; mes .n$; if( ((.equip_req == 1)?Zeny:#CASHPOINTS) < .equip_r_am) { mes "Seems like you don't have enough "+( (.equip_req == 1)?"Zeny":"Cash Points"); close; } mes "Thank you for your time and enjoy your bonus."; close2; doevent strnpcinfo(0)+"::OnEquipBonus"; set SWM_EQ_PAY,1; set SWM_EQ_TIMER,gettimetick(2)+.equip_time; set ((.equip_req == 1)?Zeny:#CASHPOINTS),((.equip_req == 1)?Zeny:#CASHPOINTS) - .equip_r_am; end; } break; case 4: mes .n$; mes "So you are here for the MvP Mastery Training, huh?"; if(!.mvp_mastery) { mes "I'm sorry, but I'm currently not offering this training."; close; } mes "Let's see if you "+( (.mvp_party == 1)?"and your party members ":"")+"meet the requirements first."; next; if(getmapusers(.map$) != 0) { mes .n$; mes "There are still someone using the practice map."; mes "Please be patient."; close; } if(.mvp_party) { if(!getcharid(1)) { mes .n$; mes "You need a party to do this training."; break; } if(getpartyleader(getcharid(1)) != strcharinfo(0)) { mes .n$; mes "You need to be the party leader to continue."; break; } set .pty_lead,getpartyleader(getcharid(1),1); getpartymember getcharid(1),1; getpartymember getcharid(1),2; if($@partymembercount < 2) { mes .n$; mes "You need at least two party members to continue"; close; } for ( set .@c,0; .@c < $@partymembercount; set .@c,.@c + 1) if(isloggedin($@partymemberaid[.@c],$@partymembercid[.@c]) == 1) { attachrid($@partymemberaid[.@c]); set .@f,0; set .@p,0; if(callfunc("DATA_D-M",1,.delay_type,3,0,2) > gettimetick(2)) { message strcharinfo(0),"[MVP Training]: I'm sorry, but you are still exhausted from your previous training."; set .@f,1; sleep2 1000; } else callfunc "DATA_D-M",1,.delay_type,3,0,3; if(BaseLevel < 175) { sleep2 1000; message strcharinfo(0),"[MVP Training]: You didn't reach the maximum Base Level yet."; set .@f,1; } if(getequipid(9) == -1) { sleep2 1000; message strcharinfo(0),"[MVP Training]: Hmm, I can't see your weapon mastery since you don't have any equipped. Please make sure you have a weapon equipped before coming back."; set .@f,1; } if(callfunc("DATA_D-M",2,2,getiteminfo(getequipid(9),11),2) < .w_level) { // Weapon Mastery Check sleep2 1000; message strcharinfo(0),"[MVP Training]: Your Weapon Mastery is not high enough."; set .@f,1; } for ( set .@s,0; .@s < 6; set .@s,.@s + 1) if(callfunc("DATA_D-M",2,1,.@s,2) == .s_level) set .@p,1; if(!.@p) { sleep2 1000; message strcharinfo(0),"[MVP Training]: You need at least one Status Mastery on "+.s_level+" to continue."; set .@f,1; } if(!.@f) { sleep2 1000; set .@pt_ct,.@pt_ct + 1; message strcharinfo(0),"[MVP Training]: You meet the requirements for the MvP Training."; } detachrid; } attachrid(.pty_lead); if(.@pt_ct < $@partymembercount) { next; mes .n$; mes "Not every party member is online or meets the requirements."; close; } } else { if(callfunc("DATA_D-M",1,.delay_type,3,0,2) > gettimetick(2)) { message strcharinfo(0),"[MVP Training]: I'm sorry, but you are still exhausted from your previous training."; set .@f,1; sleep2 1000; } else callfunc "DATA_D-M",1,.delay_type,3,0,3; if(BaseLevel < 175) { sleep2 1000; message strcharinfo(0),"[MVP Training]: You didn't reach the maximum Base Level yet."; set .@f,1; } if(getequipid(9) == -1) { sleep2 1000; message strcharinfo(0),"[MVP Training]: Hmm, I can't see your weapon mastery since you don't have any equipped. Please make sure you have a weapon equipped before coming back."; set .@f,1; } if(callfunc("DATA_D-M",2,2,getiteminfo(getequipid(9),11),2) < .w_level) { // Weapon Mastery Check sleep2 1000; message strcharinfo(0),"[MVP Training]: Your Weapon Mastery is not high enough."; set .@f,1; } for ( set .@s,0; .@s < 6; set .@s,.@s + 1) if(callfunc("DATA_D-M",2,1,.@s,2) == .s_level) set .@p,1; if(!.@p) { sleep2 1000; message strcharinfo(0),"[MVP Training]: You need at least one Status Mastery on "+.s_level+" to continue."; set .@f,1; } if(.@f) { next; mes .n$; mes "You don't meet the requirements."; close; } } mes .n$; mes "You"+( (getcharid(1))?" and your party members":"")+" passed the requirements."; close2; enablenpc "MvP Summoner#swm_mvpspawn"; if(getcharid(1)) addrid(2,1,getcharid(1)); message strcharinfo(0),"You will now be warped to the MvP Training."; sleep2 1500; set @train,3; warp .map$,.map_x,.map_y; end; case 5: break; } end; // ======== STR Training ======== OnStrMobDead: if(mobcount(.map$,strnpcinfo(0)+"::OnStrMobDead") != 0) end; dispbottom .n$+": You have completed the STR Training successfully, I will now warp you back to your Save Point."; warp "SavePoint",0,0; sleep2 2500; doevent strnpcinfo(1)+"::OnComplete"; end; // ======== AGI Training ======== OnTimer1000: stopnpctimer; set @a_t,@a_t + 1; if(@a_t == @time) { announce .n$+": You have failed to type the given text in "+@time+" seconds. The practice will end now.",bc_self; set @a_t,0; end; } initnpctimer; end; // ======== VIT Training ======== OnVitMobKill: set @f,1; deltimer strnpcinfo(0)+"::OnVitEnd"; OnVitEnd: if(@f) { dispbottom .n$+": You have killed an monster, so you failed the training. See you next time."; set SWM_Status_Limit,SWM_Status_Limit + 1; if(SWM_Status_Limit >= .train_statlimit) callfunc("DATA_D-M",1,.delay_type,1,.delay_time,1); } sleep2 1000; warp "SavePoint",0,0; removemapflag .map$,mf_noskill; killmonsterall .map$; if(!@f) goto OnComplete; end; // ============================== OnPCLogoutEvent: if(!@train) end; if(strcharinfo(3) == .map$) killmonsterall .map$; removemapflag .map$,mf_noskill; warp "SavePoint",0,0; end; OnPCDieEvent: if(!@train) end; deltimer strnpcinfo(0)+"::OnVitEnd"; killmonsterall .map$; removemapflag .map$,mf_noskill; warp "SavePoint",0,0; sleep2 1000; if(HP == 0) atcommand "@alive"; callfunc "DATA_D-M",1,.delay_type,@train,.delay_time,1; set @train,0; dispbottom .n$+": You have failed the training. See you next time."; end; // ======= Weapon Mastery ======= OnMobTrainDead: if(mobcount(.map$,strnpcinfo(0)+"::OnMobTrainDead") == 0) { dispbottom .n$+": Congratulation!!! You have defeated all enemies, therefore your training was successfull."; callfunc("DATA_D-M",2,2,@e,1,1,1); set @SWMLogin,0; } else end; set SWM_Weapon_Limit,SWM_Weapon_Limit + 1; if(SWM_Weapon_Limit >= .train_weaplimit) { callfunc("DATA_D-M",1,.delay_type,2,.delay_time,1); set SWM_Weapon_Limit,0; } set @train,0; sleep2 1000; warp "SavePoint",0,0; end; OnPCLoadMapEvent: if(strcharinfo(3) == .map$ && !@train) { dispbottom .n$+": You are NOT allowed to be here, unless you're participating in an training."; sleep2 2000; warp "SavePoint",0,0; } end; OnPCLoginEvent: if(.equip_b == 1) if(SWM_EQ_TIMER <= gettimetick(2) && SWM_EQ_PAY == 1) { announce .n$+": The Payment for the Equip Bonus has worn out. To use the Equipment Bonus again, you have to visit me again.",bc_self; set SWM_EQ_PAY,0; set SWM_EQ_TIMER,0; } OnMasteryBoost: if(SWM_Sys == 0) end; // No Mastery started yet set .@boost,300000; // 5 Minutes bonus_script_clear; // Stat Applying from Status Training for ( set .@s,0; .@s < 6; set .@s,.@s + 1) { if( set(.@s_up,callfunc("DATA_D-M",2,1,.@s,2) ) == 0) continue; switch(.@s) { case 0: bonus_script "{ bonus bStr,"+.@s_up+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@s_up+" STR Mastery-Boost."; break; case 1: bonus_script "{ bonus bAgi,"+.@s_up+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@s_up+" AGI Mastery-Boost."; break; case 2: bonus_script "{ bonus bVit,"+.@s_up+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@s_up+" VIT Mastery-Boost."; break; case 3: bonus_script "{ bonus bInt,"+.@s_up+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@s_up+" INT Mastery-Boost."; break; case 4: bonus_script "{ bonus bDex,"+.@s_up+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@s_up+" DEX Mastery-Boost."; break; case 5: bonus_script "{ bonus bLuk,"+.@s_up+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@s_up+" LUK Mastery-Boost."; break; } } // Weapon Boost if(getequipid(9) == -1) end; // No Weapon equipped set .@e,getiteminfo(getequipid(9),11); // Get type of weapon if( set(.@w_m,callfunc("DATA_D-M",2,2,.@e,2) ) > 0) { // Get Mastery Level switch(.w_boost_f) { // Boost Formulas case 1: // Mastery Level * (Refine/3) if(getequiprefinerycnt(9) < 3) set .@ref,1; else set .@ref,getequiprefinerycnt(9)/3; break; case 2: // Mastery Level * (Refine/2) if(getequiprefinerycnt(9) < 2) set .@ref,1; else set .@ref,getequiprefinerycnt(9)/2; break; case 3: // Mastery Level * Refine set .@ref,getequiprefinerycnt(9); break; case 4: // Mastery Level * (Refine*2) set .@ref,getequiprefinerycnt(9)*2; break; } set .@atk,.@w_m*.@ref; bonus_script "{ bonus bAtkRate,"+.@atk+"; }",.@boost,8; bonus_script "{ bonus bMatkRate,"+.@atk+"; }",.@boost,8; if(!@SWMLogin) dispbottom .n$+": Applied "+.@atk+"% Weapon ATK & MATK Boost."; } // MvP Mastery if(set(.@mvp_m,callfunc("DATA_D-M",2,3,0,2) ) > 0) { // Get Mastery Level above 1 bonus_script "{ bonus2 bAddClass,Class_Boss,"+.@mvp_m+"; }",.@boost,8; bonus_script "{ bonus2 bMagicAddClass,Class_Boss,"+.@mvp_m+"; }",.@boost,8; if(.@mvp_m > 1) { bonus_script "{ bonus2 bIgnoreDefClassRate,Class_Boss,"+.@mvp_m/2+"; }",.@boost,8; bonus_script "{ bonus2 bIgnoreMdefClassRate,Class_Boss,"+.@mvp_m/2+"; }",.@boost,8; } if(!@SWMLogin) dispbottom .n$+": Applied "+.@mvp_m+"% Physical & Magical Damage Boost and ignore "+.@mvp_m/2+"% DEF & MDEF against MvP's."; } if(!@SWMLogin) set @SWMLogin,1; // Prevent spamming of Boost messages duo OnPCCalcEvent addtimer .@boost,strnpcinfo(0)+"::OnMasteryBoost"; end; OnSWMStatus: dispbottom "[ === Mastery Levels ==== ]"; setarray .@st_txt$[0],"STR","AGI","VIT","INT","DEX","LUK"; for ( set .@s,0; .@s < 6; set .@s,.@s + 1) dispbottom .@st_txt$[.@s]+" Mastery Level: "+callfunc("DATA_D-M",2,1,.@s,2); if(getequipid(9) == -1) end; dispbottom "Weapon Mastery of equipped Weapon - "+.eq_n$[getiteminfo(getequipid(9),11)]+": "+callfunc("DATA_D-M",2,2,getiteminfo(getequipid(9),11),2); end; OnInit: // NPC Name set .n$,"["+strnpcinfo(1)+"]"; set .gm,80; // GM Level for GM Menu set .map$,"06guild_01"; // Map for Practice set .map_x,50; // X Cooardinate for the warp set .map_y,50; // Y Cooardinate for the warp // ======== Monster Spawn Coordinates, used by Weapon Mastery and VIT Mastery =========== // Randomly chosen spawn coordinates in a specified area: // [0] = left-down corner // [1] = right-upper corner setarray .mob_x[0],34,65; setarray .mob_y[0],32,57; // =========== Mapflags =========== setmapflag .map$,mf_noreturn; setmapflag .map$,mf_nosave; setmapflag .map$,mf_nowarpto; setmapflag .map$,mf_nowarp; setmapflag .map$,mf_nobranch; setmapflag .map$,mf_noteleport; setmapflag .map$,mf_loadevent; setmapflag .map$,mf_nobaseexp; setmapflag .map$,mf_nojobexp; setmapflag .map$,mf_nomobloot; setmapflag .map$,mf_nocommand; setmapflag .map$,mf_nopenalty; setmapflag .map$,mf_monster_noteleport; // ========= Training Fee/Requirement ==== // 0 = None // 1 = Zeny // 2 = Points // 3 = Item // 4 = Quest (usage of Quest Database) set .train_fee,3; switch(.train_fee) { case 0: break; case 1: // Zeny set .train_req_am,50000; break; case 2: // Custom Points set .train_req_vard$,"Cash Points"; // Display for Players set .train_req_varn$,"#CASHPOINTS"; // Variable Name set .train_req_am,100; break; case 3: // Item set .train_req_item,512; // Item ID set .train_req_am,10; break; case 4: // Quest set .train_req_quest,15000; set .train_req_quest_n$,"Quest Name"; break; } // ======== Training Delay Settings ====== // Type: // - 0 = Off // - 1 = Global Delay (Weapon & Status) // - 2 = Seperate Delay for Status and Weapon Mastery set .delay_type,1; if(.delay_type) { // Delay in seconds, Default: 86400 = 1 Day set .delay_time,86400; // Delay Limit: // How often can someone train before the Delay comes active? set .train_statlimit,3; // Status Mastery set .train_weaplimit,3; // Weapon Mastery } // ======= Status Mastery Settings ======= // Max Level // Suggested values for: // - Low Rate: 10 // - Mid Rate: 30 // - High Rate: 50 // - And higher: 100 // Note: If you go higher than 30, be sure to fill .w_mob_am and .vit_mob_am with more values // I was too lazy to do that :I set .s_level,10; // Status Training Restriction // 1 = Enabled // 0 = Disabled // When enabled, only one status can be trained at once. // Any other will be reseted. set .train_s,0; // ====== Str Mastery ====== // = Training Mob ID set .str_mid,1906; // 1906 = WoE:SE Barricade set .str_mx,50; // X Cooardinate for the mob set .str_my,58; // Y Cooardinate for the mob // ====== Agi Mastery - Fast Typing ====== setarray .agi_txt$[0],"Train me","Moar Speed","Agi r0ckz","I wanna be faster"; set .agi_b_time,15; // x seconds to type the text set .agi_x_red,10; // Every x lvl the duration to type will be reduced by 1 // ====== Vit Mastery - Survival ====== // - Mob Spawn Type at once: // 0 = One Mob // 1 = Multiply Mobs set .vit_mob_s,1; set .vit_cd,30; // x seconds base countdown set .vit_inc,10; // x seconds the countdown increases by every 10th level // Mob Spawn Quantity: // Until [X] Mastery Level spawn x Mobs each // [0] == Mob Amount for Mastery Training Level 1 setarray .vit_mob_am[0],3,3,3,3,3,5,5,5,5,5,8,8,8,8,8,10,10,10,10,10,13,13,13,13,13,17,17,17,17,17,17,20,20,20,20,20,23,23,23,23,23,26,26,26,26,26,28,28,28,28,28; // Max x different Mobs spawned at once: // Note: This value is not the Quantity of 1 Mob, see above for that set .vit_mob_spawn,3; // ====== Int Mastery - Quiz ====== set .int_max,200; // Max Questions in the array set .int_base,10; // Minium quantity of questions set .int_pt,8; // Minimum points required to pass setarray .int_quest$[0],"What is the name of this Server?","Which Card gives +100% HP, -50% DEF?","How many Stats exists?","In which year was Ragnarok released?","What is the main City of Ragnarok?","Which item allows you to resurrect when you die?","Which card gives you the penetration effect?","How many 1st Classes exist?","What is the name of the Angel MVP?","How many Fragments are used in the Thanatos Tower?","What is the cutest slime monster?","How many elements exist?","How many races exist?","How many Slots can Equipment have?","Where do you spawn for the first time?"; setarray .int_ans1$[0],"Server 1","Tao Gunka Card","6","1998","Gonryun","Jellopy","Thanatos Card","3","Baphomet","2","Myst","4","10","4","Prontera"; setarray .int_ans2$[0],"Server 2","Fabre Card","2","2002","Morroc","White Potion","Poring Card","10","Valkyrie Randgris","7","Poring","7","4","2","Heaven"; setarray .int_ans3$[0],"Server 3","Acidus Card","3","2010","Payon","Token of Siegfried","Tooth Pick","6","Baroness of Retribution","2","Aqua Elemenal","10","15","3","Jail"; setarray .int_ans4$[0],"Server 4","Mimic Card","9","2005","Prontera","Gold Coin","Detale Card","8","Ifrit","4","Gloom Under Night","9","12","0","Izlude Ship"; setarray .int_right[0],2,1,1,2,4,3,1,3,2,4,2,3,1,1,4; // ====== Dex Mastery - Reaction ====== set .dex_time,15; // x seconds to click the npc set .dex_npc,10; // x times the NPC have to be clicked set .dex_pt,8; // x Points required to pass the test // ====== Luk Mastery - Number guessing ====== set .luk_gue,20; // Chances to guess // ========= Weapon Mastery Settings ======== // ====== Max Level ====== // Suggested values for: // - Low Rate: 10 // - Mid Rate: 30 // - High Rate: 50 // - And higher: 100 set .w_level,10; // ====== Weapon Types ====== // 1: Daggers // 2: One-handed swords // 3: Two-handed swords // 4: One-handed spears // 5: Two-handed spears // 6: One-handed axes // 7: Two-handed axes // 8: Maces // 10: Staves // 11: Bows // 12: Knuckles // 13: Musical Instruments // 14: Whips // 15: Books // 16: Katars // 17: Revolvers // 18: Rifles // 19: Gatling guns // 20: Shotguns // 21: Grenade launchers // 22: Fuuma Shurikens // 23: Two-Handed Staves setarray .eq_n$[1],"Dagger","One-Handed Sword","Two-Handed Sword","One-Handed Spear","Two-Handed Spear","One-Handed Axe","Two-Handed Axe","Mace","Unused","Staff","Bow","Knuckle/Fist","Musical Instrument","Whip","Book","Katar","Revolver","Rifle","Gatling Gun","Shotgun","Grenade Launcher","Fuuma Shuriken","Two-Handed Staves"; // Insert the numbers of the weapons, which are forbidden to be trained with. setarray .kill_weap[0],0; // ====== ATK/MATK Boost Formula ====== // Decide which formula you want to you use for your server! // These are only suggestes values. // The formula itself can be found at "StatusBonus" NPC // 1 = Low Rate: Mastery Level * (Refine Level/3) // 2 = Low Rate#2: Mastery Level * (Refine Level/2) // 3 = Mid Rate: Mastery Level * Refine Level // 4 = High Rate: Mastery Level * (Refine Level*2) set .w_boost_f,1; // Mob Spawn Quantity: // Until [X] Mastery Level spawn x Mobs each // [0] == Mob Amount for Mastery Training Level 1 setarray .w_mob_am[0],3,3,3,3,3,5,5,5,5,5,8,8,8,8,8,10,10,10,10,10,13,13,13,13,13,17,17,17,17,17,17,20,20,20,20,20,23,23,23,23,23,26,26,26,26,26,28,28,28,28,28; // Max x different Mobs spawned at once: // Note: This value is not the Quantity of 1 Mob, see above for that set .w_mob_spawn,3; // ============= MvP Mastery ======== query_sql "SHOW TABLES LIKE 'swm_mvpladder'",.@mvp$; if(.@mvp$ != "") // MvP Mastery Status // 0 = Disabled // 1 = Only Training // 2 = Training and Ladder set .mvp_mastery,2; // Max Level: set .mvp_level,10; // Party Entry: // 1 = Party only // 0 = Solo too set .mvp_party,1; // See MvP Ladder NPC for the other config! // ========== Equip Bonus ====== // 0 = Off // 1 = On // Note: Equip bonus will be done via the refine level/2 // and increases the DEF/MDEF depending on the class set .equip_b,1; // Equip Bonus Timer (in seconds) // How long can the Equip Bonus be used before repay/request it again: set .equip_time,86400; // 1 Day // Equip Bonus Payment: // 0 = None // 1 = Zeny // 2 = Cash Points set .equip_req,1; set .equip_r_am,100000; // 100k // Custom Command bindatcmd "swmstatus",strnpcinfo(0)+"::OnSWMStatus"; // ========== Showing Practice Map Usage =============== while(1) { waitingroom "Practice Map: "+( (getmapusers(.map$) == 0)?"Free":"In usage"),0; sleep 2500; delwaitingroom; } end; } // ===== Function to save/read the Delay and Level ===== // function script DATA_D-M { // // getarg(0): Categorie // // - 1 = Delay // // - 2 = Mastery // // // // ================ Delay ================ // // getarg(1): Type // // - 0 = Off // // - 1 = Global Delay (Weapon & Status) // // - 2 = Seperate Delays // // // // getarg(2): Section // // - 1 = Status // // - 2 = Weapon // // - 3 = MvP // // // // getarg(3): Delay Duration // // // // getarg(4): Save/Read // // - 1 = Save // // - 2 = Read // // - 3 = Reset // // // // Example: callfunc "DATA_D-M" // // Categorie,Type,Section,Time,Save/Read/Reset; // // 1,.delay_type,@mastery,.delay_time,1/2/3; // // // // =============== Mastery =============== // // getarg(1): Section // // - 1 = Status // // - 2 = Weapon // // - 3 = MvP // // // // getarg(2): Mastery Type // // - When getarg(1) = 1: Status // // - 0 = STR // // - 1 = AGI // // - 2 = VIT // // - 3 = INT // // - 4 = DEX // // - 5 = LUK // // - When getarg(1) = 2: Weapon // // - See 'Weapon Types' above // // Don't wanna repeat 22 lines, duh!! // // - When getarg(1) == 3: MvP // // // // getarg(3): Save/Read // // - 1 = Save // // - 2 = Read // // // // getarg(4): Used as Value for getarg(3) // // // // getarg(5): Used as identifier for getarg(4) // // - 1 = Add // // - 2 = Set // // // // Example: callfunc "DATA_D-M" // // Categorie,Section,Mastery Type,Save/Read,Value,Add/Set;// // 2,@mastery,@e/@p,1/2,,1/2; // // // // ================================================ // //debugmes getarg(0,0)+","+getarg(1,0)+","+getarg(2,0)+","+getarg(3,0)+","+getarg(4,0)+","+getarg(5,0); // ============ Delay =============== if(getarg(0) == 1) { if(getarg(1) == 0) return; // Off = No Delay // Type of Delay if(getarg(1) == 1) // Global Delay set .@mast$,"Train"; // Seperate Delays else if(getarg(1) == 2) { // Status Mastery if(getarg(2) == 1) set .@mast$,"Status"; // Weapon Mastery else if(getarg(2) == 2) set .@mast$,"Weapon"; // MvP Mastery else if(getarg(2) == 3) set .@mast$,"MvP"; } if(getarg(4) == 1) { // Write Delay setd(""+.@mast$+"Delay"),gettimetick(2)+getarg(3); setd("SWM_"+.@mast$+"_Limit"),0; } else if(getarg(4) == 2) // Read current Delay return getd(""+.@mast$+"Delay"); else if(getarg(4) == 3) // Reset Delay setd(""+.@mast$+"Delay"),0; // ========= Mastery ================ } else if(getarg(0) == 2) { if(getarg(1) == 1) // Status Mastery set .@mast$,"stats"; else if(getarg(1) == 2) // Weapon Mastery set .@mast$,"weap"; else if(getarg(1) == 3) // MvP Mastery set .@mast$,"mvp"; // Save or Read if(getarg(3) == 1) { // Save new data // Identifier if(getarg(5) == 1) // "Add" setarray getd(""+.@mast$+"["+getarg(2)+"]"),getd(""+.@mast$+"["+getarg(2)+"]") + getarg(4); else if(getarg(5) == 2)// "Set" setarray getd(""+.@mast$+"["+getarg(2)+"]"),getarg(4); } else if(getarg(3) == 2) // Read current data return getd(""+.@mast$+"["+getarg(2)+"]"); } return; } prontera,163,174,4 script MvP Ladder#swm_mvpladder::swm_mvp 100,{ mes "["+strnpcinfo(1)+"]"; if(strnpcinfo(2) == "swm_mvpladder") { if(getvariableofnpc(.mvp_mastery,"Mastery Trainer") < 2) { mes "I'm sorry, but the MvP Ladder is currently not active."; close; } // Display after selection of an MvP the killing time of each Player mes "Please choose the MvP you want to display the Top 10 Killing Times from:"; for ( set .@m,0; .@m < getarraysize(.mvp_id); set .@m,.@m + 1) set .@mvp_m$,.@mvp_m$ + "- "+getmonsterinfo(.mvp_id[.@m],MOB_NAME) + ( (.mvp_id[.@m+1] != 0)?":":""); next; set .@c,select(.@mvp_m$) - 1; query_sql "SELECT `pty_mem1` , `pty_mem2` , `pty_mem3` , `pty_mem4` , `pty_mem5` , `pty_mem6` , `pty_mem7` , `pty_mem8` , `pty_mem9` , `pty_mem10` , `pty_mem11` , `pty_mem12` , `mvp_killtime` FROM `swm_mvpladder` WHERE `mvp_mobid` = '"+.mvp_id[.@c]+"' ORDER BY `mvp_killtime` DESC LIMIT 10",.@pty_mem1$,.@pty_mem2$,.@pty_mem3$,.@pty_mem4$,.@pty_mem5$,.@pty_mem6$,.@pty_mem7$,.@pty_mem8$,.@pty_mem9$,.@pty_mem10$,.@pty_mem11$,.@pty_mem12$,.@time; for ( set .@l,0; .@l < getarraysize(.@pty_mem1$); set .@l,.@l + 1) { mes (.@l+1)+" - "+.@pty_mem1$[.@l]+" - "+( (.@time[.@l]%60 > 0)?.@time[.@l]/60+" Minutes and "+(.@time[.@l]-(.@time[.@l]/60)*60)+" Seconds":.@sec+" Seconds"); set .@pty_list$,.@pty_list$ + "- "+.@pty_mem1$[.@l] + ( (.@pty_mem1$[.@l+1] != "")?":":""); } mes " "; mes "Choose an Player to view the details, if you want:"; next; set .@p,select(.@pty_list$) - 1; mes "["+strnpcinfo(1)+"]"; mes "Player: "+.@pty_mem1$[.@p]; mes " "; if(.@pty_mem2$[.@p] != "") { mes "Helpers:"; for ( set .@c,2; .@c < 13; set .@c,.@c + 1) mes ( (getd(".@ptymem"+.@c+"$["+.@p+"]") != "")?" > "+getd(".@pty_mem"+.@c+"$["+.@p+"]"):""); mes " "; } mes "Time needed:"; mes ( (.@time[.@p]%60 > 0)?.@time[.@l]/60+" Minutes and "+(.@time[.@l]-(.@time[.@l]/60)*60)+" Seconds":.@sec+" Seconds"); } else if(strnpcinfo(2) == "swm_mvpspawn") { mes "Please choose what you want to do:"; if(select("- Spawn MvP:- Leave") - 1) { set @train,0; warp "prontera",156,191; end; } next; mes "["+strnpcinfo(1)+"]"; if(getcharid(1) && getpartyleader(getcharid(1)) != strcharinfo(0)) { mes "I'm sorry, only the party leader can spawn the MvP."; close; } mes "Please choose the MvP you want to spawn:"; next; for ( set .@m,0; .@m < getarraysize(.mvp_id); set .@m,.@m + 1) set .@mvp_m$,.@mvp_m$ + "- "+getmonsterinfo(.mvp_id[.@m],MOB_NAME) + ( (.mvp_id[.@m+1] != 0)?":":""); set .@c,select(.@mvp_m$) - 1; mes "["+strnpcinfo(1)+"]"; mes "Chosen MvP: "+getmonsterinfo(.mvp_id[.@c],MOB_NAME); mes "Is that correct?"; if(select("- Yes:- No") - 1) close; next; mes "["+strnpcinfo(1)+"]"; mes "I will now spawn the chosen MvP!"; close2; monster strnpcinfo(4),rand(.mob_x[0],.mob_x[1]),rand(.mob_y[0],.mob_y[1]),getmonsterinfo(.mvp_id[.@c],0),.mvp_id[.@c],1,strnpcinfo(3)+"::OnMvPLadderDead"; initnpctimer; } end; OnMvPLadderDead: stopnpctimer; set .@time,getnpctimer(0)/1000; announce "["+strcharinfo(0)+"] "+ ( (getcharid(1) != 0)?" from the party ["+getpartyname(getcharid(1))+"]":"") +" took "+.@time+" seconds to kill "+getmonsterinfo(killedrid,MOB_NAME)+" in the MvP Training.",bc_all; sleep2 2000; if(getvariableofnpc(.mvp_mastery,"Mastery Trainer") == 2) { if(getcharid(1)) { getpartymember(getcharid(1),0); // Get Party Member Name // SQL Insertion for Ladder query_sql "SELECT `pty_mem1` FROM `swm_mvpladder` WHERE `mvp_mobid` = '"+killedrid+"' AND `pty_mem1` = '"+escape_sql(getpartyleader(getcharid(1)))+"'",.@leader$; if(.@leader$ != "") { query_sql "SELECT `mvp_killtime` FROM `swm_mvpladder` WHERE `mvp_mobid` = '"+killedrid+"' AND `pty_mem1` = '"+escape_sql(getpartyleader(getcharid(1)))+"'",.@mvp_time; if(.@mvp_time > .@time) { query_sql "UPDATE `swm_mvpladder` SET `mvp_killtime` = '"+.@time+"' WHERE `pty_mem1` = '"+escape_sql(getpartyleader(getcharid(1)))+"' AND `mvp_mobid` = '"+killedrid+"'"; for ( set .@c,1; .@c < $@partymembercount; set .@c,.@c + 1) query_sql "UPDATE `swm_mvpladder` SET `pty_mem"+(.@c+1)+"` = '"+escape_sql($@partymembername$[.@c])+"' WHERE `mvp_killtime` = '"+.@time+"' AND `pty_mem1` = '"+escape_sql(getpartyleader(getcharid(1)))+"' AND `mvp_mobid` = '"+killedrid+"'"; } } else { query_sql "INSERT INTO `swm_mvpladder` ( `pty_mem1` , `mvp_killtime` , `mvp_mobid` ) VALUES ( '"+escape_sql(getpartyleader(getcharid(1)))+"' , '"+.@time+"' , '"+killedrid+"' )"; for ( set .@c,1; .@c < $@partymembercount; set .@c,.@c + 1) query_sql "UPDATE `swm_mvpladder` SET `pty_mem"+(.@c+1)+"` = '"+escape_sql($@partymembername$[.@c])+"' WHERE `mvp_killtime` = '"+.@time+"' AND `pty_mem1` = '"+escape_sql(getpartyleader(getcharid(1)))+"' AND `mvp_mobid` = '"+killedrid+"'"; } addrid(2,1,getcharid(1)); } else { // SQL Insertion for Ladder query_sql "SELECT `pty_mem1` FROM `swm_mvpladder` WHERE `mvp_mobid` = '"+killedrid+"' AND `pty_mem1` = '"+escape_sql(getpartyleader(getcharid(1)))+"'",.@leader$; if(.@leader$ != "") { query_sql "SELECT `mvp_killtime` FROM `swm_mvpladder` WHERE `mvp_mobid` = '"+killedrid+"' AND `pty_mem1` = '"+escape_sql(strcharinfo(0))+"'",.@mvp_time; if(.@mvp_time > .@time) { query_sql "UPDATE `swm_mvpladder` SET `mvp_killtime` = '"+.@time+"' WHERE `pty_mem1` = '"+escape_sql(strcharinfo(0))+"' AND `mvp_mobid` = '"+killedrid+"'"; for ( set .@c,1; .@c < 13; set .@c,.@c + 1) query_sql "UPDATE `swm_mvpladder` SET `pty_mem"+(.@c+1)+"` = NULL WHERE `mvp_killtime` = '"+.@time+"' AND `pty_mem1` = '"+escape_sql(strcharinfo(0))+"' AND `mvp_mobid` = '"+killedrid+"'"; } } else query_sql "INSERT INTO `swm_mvpladder` ( `pty_mem1` , `mvp_killtime` , `mvp_mobid` ) VALUES ( '"+escape_sql(strcharinfo(0))+"' , '"+.@time+"' , '"+killedrid+"' )"; } } warp "prontera",156,191; callfunc("DATA_D-M",2,3,1,1,1,1); // Add MVP Kill to MvP Mastery set @mvp_kills,callfunc("DATA_D-M",2,3,1,2); // Get MvP Kills set @mvp_lvl,callfunc("DATA_D-M",2,3,0,2); // Get MvP Mastery if(@mvp_kills >= .mvp_mob_am[@mvp_lvl]) { // Check if Mvp Kills match the required Kills for lvl up dispbottom .n$+": Your MvP Mastery has been increased by one."; callfunc("DATA_D-M",2,3,0,1,1,1); // Increase MvP Mastery by 1 callfunc("DATA_D-M",2,3,1,1,0,2); // Reset MvP Kills set @SWMLogin,0; } callfunc("DATA_D-M",1,getvariableofnpc(.delay_type,"Mastery Trainer"),3,getvariableofnpc(.delay_time,"Mastery Trainer"),1); // Set Delay disablenpc strnpcinfo(0); end; OnInit: // MvP Mastery Requirement: // [X] MvP's need to kill before level up // [0] == MvP Amount for Mastery Training Level 1 setarray .mvp_mob_am[0],3,3,3,3,3,5,5,5,5,5,8,8,8,8,8,10,10,10,10,10,13,13,13,13,13,17,17,17,17,17,17,20,20,20,20,20,23,23,23,23,23,26,26,26,26,26,28,28,28,28,28; // MVP IDs setarray .mvp_id[0],1511,1647,1785,1630,1039,1874,1272,1719,1046,1389,1112,1115,1418,1871,1252,1768,1086,1885,1649,1651,1832,1492,1734,1251,1779,1688,1646,1373,1147,1059,1150,1087,1190,1038,1157,1159,1623,1650,1583,1708,1312,1751,1648,1658,1916,1929,1956,1957,1990,2022,2068; // ======== Monster Spawn Coordinates =========== // Randomly chosen spawn coordinates in a specified area: // [0] = left-down corner // [1] = right-upper corner setarray .mob_x[0],34,65; setarray .mob_y[0],32,57; if(strnpcinfo(2) == "swm_mvpspawn") disablenpc strnpcinfo(0); end; } 06guild_01,49,49,4 duplicate(swm_mvp) MvP Summoner#swm_mvpspawn 110 06guild_01.gat,50,50,4 script DEX Training 110,{ if(.dex_t) { npctalk strnpcinfo(0)+": "+@d_pt+" Points"; set @d_pt,@d_pt + 1; set .sec,.sl-1; goto OnTimer1000; } end; OnPrepare: set .t_id,getcharid(3); set .@st_calc,@stat/10 + ( (@stat >= 10)?"":( (@stat == 0)?"+1":"") ); set .@timer,getvariableofnpc(.dex_time,"Mastery Trainer"); set .sl,.@timer-.@st_calc; // Time till next move of NPC pcblockmove .t_id,1; // Blocking Movement of the Character npctalk strnpcinfo(0)+": The DEX Training will begin in 5 seconds! Prepare yourself!",bc_map; sleep2 5000; npctalk strnpcinfo(0)+": LET'S GO!!!"; sleep2 1000; movenpc strnpcinfo(1),rand(.x[0],.x[1]),rand(.y[0],.y[1]); set .npc,1; // Times the NPC has been moved set .dex_t,1; // Training Activated set @d_pt,0; // Reseting Points set .sec,0; initnpctimer; end; OnTimer1000: set .sec,.sec + 1; if(.sec == .sl) { stopnpctimer; if(.npc == getvariableofnpc(.dex_npc,"Mastery Trainer") ) goto OnEnd; movenpc strnpcinfo(1),rand(.x[0],.x[1]),rand(.y[0],.y[1]); set .npc,.npc + 1; // Times the NPC has been moved set .sec,0; initnpctimer; } end; OnEnd: if(playerattached() == 0) // If no player is attached if(isloggedin(.t_id) == 1) // Check if the character is still online attachrid(.t_id); else goto OnTrainDisable; pcblockmove getcharid(3),0; warp "SavePoint",0,0; sleep2 1000; // Delay to finish warping if(@d_pt >= getvariableofnpc(.dex_pt,"Mastery Trainer") ) doevent "Mastery Trainer::OnComplete"; else { dispbottom getvariableofnpc(.n$,"Mastery Trainer")+": You have failed this training."; dispbottom getvariableofnpc(.n$,"Mastery Trainer")+": Your points: "+@d_pt+", required: "+getvariableofnpc(.dex_pt,"Mastery Trainer")+"."; } OnTrainDisable: set .dex_t,0; disablenpc strnpcinfo(0); end; OnInit: // Randomly chosen coordinates in a specified area: // [0] = left-down corner // [1] = right-upper corner setarray .x[0],44,57; setarray .y[0],41,57; disablenpc strnpcinfo(0); end; }