astralprojection
New member
- Messages
- 334
- Points
- 0
//===== Hercules Script ======================================
// MVP Spawn Controller
//===== By: ==================================================
// astralprojektion
//===== Current Version: =====================================
// 1.3
//===== Description: =========================================
// Control MVP Spawn with script. MVP will not respawn on server start or reload using flag.
// Delete or Comment all MVP and mini boss spawn at npc/pre-re/mobs/dungeons/ or /fields.
// Make sure set at NifInvasion to make it work.
// OnLoDDead:
// // Set LOD as dead ang next respawn is 5580sec
// $S11373 = 2; $T11373 = (gettimetick(2) + 5580);
//
//===== Additional Comments: =================================
// 1.0 Initial Release
// 1.1 Use TimeStamp when mvp is killed
// Fixed typo on MVP_Map array.
// 1.2 Set Variables to Global.
// 1.3 Include some Mini Boss on the controller
// Added PvP On/Off MvP is alive
// Integrate LOD invasion
// Added @mvpcontroller command to reset all or a specific mvp and other settings.
//============================================================
/* Credits to Meko
https://herc.ws/board/files/file/326-array-manipulation-functions/
*/
function script array_find {
.@size = getarraysize(getarg(0));
.@neq = getarg(2, false);
freeloop(true);
for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) {
if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) ||
(!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) {
freeloop(false);
return .@i;
}
}
freeloop(false);
return -1;
}
- script mvpcontroller FAKE_NPC,{
end;
OnNPCKillEvent:
if(array_find(.mvpid, killedrid) >= 0 ){
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
if( killedrid == .mvpid[.@i] && strcharinfo(PC_MAP) == .mvpmaps$[.@i]) {
// 1 - Alive 2 - Dead
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 2);
// current time + respawn time (seconds)
setd("$T"+.mvpa[.@i]+.mvpid[.@i],gettimetick(2)+(.mvptime[.@i]*60));
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$", strcharinfo(PC_NAME));
if( killedrid == 1120 || killedrid == 1096 || killedrid == 1388 ) {
if(.announce) announce "A mini boss monster [ "+strmobinfo(1,killedrid)+" ] at "+strcharinfo(PC_MAP)+" has been slain.",bc_all;
} else {
if(.announce) announce "A boss monster [ "+strmobinfo(1,killedrid)+" ] at "+strcharinfo(PC_MAP)+" has been slain.",bc_all;
if(.pvp){
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
break;
}
}
}
end;
OnSettings:
while(1){
switch(select(
" ~ PvP On Map [ "+((.pvp)?"^28bf00Yes^000000":"^ff0000No^000000")+" ]:"+
" ~ Announce [ "+((.announce)?"^28bf00Yes^000000":"^ff0000No^000000")+" ]:"+
" ~ Reset All MvP:"+
" ~ Reset Specific MvP:"+
" ~ ^777777Close^000000"
)) {
case 1: .pvp =! .pvp;
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
if ( getd("$S"+.mvpa[.@i]+.mvpid[.@i]) < 2 || getd("$T"+.mvpa[.@i]+.mvpid[.@i]) <= gettimetick(2) ) {
// if mini boss, just ignore pvp
if(.pvp){
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
}
break;
case 2: .announce =! .announce; break;
case 3:
freeloop(1);
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1);
setd("$T"+.mvpa[.@i]+.mvpid[.@i], 0);
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$","");
killmonsterall .mvpmaps$[.@i];
}
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
if( compare( .mvpmaps$[.@i], "prt_maze03" ) && .mvpid[.@i] == 1039 ) { // Baphomet
monster .mvpmaps$[.@i],100,100,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "treasure02" ) && .mvpid[.@i] == 1112 ) { // Drake
monster .mvpmaps$[.@i],101,151,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "pay_dun04" ) && .mvpid[.@i] == 1150 ) { // moonlight
monster .mvpmaps$[.@i],120,115,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "tur_dun04" ) && .mvpid[.@i] == 1312 ) { // turtle
monster .mvpmaps$[.@i],99,93,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "moc_pryd06" ) && .mvpid[.@i] == 1511 ) { // amon
monster .mvpmaps$[.@i],102,166,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "ayo_dun02" ) && .mvpid[.@i] == 1688 ) { // lady
monster .mvpmaps$[.@i],150,90,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "niflheim" ) && .mvpid[.@i] == 1373 ) { // LOD
donpcevent("NifInvasion::OnSpawn");
} else {
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
}
if(.pvp){
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
freeloop(0);
dispbottom "All MVP has been reset.";
break;
case 4:
set .@menu$,"";
freeloop(1);
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ )
set .@menu$, .@menu$+getmonsterinfo(.mvpid[.@i],0)+" - ("+.mvpmaps$[.@i]+"):";
set .@menu$, .@menu$+" ~ ^777777Cancel^000000";
freeloop(0);
set .@i, select(.@menu$)-1;
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1);
setd("$T"+.mvpa[.@i]+.mvpid[.@i], 0);
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$","");
killmonsterall .mvpmaps$[.@i];
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
if(.pvp){
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
dispbottom "Monster [ "+strmobinfo(1,.mvpid[.@i])+" ] at "+.mvpmaps$[.@i]+" has been reset.";
break;
default:
close;
}
}
close;
OnTimer60000:
// Let recheck after a minute.
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
/* $S 1 - Alive $S 2 - Dead */
// If MvP status is not yet set
if ( getd("$S"+.mvpa[.@i]+.mvpid[.@i]) == 2 && getd("$T"+.mvpa[.@i]+.mvpid[.@i]) <= gettimetick(2) ) {
// check if MvP has fixed spawn location in the map.
if( compare( .mvpmaps$[.@i], "prt_maze03" ) && .mvpid[.@i] == 1039 ) { // Baphomet
monster .mvpmaps$[.@i],100,100,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "treasure02" ) && .mvpid[.@i] == 1112 ) { // Drake
monster .mvpmaps$[.@i],101,151,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "pay_dun04" ) && .mvpid[.@i] == 1150 ) { // moonlight
monster .mvpmaps$[.@i],120,115,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "tur_dun04" ) && .mvpid[.@i] == 1312 ) { // turtle
monster .mvpmaps$[.@i],99,93,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "moc_pryd06" ) && .mvpid[.@i] == 1511 ) { // amon
monster .mvpmaps$[.@i],102,166,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "ayo_dun02" ) && .mvpid[.@i] == 1688 ) { // lady
monster .mvpmaps$[.@i],150,90,"--ja--",.mvpid[.@i],1;
// Initiate LOD invasion at Niflheim
} else if( compare( .mvpmaps$[.@i], "niflheim" ) && .mvpid[.@i] == 1373 ) { // LOD
donpcevent("NifInvasion::OnSpawn");
} else {
// Spawn the MvP at random location.
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
}
if(.announce) announce "Monster [ "+strmobinfo(1,.mvpid[.@i])+" ] at "+.mvpmaps$[.@i]+" has been spawned.",bc_all;
// set status of MvP as ALIVE!
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1);
// reset killer name.
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$", "");
if(.pvp){
// if mini boss, just ignore pvp
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
}
initnpctimer();
end;
OnCheck:
OnPCLoginEvent:
.@rank = 0;
query_sql "SELECT DATABASE()", .@rag_db$;
query_logsql "SELECT DATABASE()", .@log_db$;
query_sql( "SELECT COUNT(`monster_id`) AS `total`,`char`.`name`,`kill_char_id` FROM "+.@log_db$+".`mvplog`"+" LEFT JOIN "+.@rag_db$+".`char` ON `char`.`char_id` = `mvplog`.`kill_char_id` WHERE `map` <> 'guild_vs5' AND DATE_FORMAT( `mvp_date`, '%Y-%m-%d') = DATE_FORMAT( now(), '%Y-%m-%d') GROUP BY `kill_char_id` ORDER BY `total` DESC LIMIT 10",.@mvptotal,.@mvpname$,.@kill_char_id );
for( .@i = 0; .@i < getarraysize(.@kill_char_id); .@i++ ) {
if(getcharid(CHAR_ID_CHAR) == .@kill_char_id[.@i]){
.@rank = .@i+1; .@total = .@mvptotal[.@i];
}
}
if ( .@rank > 0 && .@rank < 4 ) {
if(countitem(.topreward) == 0){
dispbottom "Congratulations you ranked as #"+.@rank+" MvP Hunter for today. Total kill "+.@total;
getitembound .topreward,1,4;
equip(.topreward);
}
} else {
if(countitem(.topreward) > 0){
delitem .topreward,countitem(.topreward);
dispbottom "Sorry you have lost your rank as Top 3 MvP Hunter of the day.";
}
}
addtimer 300000,strnpcinfo(0) + "::OnCheck";
end;
OnInit:
.topreward = 31488; // top mvp daily reward
.toprange = 3; // Only Top 3 gets the reward
.announce = 1; // shall we announce mvp kills and spawn? (yes = 1 no = 0)
.pvp = 1; // shall will make the map pvp? (yes = 1 no = 0)
bindatcmd("mvpcontroller","mvpcontroller::OnSettings",99,99);
// Mvp ids
setarray .mvpid[0],1511,1096,1096,1388,1039,1272,1272,1046,1046,1389,1112,1115,1115,1418,1252,1120,1120,1120,1120,1086,1492,1251,1147,1147,1059,1150,1087,1190,1038,1157,1159,1312,1373,1630,1688;
// Mvp Index is used because there are same mvp that spawn on different maps.
setarray .mvpa[0],1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,1,2,3,4,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1;
// MvP maps
setarray .mvpmaps$[0],"moc_pryd06","pay_fild04","xmas_dun01","yuno_fild02","prt_maze03","gl_chyard","gld_dun04","gef_dun02","gld_dun02","gef_dun01","treasure02","gld_dun01","pay_fild11","gon_dun03","xmas_fild01","gld_dun04","pay_fild04","prt_maze03","treasure02","prt_sewb4","ama_dun03","xmas_dun02","anthell02","gld_dun03","mjolnir_04","pay_dun04","gef_fild14","gef_fild10","moc_pryd04","in_sphinx5","moc_fild15","tur_dun04","niflheim","lou_dun03","ayo_dun02";
// How many minutes to respawn?
setarray .mvptime[0],60,60,60,60,120,60,480,120,480,60,120,480,120,95,120,240,60,114,32,60,91,60,120,480,120,60,60,120,60,60,120,60,93,117,420;
freeloop(1);
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
// If MvP status is not yet set
if ( getd("$S"+.mvpa[.@i]+.mvpid[.@i]) < 2 || getd("$T"+.mvpa[.@i]+.mvpid[.@i]) <= gettimetick(2) ) {
// check if MvP has fixed spawn location in the map.
if( compare( .mvpmaps$[.@i], "prt_maze03" ) && .mvpid[.@i] == 1039 ) { // Baphomet
monster .mvpmaps$[.@i],100,100,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "treasure02" ) && .mvpid[.@i] == 1112 ) { // Drake
monster .mvpmaps$[.@i],101,151,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "pay_dun04" ) && .mvpid[.@i] == 1150 ) { // moonlight
monster .mvpmaps$[.@i],120,115,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "tur_dun04" ) && .mvpid[.@i] == 1312 ) { // turtle
monster .mvpmaps$[.@i],99,93,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "moc_pryd06" ) && .mvpid[.@i] == 1511 ) { // amon
monster .mvpmaps$[.@i],102,166,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "ayo_dun02" ) && .mvpid[.@i] == 1688 ) { // lady
monster .mvpmaps$[.@i],150,90,"--ja--",.mvpid[.@i],1;
// Initiate LOD invasion at Niflheim
} else if( compare( .mvpmaps$[.@i], "niflheim" ) && .mvpid[.@i] == 1373 ) { // LOD
donpcevent("NifInvasion::OnSpawn");
} else {
// Spawn the MvP at random location.
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
}
// set status of MvP as ALIVE!
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1); // status is alive (1)
// reset killer name.
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$", ""); // killer name reset
if(.pvp){
// if mini boss, just ignore pvp
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
}
freeloop(0);
initnpctimer();
end;
}
/* If you want your player have access to spawn time, you can use this function to display status of each MvP and who killed them
{
Id: 501
AegisName: "Red_Potion"
Name: "Red Potion"
Type: "IT_HEALING"
Buy: 50
Weight: 70
Script: <" callfunc "F_MVPTime"; ">
},
*/
function script F_MVPTime {
mes "^FF0000MvP Status^000000";
for( .@i = 0; .@i < getarraysize(getvariableofnpc(.mvpid,"mvpcontroller")); .@i++ ) {
.@time = getd("$T" +getvariableofnpc(.mvpindex[.@i],"mvpcontroller") + getvariableofnpc(.mvpid[.@i],"mvpcontroller"));
.@alive = getd("$S" +getvariableofnpc(.mvpindex[.@i],"mvpcontroller") + getvariableofnpc(.mvpid[.@i],"mvpcontroller"));
set .@hours, (.@time - gettimetick(2)) / 3600;
set .@mins, (.@time - gettimetick(2))%3600/60;
set .@secs, (.@time - gettimetick(2))%60;
set .@mobname$,getmonsterinfo( getvariableofnpc(.mvpid[.@i], "mvpcontroller"),0 );
set .@map$,getvariableofnpc(.mvpmaps$[.@i], "mvpcontroller");
set .@player$,getd("$P"+getvariableofnpc(.mvpindex[.@i], "mvpcontroller") + getvariableofnpc(.mvpid[.@i], "mvpcontroller") +"$");
mes ((.@alive == 1) ? "[ ^01DF01+^000000 ]" : "[ ^FF0000x^000000 ]")+((getstrlen( .@mobname$ ) > 10 ) ? " ^0055FF"+substr(.@mobname$,0, 10)+"^000000" : " ^0055FF"+.@mobname$+"^000000")+" ^777777"+.@map$+"^000000 ";
if( .@alive == 2 ) {
mes "^FF0000"+((.@hours) ? .@hours +"h" : "")+" "+((.@mins) ? .@mins +"m" : "")+" "+((.@secs) ? .@secs +"s" : "")+"^000000 "+"^777777 kiiled by "+.@player$+"^000000";
}
}
close;
}
What does it do?
- prevents spawn of mvp on each server starts or reload.
- spawns mvp or mini only at specific time based when it was killed + spawn time
- reward x top mvp killers.
Cons:
- you can not use convex mirrors to show mvp in the map
- you can not find mvp using @whereis.
How to use:
- Delete or Comment target MVP and mini boss spawn from your npc/pre-re/mobs/dungeons/ or /fields.
- Add these mvps to array.
FAQ:
#Q1 What the heck is this?
setarray .mvpa[0],1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,1,2,3,4,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1;
#A1: since there are same kind of MVP spawn on multile map (i.e Angeling spawns at pay_fild04, xmas_dun01, yuno_fild03) those numbers are the unique identifiers.
if there is only 1 spawn, then just write 1.
succeeding spawn is 2 then 3 ....
All other suggestions to simplify and improve @AnnieRuru yohoo! my master.
// MVP Spawn Controller
//===== By: ==================================================
// astralprojektion
//===== Current Version: =====================================
// 1.3
//===== Description: =========================================
// Control MVP Spawn with script. MVP will not respawn on server start or reload using flag.
// Delete or Comment all MVP and mini boss spawn at npc/pre-re/mobs/dungeons/ or /fields.
// Make sure set at NifInvasion to make it work.
// OnLoDDead:
// // Set LOD as dead ang next respawn is 5580sec
// $S11373 = 2; $T11373 = (gettimetick(2) + 5580);
//
//===== Additional Comments: =================================
// 1.0 Initial Release
// 1.1 Use TimeStamp when mvp is killed
// Fixed typo on MVP_Map array.
// 1.2 Set Variables to Global.
// 1.3 Include some Mini Boss on the controller
// Added PvP On/Off MvP is alive
// Integrate LOD invasion
// Added @mvpcontroller command to reset all or a specific mvp and other settings.
//============================================================
/* Credits to Meko
https://herc.ws/board/files/file/326-array-manipulation-functions/
*/
function script array_find {
.@size = getarraysize(getarg(0));
.@neq = getarg(2, false);
freeloop(true);
for (.@i = getarrayindex(getarg(0)); .@i < .@size; ++.@i) {
if ((.@neq && (getelementofarray(getarg(0), .@i) != getarg(1))) ||
(!(.@neq) && (getelementofarray(getarg(0), .@i) == getarg(1)))) {
freeloop(false);
return .@i;
}
}
freeloop(false);
return -1;
}
- script mvpcontroller FAKE_NPC,{
end;
OnNPCKillEvent:
if(array_find(.mvpid, killedrid) >= 0 ){
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
if( killedrid == .mvpid[.@i] && strcharinfo(PC_MAP) == .mvpmaps$[.@i]) {
// 1 - Alive 2 - Dead
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 2);
// current time + respawn time (seconds)
setd("$T"+.mvpa[.@i]+.mvpid[.@i],gettimetick(2)+(.mvptime[.@i]*60));
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$", strcharinfo(PC_NAME));
if( killedrid == 1120 || killedrid == 1096 || killedrid == 1388 ) {
if(.announce) announce "A mini boss monster [ "+strmobinfo(1,killedrid)+" ] at "+strcharinfo(PC_MAP)+" has been slain.",bc_all;
} else {
if(.announce) announce "A boss monster [ "+strmobinfo(1,killedrid)+" ] at "+strcharinfo(PC_MAP)+" has been slain.",bc_all;
if(.pvp){
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
break;
}
}
}
end;
OnSettings:
while(1){
switch(select(
" ~ PvP On Map [ "+((.pvp)?"^28bf00Yes^000000":"^ff0000No^000000")+" ]:"+
" ~ Announce [ "+((.announce)?"^28bf00Yes^000000":"^ff0000No^000000")+" ]:"+
" ~ Reset All MvP:"+
" ~ Reset Specific MvP:"+
" ~ ^777777Close^000000"
)) {
case 1: .pvp =! .pvp;
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
if ( getd("$S"+.mvpa[.@i]+.mvpid[.@i]) < 2 || getd("$T"+.mvpa[.@i]+.mvpid[.@i]) <= gettimetick(2) ) {
// if mini boss, just ignore pvp
if(.pvp){
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
}
break;
case 2: .announce =! .announce; break;
case 3:
freeloop(1);
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1);
setd("$T"+.mvpa[.@i]+.mvpid[.@i], 0);
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$","");
killmonsterall .mvpmaps$[.@i];
}
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
if( compare( .mvpmaps$[.@i], "prt_maze03" ) && .mvpid[.@i] == 1039 ) { // Baphomet
monster .mvpmaps$[.@i],100,100,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "treasure02" ) && .mvpid[.@i] == 1112 ) { // Drake
monster .mvpmaps$[.@i],101,151,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "pay_dun04" ) && .mvpid[.@i] == 1150 ) { // moonlight
monster .mvpmaps$[.@i],120,115,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "tur_dun04" ) && .mvpid[.@i] == 1312 ) { // turtle
monster .mvpmaps$[.@i],99,93,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "moc_pryd06" ) && .mvpid[.@i] == 1511 ) { // amon
monster .mvpmaps$[.@i],102,166,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "ayo_dun02" ) && .mvpid[.@i] == 1688 ) { // lady
monster .mvpmaps$[.@i],150,90,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "niflheim" ) && .mvpid[.@i] == 1373 ) { // LOD
donpcevent("NifInvasion::OnSpawn");
} else {
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
}
if(.pvp){
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
freeloop(0);
dispbottom "All MVP has been reset.";
break;
case 4:
set .@menu$,"";
freeloop(1);
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ )
set .@menu$, .@menu$+getmonsterinfo(.mvpid[.@i],0)+" - ("+.mvpmaps$[.@i]+"):";
set .@menu$, .@menu$+" ~ ^777777Cancel^000000";
freeloop(0);
set .@i, select(.@menu$)-1;
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1);
setd("$T"+.mvpa[.@i]+.mvpid[.@i], 0);
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$","");
killmonsterall .mvpmaps$[.@i];
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
if(.pvp){
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
dispbottom "Monster [ "+strmobinfo(1,.mvpid[.@i])+" ] at "+.mvpmaps$[.@i]+" has been reset.";
break;
default:
close;
}
}
close;
OnTimer60000:
// Let recheck after a minute.
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
/* $S 1 - Alive $S 2 - Dead */
// If MvP status is not yet set
if ( getd("$S"+.mvpa[.@i]+.mvpid[.@i]) == 2 && getd("$T"+.mvpa[.@i]+.mvpid[.@i]) <= gettimetick(2) ) {
// check if MvP has fixed spawn location in the map.
if( compare( .mvpmaps$[.@i], "prt_maze03" ) && .mvpid[.@i] == 1039 ) { // Baphomet
monster .mvpmaps$[.@i],100,100,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "treasure02" ) && .mvpid[.@i] == 1112 ) { // Drake
monster .mvpmaps$[.@i],101,151,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "pay_dun04" ) && .mvpid[.@i] == 1150 ) { // moonlight
monster .mvpmaps$[.@i],120,115,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "tur_dun04" ) && .mvpid[.@i] == 1312 ) { // turtle
monster .mvpmaps$[.@i],99,93,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "moc_pryd06" ) && .mvpid[.@i] == 1511 ) { // amon
monster .mvpmaps$[.@i],102,166,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "ayo_dun02" ) && .mvpid[.@i] == 1688 ) { // lady
monster .mvpmaps$[.@i],150,90,"--ja--",.mvpid[.@i],1;
// Initiate LOD invasion at Niflheim
} else if( compare( .mvpmaps$[.@i], "niflheim" ) && .mvpid[.@i] == 1373 ) { // LOD
donpcevent("NifInvasion::OnSpawn");
} else {
// Spawn the MvP at random location.
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
}
if(.announce) announce "Monster [ "+strmobinfo(1,.mvpid[.@i])+" ] at "+.mvpmaps$[.@i]+" has been spawned.",bc_all;
// set status of MvP as ALIVE!
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1);
// reset killer name.
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$", "");
if(.pvp){
// if mini boss, just ignore pvp
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
}
initnpctimer();
end;
OnCheck:
OnPCLoginEvent:
.@rank = 0;
query_sql "SELECT DATABASE()", .@rag_db$;
query_logsql "SELECT DATABASE()", .@log_db$;
query_sql( "SELECT COUNT(`monster_id`) AS `total`,`char`.`name`,`kill_char_id` FROM "+.@log_db$+".`mvplog`"+" LEFT JOIN "+.@rag_db$+".`char` ON `char`.`char_id` = `mvplog`.`kill_char_id` WHERE `map` <> 'guild_vs5' AND DATE_FORMAT( `mvp_date`, '%Y-%m-%d') = DATE_FORMAT( now(), '%Y-%m-%d') GROUP BY `kill_char_id` ORDER BY `total` DESC LIMIT 10",.@mvptotal,.@mvpname$,.@kill_char_id );
for( .@i = 0; .@i < getarraysize(.@kill_char_id); .@i++ ) {
if(getcharid(CHAR_ID_CHAR) == .@kill_char_id[.@i]){
.@rank = .@i+1; .@total = .@mvptotal[.@i];
}
}
if ( .@rank > 0 && .@rank < 4 ) {
if(countitem(.topreward) == 0){
dispbottom "Congratulations you ranked as #"+.@rank+" MvP Hunter for today. Total kill "+.@total;
getitembound .topreward,1,4;
equip(.topreward);
}
} else {
if(countitem(.topreward) > 0){
delitem .topreward,countitem(.topreward);
dispbottom "Sorry you have lost your rank as Top 3 MvP Hunter of the day.";
}
}
addtimer 300000,strnpcinfo(0) + "::OnCheck";
end;
OnInit:
.topreward = 31488; // top mvp daily reward
.toprange = 3; // Only Top 3 gets the reward
.announce = 1; // shall we announce mvp kills and spawn? (yes = 1 no = 0)
.pvp = 1; // shall will make the map pvp? (yes = 1 no = 0)
bindatcmd("mvpcontroller","mvpcontroller::OnSettings",99,99);
// Mvp ids
setarray .mvpid[0],1511,1096,1096,1388,1039,1272,1272,1046,1046,1389,1112,1115,1115,1418,1252,1120,1120,1120,1120,1086,1492,1251,1147,1147,1059,1150,1087,1190,1038,1157,1159,1312,1373,1630,1688;
// Mvp Index is used because there are same mvp that spawn on different maps.
setarray .mvpa[0],1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,1,2,3,4,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1;
// MvP maps
setarray .mvpmaps$[0],"moc_pryd06","pay_fild04","xmas_dun01","yuno_fild02","prt_maze03","gl_chyard","gld_dun04","gef_dun02","gld_dun02","gef_dun01","treasure02","gld_dun01","pay_fild11","gon_dun03","xmas_fild01","gld_dun04","pay_fild04","prt_maze03","treasure02","prt_sewb4","ama_dun03","xmas_dun02","anthell02","gld_dun03","mjolnir_04","pay_dun04","gef_fild14","gef_fild10","moc_pryd04","in_sphinx5","moc_fild15","tur_dun04","niflheim","lou_dun03","ayo_dun02";
// How many minutes to respawn?
setarray .mvptime[0],60,60,60,60,120,60,480,120,480,60,120,480,120,95,120,240,60,114,32,60,91,60,120,480,120,60,60,120,60,60,120,60,93,117,420;
freeloop(1);
for( .@i = 0; .@i < getarraysize(.mvpid); .@i++ ) {
// If MvP status is not yet set
if ( getd("$S"+.mvpa[.@i]+.mvpid[.@i]) < 2 || getd("$T"+.mvpa[.@i]+.mvpid[.@i]) <= gettimetick(2) ) {
// check if MvP has fixed spawn location in the map.
if( compare( .mvpmaps$[.@i], "prt_maze03" ) && .mvpid[.@i] == 1039 ) { // Baphomet
monster .mvpmaps$[.@i],100,100,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "treasure02" ) && .mvpid[.@i] == 1112 ) { // Drake
monster .mvpmaps$[.@i],101,151,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "pay_dun04" ) && .mvpid[.@i] == 1150 ) { // moonlight
monster .mvpmaps$[.@i],120,115,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "tur_dun04" ) && .mvpid[.@i] == 1312 ) { // turtle
monster .mvpmaps$[.@i],99,93,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "moc_pryd06" ) && .mvpid[.@i] == 1511 ) { // amon
monster .mvpmaps$[.@i],102,166,"--ja--",.mvpid[.@i],1;
} else if( compare( .mvpmaps$[.@i], "ayo_dun02" ) && .mvpid[.@i] == 1688 ) { // lady
monster .mvpmaps$[.@i],150,90,"--ja--",.mvpid[.@i],1;
// Initiate LOD invasion at Niflheim
} else if( compare( .mvpmaps$[.@i], "niflheim" ) && .mvpid[.@i] == 1373 ) { // LOD
donpcevent("NifInvasion::OnSpawn");
} else {
// Spawn the MvP at random location.
monster .mvpmaps$[.@i],0,0,"--ja--",.mvpid[.@i],1;
}
// set status of MvP as ALIVE!
setd("$S"+.mvpa[.@i]+.mvpid[.@i], 1); // status is alive (1)
// reset killer name.
setd("$P"+.mvpa[.@i]+.mvpid[.@i]+"$", ""); // killer name reset
if(.pvp){
// if mini boss, just ignore pvp
if(.mvpid[.@i] == 1120 || .mvpid[.@i] == 1096 || .mvpid[.@i] == 1388 ){
//PASS THROUGH
} else {
setmapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpon .mvpmaps$[.@i];
}
} else {
removemapflag .mvpmaps$[.@i], mf_pvp_nocalcrank;
pvpoff .mvpmaps$[.@i];
}
}
}
freeloop(0);
initnpctimer();
end;
}
/* If you want your player have access to spawn time, you can use this function to display status of each MvP and who killed them
{
Id: 501
AegisName: "Red_Potion"
Name: "Red Potion"
Type: "IT_HEALING"
Buy: 50
Weight: 70
Script: <" callfunc "F_MVPTime"; ">
},
*/
function script F_MVPTime {
mes "^FF0000MvP Status^000000";
for( .@i = 0; .@i < getarraysize(getvariableofnpc(.mvpid,"mvpcontroller")); .@i++ ) {
.@time = getd("$T" +getvariableofnpc(.mvpindex[.@i],"mvpcontroller") + getvariableofnpc(.mvpid[.@i],"mvpcontroller"));
.@alive = getd("$S" +getvariableofnpc(.mvpindex[.@i],"mvpcontroller") + getvariableofnpc(.mvpid[.@i],"mvpcontroller"));
set .@hours, (.@time - gettimetick(2)) / 3600;
set .@mins, (.@time - gettimetick(2))%3600/60;
set .@secs, (.@time - gettimetick(2))%60;
set .@mobname$,getmonsterinfo( getvariableofnpc(.mvpid[.@i], "mvpcontroller"),0 );
set .@map$,getvariableofnpc(.mvpmaps$[.@i], "mvpcontroller");
set .@player$,getd("$P"+getvariableofnpc(.mvpindex[.@i], "mvpcontroller") + getvariableofnpc(.mvpid[.@i], "mvpcontroller") +"$");
mes ((.@alive == 1) ? "[ ^01DF01+^000000 ]" : "[ ^FF0000x^000000 ]")+((getstrlen( .@mobname$ ) > 10 ) ? " ^0055FF"+substr(.@mobname$,0, 10)+"^000000" : " ^0055FF"+.@mobname$+"^000000")+" ^777777"+.@map$+"^000000 ";
if( .@alive == 2 ) {
mes "^FF0000"+((.@hours) ? .@hours +"h" : "")+" "+((.@mins) ? .@mins +"m" : "")+" "+((.@secs) ? .@secs +"s" : "")+"^000000 "+"^777777 kiiled by "+.@player$+"^000000";
}
}
close;
}
What does it do?
- prevents spawn of mvp on each server starts or reload.
- spawns mvp or mini only at specific time based when it was killed + spawn time
- reward x top mvp killers.
Cons:
- you can not use convex mirrors to show mvp in the map
- you can not find mvp using @whereis.
How to use:
- Delete or Comment target MVP and mini boss spawn from your npc/pre-re/mobs/dungeons/ or /fields.
- Add these mvps to array.
FAQ:
#Q1 What the heck is this?
setarray .mvpa[0],1,1,2,1,1,1,2,1,2,1,1,1,2,1,1,1,2,3,4,1,1,1,1,2,1,1,1,1,1,1,1,1,1,1,1;
#A1: since there are same kind of MVP spawn on multile map (i.e Angeling spawns at pay_fild04, xmas_dun01, yuno_fild03) those numbers are the unique identifiers.
if there is only 1 spawn, then just write 1.
succeeding spawn is 2 then 3 ....
All other suggestions to simplify and improve @AnnieRuru yohoo! my master.
Last edited by a moderator: