Jump to content
Emistry

Utility: [SQL] Mission Board

Recommended Posts

Excuse me , I am getting this error on my emulator.
 

[Warning]: script:getelementofarray: index out of range (128)
[Debug]: Data: variable name='[email protected]_array' index=0
[Debug]: Source (NPC): mission_board (invisible/not on a map)

what might be the problem ? I'm using rAthena 17701 from github.

Link to comment
Share on other sites

... this script has many bugs <.<

now I feel like want to update/fix this myself

I don't want members to think that my original one has bug

@Emistry you better don't taint my name !

[paste=2kmtv0zl51by]

1. added bindatcmd, type "@mission" will allow you to display the current mission progress

2. fix the infinite loop bug as mentioned above

3. fix maximum level input problem when setup a mission

4. fix mission board allow to do mission without any time limit

5. fix when player login, the data explode wrongly

Link to comment
Share on other sites

stoped using this because for a weird reason it make my server mobs and even mvps to not walk or being not aggressive, even sometimes players couldn't walk

 

i know it sounds weird but when i removed the script everything went fine

 

since then i make my quests/misions manually with quest_db i get tired so quick x______x

Link to comment
Share on other sites

stoped using this because for a weird reason it make my server mobs and even mvps to not walk or being not aggressive, even sometimes players couldn't walk

it sounds like an infinite loop problem

however I'm not able to detect any freeloop in this script o.o

this is a performance killer script ?

then, maybe this script access too much query_sql ?

I wonder how many players in your server ?

and how high is your check_goto_count

Link to comment
Share on other sites

 

stoped using this because for a weird reason it make my server mobs and even mvps to not walk or being not aggressive, even sometimes players couldn't walk

it sounds like an infinite loop problem

however I'm not able to detect any freeloop in this script o.o

this is a performance killer script ? /dunno

then, maybe this script access too much query_sql ? // maybe, i made about 13 npcs and each had about 7 quests to kill some mvps and common mobs

I wonder how many players in your server ? //it was around 8 players when the bug appeared

and how high is your check_goto_count //i don't use them at all, just in a few simple npcs that just give info to the players

 

 

i wasn't refering tot his actual one, i was refering to the first version

Link to comment
Share on other sites

Hey Emistry, thank you for the awesome script!

 

I have one problem. The re-do delay and repeatable doesn't work for me for some reason. If I put 24 hours, it still let's me pick the mission over and over after completion, same with the repeatable status, it's always infinite.

 

I have to admit i did make some changes, but I believe nothing to have that result.

 

Another request if it isn't too much to ask, how do i make it so that when i put repeatable 1, the player can only do it once? Basically a "Can Do: 1 Time(s).

 

 

Here's the script. Thanks in advance. ^^;

- script mission_board -1,{
[email protected]_level = getgmlevel();
[email protected]_name$ = strnpcinfo(1);
[email protected]_npc_num = atoi( strnpcinfo(2) );
 
// check npc if it's a valid npc with number 1 ~ 500
if( [email protected]_npc_num || [email protected]_npc_num > 500 ){
message strcharinfo(0),"This NPC isnt working, invalid <'"+strnpcinfo(2)+"'>";
disablenpc strnpcinfo(0);
end;
}
 
// to assign offset index.
[email protected]_npc_num--;
query_sql( "SELECT COUNT(`id`) FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' ",[email protected]_count );
query_sql( "SELECT `id`,`mission_id`,`mob_hunt` FROM `player_mission` WHERE `mission_id` IN ( SELECT `id` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' ) AND `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' ",[email protected],[email protected]_id,[email protected]_hunt$ );
[email protected]_mission_size = getarraysize( [email protected] );
 
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "The Mission Board will instruct you to hunt certain monsters or items. Completing missions will result into rewards such as EXP and Midgard Coins";
next;
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Every player may pick up to ^FF0000"+.max_mission_per_char+" missions^000000 from the Mission Board.";
next;
switch( select( ( [email protected]_mission_size )?"Submit Mission":"",
( [email protected]_mission_size < .max_mission_per_char )?"Pick Mission":"",
( [email protected]_mission_size )?"Drop Mission":"",
( [email protected]_level < .gm_level || [email protected]_count )?"":"^FF0000[GM] Update Mission^000000",
( [email protected]_level < .gm_level )?"":"^FF0000[GM] Setup Mission^000000",
( [email protected]_level < .gm_level || [email protected]_count  )?"":"^FF0000[GM] Delete Mission^000000" ) ){
Case 1:
 
// get mission data from sql
query_sql( "SELECT * FROM `mission_board` WHERE `id` = "[email protected]_id[[email protected]]+" LIMIT 1",
[email protected]_id,
[email protected]$,
[email protected]$,
[email protected]_list$,
[email protected]_qty$,
[email protected]_list$,
[email protected]_qty$,
[email protected]_job_bitmask,
[email protected]_branch_bitmask,
[email protected]_lv,
[email protected]_lv,
[email protected],
[email protected],
[email protected]_list$,
[email protected]_qty$,
[email protected],
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]$,
[email protected]_update$,
[email protected]_id$,
[email protected]_delay
);
 
// explode all saved strings to array value.
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
if( [email protected]_size )
callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
if( [email protected]_size )
callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
if( [email protected]_size )
callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_npc_size = callsub( OnExplodeArray,[email protected]_id$,[email protected]_npc_array$,1 );
 
setarray [email protected]_range,[email protected]_lv,[email protected]_lv;
 
// display the information of mission
[email protected] = callsub( OnDisplayMissionInfo,
[email protected]_id,
[email protected]$,
[email protected]$,
[email protected]_range,
[email protected],
[email protected][[email protected]],
[email protected]_list,
[email protected]_qty,
[email protected]_list,
[email protected]_qty,
[email protected]_job_bitmask,
[email protected]_branch_bitmask,
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]_list,
[email protected]_qty,
[email protected]_npc_array$,
[email protected]_update$,
[email protected]_delay,
1|2|4|8
);
 
// check completed how many times.
if( [email protected][[email protected]] ){
query_sql( "SELECT COUNT(`id`),TIMESTAMPDIFF( HOUR,`completion`,NOW() ),DATE_ADD( `completion`, INTERVAL "[email protected]_delay+" HOUR) FROM `player_mission` WHERE `mission_id` = "[email protected][[email protected]]+" AND `completion` <> '0000-00-00 00:00:00'",[email protected]_completed,[email protected]_delay,[email protected]$ );
if( [email protected][[email protected]] && ( ( [email protected]_completed >= [email protected][[email protected]] ) || ( [email protected]_delay && [email protected]_delay <= [email protected]_delay ) ) ){
next;
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes " ";
if( [email protected]_completed >= [email protected][[email protected]] ){
mes "You can't pick this mission. You have completed this mission "[email protected]_completed+" time(s). You may only do it that many times.";
close;
}
if( [email protected]_delay && [email protected]_delay <= [email protected]_delay ){
mes "You cant pick this mission, the re-do delay hasn't passed yet.";
mes "Approximate : ^FF0000"[email protected]$+"^000000";
close;
}
}
}
 
// submit mission or not
if( [email protected] ){
message strcharinfo(0),"Failed to submit this mission.";
}else{
next;
if( select( "Submit Completed Mission","Cancel" ) == 1 ){
for( [email protected] = ( @ms_size - 1 ); [email protected] >= 0; [email protected] )
if( @ms_list$[[email protected]] == ""[email protected]_id ){
mes "^0055FF[ "[email protected]_name$+" ]^000000";
query_sql( "UPDATE `player_mission` SET `completion` = NOW() WHERE `cid` = "+getcharid(0)+" AND `mission_id` = "[email protected]_id );
mes "Mission accomplished.";
@ms_size--;
 
// clear requirement.
setd( "@ms_"[email protected]_id+"_expire" ),0;
deletearray getd( "@ms_"[email protected]_id+"_list" );
deletearray getd( "@ms_"[email protected]_id+"_qty" );
deletearray getd( "@ms_"[email protected]_id+"_hunt" );
if( [email protected]_size )
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
debugmes getitemname( [email protected]_list[[email protected]] )+" - "[email protected]_qty[[email protected]];
}
// delitem [email protected]_list[[email protected]],[email protected]_qty[[email protected]];
 
mes "Here are your rewards!";
// rewards
getexp [email protected],[email protected];
if( [email protected]_size )
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
getitem [email protected]_list[[email protected]],[email protected]_qty[[email protected]];
#CASHPOINTS += [email protected];
Zeny += [email protected];
break;
}
mes " ";
}
}
break;
Case 2:
// get info from SQL.
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
deletearray [email protected];
query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' AND `id` NOT IN ( SELECT `mission_id` FROM `player_mission` WHERE `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' ) LIMIT "+.max_page_size+" OFFSET "[email protected],[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
[email protected] += .max_page_size;
[email protected] = getarraysize( [email protected] );
if( [email protected] ){
mes "There are no other available missions to pick.";
close;
 
}else{
mes "Pick a mission~";
mes "Reminder, the EXP reward that may look like very little is still going to be multiplied by 30 times, which is what our Quest EXP rates are set to!";
[email protected]_menu$ = "";
for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ )
[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
}
next;
[email protected] = select( [email protected]_menu$+ ( ( [email protected] < .max_page_size )?"":"- next page" ) ) - 1;
}while( [email protected] == [email protected] );
 
query_sql( "SELECT * FROM `mission_board` WHERE `id` = "[email protected][[email protected]]+" LIMIT 1",
[email protected]_id,
[email protected]$,
[email protected]$,
[email protected]_list$,
[email protected]_qty$,
[email protected]_list$,
[email protected]_qty$,
[email protected]_job_bitmask,
[email protected]_branch_bitmask,
[email protected]_lv,
[email protected]_lv,
[email protected],
[email protected],
[email protected]_list$,
[email protected]_qty$,
[email protected],
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]$,
[email protected]_update$,
[email protected]_id$,
[email protected]_delay
);
 
// explode all saved strings to array value.
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_npc_size = callsub( OnExplodeArray,[email protected]_id$,[email protected]_npc_array$,1 );
 
setarray [email protected]_range,[email protected]_lv,[email protected]_lv;
 
// display the information of mission
[email protected] = callsub( OnDisplayMissionInfo,
[email protected]_id,
[email protected]$,
[email protected]$,
[email protected]_range,
[email protected],
( [email protected] + gettimetick(2) ),
[email protected]_list,
[email protected]_qty,
[email protected]_list,
[email protected]_qty,
[email protected]_job_bitmask,
[email protected]_branch_bitmask,
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]_list,
[email protected]_qty,
[email protected]_npc_array$,
[email protected]_update$,
[email protected]_delay,
1|8
);
 
// check completed how many times.
if( [email protected][[email protected]] ){
query_sql( "SELECT COUNT(`id`),TIMESTAMPDIFF( HOUR,`completion`,NOW() ),DATE_ADD( `completion`, INTERVAL "[email protected]_delay+" HOUR) FROM `player_mission` WHERE `mission_id` = "[email protected][[email protected]]+" AND `completion` <> '0000-00-00 00:00:00'",[email protected]_completed,[email protected]_delay,[email protected]$ );
if( [email protected][[email protected]] && ( ( [email protected]_completed >= [email protected][[email protected]] ) || ( [email protected]_delay && [email protected]_delay <= [email protected]_delay ) ) ){
next;
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes " ";
if( [email protected]_completed >= [email protected][[email protected]] ){
mes "You cant pick this mission, you have mission completion reach the max repeatable attempt of "[email protected]_completed+" times.";
close;
}
if( [email protected]_delay && [email protected]_delay <= [email protected]_delay ){
mes "You cant pick this mission, you have mission redo delay isnt finish yet.";
mes "Approximate : ^FF0000"[email protected]$+"^000000";
close;
}
}
}
 
if( [email protected] ){
message strcharinfo(0),"Failed to pick this mission.";
}else{
if( select( "Pick Mission","Cancel" ) == 1 ){
query_sql( "INSERT INTO `player_mission` VALUES ( "+gettimetick(2)+","[email protected]_id+","+getcharid(3)+","+getcharid(0)+",'"+escape_sql( strcharinfo(0) )+"','',"+( [email protected] + gettimetick(2) )+",NOW(),'0000-00-00 00:00:00' );" );
message strcharinfo(0),"Picked Mission # "[email protected]_id;
 
@ms_list$[ @ms_size ] = ""[email protected]_id;
@ms_size++;
 
copyarray getd( "@ms_"[email protected]_id+"_list[0]" ),[email protected]_list[0],[email protected]_size;
copyarray getd( "@ms_"[email protected]_id+"_qty[0]" ),[email protected]_qty[0],[email protected]_size;
deletearray getd( "@ms_"[email protected]_id+"_hunt" );
addtimer ( [email protected] * 1000 ),.npc_name$+"::OnTimeCheck";
}
}
break;
Case 3:
query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' AND `id` IN ( SELECT `mission_id` FROM `player_mission` WHERE `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' )",[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
[email protected]_size = getarraysize( [email protected] );
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Pick a Mission to remove.";
next;
[email protected] = select( [email protected]_menu$ ) - 1;
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Please confirm that you want to remove ^0055FFMission # "[email protected][[email protected]]+"^000000.";
mes "Title: ^0055FF"[email protected]$[[email protected]]+"^000000";
mes "^777777NOTE: Any progress you've made for this mission will be lost!^000000";
if( select( "Don't drop mission.","Drop mission." ) == 2 ){
message strcharinfo(0),"Dropped Mission # "[email protected][[email protected]];
query_sql( "DELETE FROM `player_mission` WHERE `mission_id` = "[email protected][[email protected]]+" AND `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00'" );
setd( "@ms_"[email protected][[email protected]]+"_expire" ),0;
deletearray getd( "@ms_"[email protected][[email protected]]+"_list" );
deletearray getd( "@ms_"[email protected][[email protected]]+"_qty" );
deletearray getd( "@ms_"[email protected][[email protected]]+"_hunt" );
for( [email protected] = 0; [email protected] < @ms_size; [email protected]++ )
if( ""[email protected][[email protected]] == @ms_list$[[email protected]] ){
deletearray @ms_list$[[email protected]],1;
@ms_size--;
break;
}
}
break;
Case 4:
// get info from SQL.
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
deletearray [email protected];
query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' LIMIT "+.max_page_size+" OFFSET "[email protected],[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
[email protected] += .max_page_size;
[email protected] = getarraysize( [email protected] );
if( [email protected] ){
mes "There are no available mission to update.";
close;
 
}else{
mes "Pick a mission.";
[email protected]_menu$ = "";
for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ )
[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
}
next;
[email protected] = select( [email protected]_menu$+ ( ( [email protected] < .max_page_size )?"":"- next page" ) ) - 1;
}while( [email protected] == [email protected] );
query_sql( "SELECT * FROM `mission_board` WHERE `id` = "[email protected][[email protected]],
[email protected]_mission_id,
[email protected]$,
[email protected]$,
[email protected]_list$,
[email protected]_qty$,
[email protected]_list$,
[email protected]_qty$,
[email protected]_job_bitmask,
[email protected]_branch_bitmask,
[email protected]_lv,
[email protected]_lv,
[email protected],
[email protected],
[email protected]_list$,
[email protected]_qty$,
[email protected],
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]$,
[email protected]_update$,
[email protected]_id$,
[email protected]_delay
);
// explode all saved strings to array value.
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
[email protected]_npc_size = callsub( OnExplodeArray,[email protected]_id$,[email protected]_npc_array$,1 );
 
setarray [email protected]_range,[email protected]_lv,[email protected]_lv;
 
Case 5:
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
// display the information of mission
callsub( OnDisplayMissionInfo,
[email protected]_mission_id,
[email protected]$,
[email protected]$,
[email protected]_range,
[email protected],
( [email protected] + gettimetick(2) ),
[email protected]_list,
[email protected]_qty,
[email protected]_list,
[email protected]_qty,
[email protected]_job_bitmask,
[email protected]_branch_bitmask,
[email protected],
[email protected],
[email protected],
[email protected],
[email protected]_list,
[email protected]_qty,
[email protected]_npc_array$,
[email protected]_update$,
[email protected]_delay,
0
);
 
// check if required info complete for setup mission
[email protected] = 0;
if( [email protected]$ == "" ) [email protected] |= 1;
if( [email protected]$ == "" ) [email protected] |= 2;
if( [email protected]_size && [email protected]_size ) [email protected]complete |= 4;
if( getarraysize( [email protected]_range ) != 2 || [email protected]_job_bitmask || [email protected]_branch_bitmask ) [email protected] |= 8;
if( [email protected]_size && [email protected] && [email protected] && [email protected] && [email protected] ) [email protected] |= 16;
if( [email protected]_npc_size ) [email protected] |= 32;
 
[email protected]_option = select( "Edit Title "+(( [email protected] & 1 )?"^FF0000-incomplete-^000000":"" ),
"Edit Description "+(( [email protected] & 2 )?"^FF0000-incomplete-^000000":"" ),
"Edit Monster List "+(( [email protected] & 4 )?"^FF0000-incomplete-^000000":( ( [email protected]_size )?"^777777-none-^000000":"" )),
"Edit Item List "+(( [email protected] & 4 )?"^FF0000-incomplete-^000000":( ( [email protected]_size )?"^777777-none-^000000":"" )),
"Edit Class/Level Limitation "+(( [email protected] & 8 )?"^FF0000-incomplete-^000000":"" ),
"Edit Time/Repeat/Mission Limitation ",
"Edit Reward List "+(( [email protected] & 16 )?"^FF0000-incomplete-^000000":"" ),
"Edit NPC Limitation "+(( [email protected] & 32 )?"^FF0000-incomplete-^000000":"" ),
( [email protected] )?"":"^0055FF - Complete Setup Mission^000000" );
next; 
switch( [email protected]_option ){
Case 1:
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Enter Title";
mes "^777777( Length: 4 ~ 30 )^000000";
while( input( [email protected]$,4,30 ) );
[email protected]_result = replacestr( [email protected]$,":"," " );
break;
Case 2:
[email protected]$ = "";
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Enter Description";
mes "^777777( Length: 4 ~ 255 )^000000";
mes " ";
mes "^0055FF"[email protected]$+"^000000";
[email protected] = getstrlen( [email protected]$ );
do{
[email protected]_result = input( [email protected]_input$,4,255 );
if( [email protected]_result )
message strcharinfo(0),"Input length must between 4 ~ 255";
}while( [email protected]_result );
[email protected]$ = [email protected]$ + " "+ [email protected]_input$;
mes "^0055FF"[email protected]_input$+"^000000";
[email protected] = getstrlen( [email protected]$ );
next;
}while( select( ( [email protected] >= 255 )?"":"add more ^777777( left "+( 255 - [email protected] )+" words )^000000","-back" ) == 1 );
[email protected]$  = replacestr( [email protected]$,":"," " );
break;
Case 3:
if( [email protected]_mission_id ){
dispbottom "Editing monster list might caused unwanted behaviours of scripts.  Which may included :";
dispbottom " > Script/Missions isnt working properly.";
dispbottom " > Deletion of player mission's progress.";
dispbottom " > etc.";
dispbottom "Overall it's not suggested to edit monster list that you have set early.";
dispbottom "( Recommend for Re-Adding mission, if needed )";
}
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Monsters to kill:";
if( [email protected]_size ){
[email protected]_menu$ = "";
[email protected]_mob_list$ = "|";
deletearray [email protected]_mob$;
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_name$ = getmonsterinfo( [email protected]_list[[email protected]],MOB_NAME );
[email protected]_menu$ = [email protected]_menu$ + [email protected]_qty[[email protected]] +" x "[email protected]_name$ +":";
mes " ^777777 ~ "[email protected]_qty[[email protected]]+" x "[email protected]_name$+"^000000";
[email protected]_mob_list$ = [email protected]_mob_list$ + [email protected]_list[[email protected]] +"|";
}
 
}else{
mes " ^777777 ~ Unavailable ^000000";
}
mes " ";
[email protected] = select( ( [email protected]_size >= .max_required_monster )?"":"Add Monster",( [email protected]_size )?"Delete Monster":"","- Back" );
switch( [email protected] ){
Case 1:
mes "Enter Monster ID";
do{
input [email protected]_id;
if( [email protected]_id ) break;
[email protected]_name$ = getmonsterinfo( [email protected]_id,MOB_NAME );
}while( [email protected]_name$ == "null" );
if( [email protected]_name$ != "null" && [email protected]_id ){
mes "How many "[email protected]_name$+" need to hunt ?";
input [email protected],0,30000;
if( [email protected] ){
if( compare( "|"[email protected]_mob_list$+"|","|"[email protected]_id+"|" ) ){
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
if( [email protected]_list[[email protected]] == [email protected]_id ){
[email protected]_qty[[email protected]] += [email protected];
break;
}
 
}else{
[email protected]_list[[email protected]_size] = [email protected]_id;
[email protected]_qty[[email protected]_size] = [email protected];
[email protected]_size++;
}
}
}
break;
Case 2:
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Pick a Monster to Remove.";
[email protected] = select( [email protected]_menu$+"- Back" ) - 1;
if( [email protected] < [email protected]_size ){
deletearray [email protected]_list[[email protected]],1;
deletearray [email protected]_qty[[email protected]],1;
[email protected]_size--;
}
default: break;
}
if( [email protected] < 3 ) next;
}while( [email protected] < 3 );
break;
Case 4:
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Required Item List: ";
if( [email protected]_size ){
[email protected]_menu$ = "";
[email protected]_item_list$ = "|";
deletearray [email protected]_item$;
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_name$ = getitemname( [email protected]_list[[email protected]] );
[email protected]_menu$ = [email protected]_menu$ + [email protected]_qty[[email protected]] +"x "[email protected]_name$ +":";
mes " ^777777 ~ "[email protected]_qty[[email protected]]+" x "[email protected]_name$+"^000000";
[email protected]_item_list$ = [email protected]_item_list$ + [email protected]_list[[email protected]] + "|";
}
 
}else{
mes " ^777777 ~ Unavailable ^000000";
}
mes " ";
[email protected] = select( ( [email protected]_size >= .max_required_item )?"":"Add Item",( [email protected]_size )?"Delete Item":"","- Back" );
switch( [email protected] ){
Case 1:
do{
input [email protected]_id;
if( [email protected]_id ) break;
[email protected]_name$ = getitemname( [email protected]_id );
}while( [email protected]_name$ == "null" || [email protected]_name$ == "" );
if( [email protected]_id && [email protected]_name$ != "null" && [email protected]_name$ != "" ){
mes "How many "[email protected]_name$+" need to collect ?";
input [email protected],0,30000;
if( [email protected] ){
if( compare( "|"[email protected]_item_list$+"|","|"[email protected]_id+"|" ) ){
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
if( [email protected]_list[[email protected]] == [email protected]_id ){
[email protected]_qty[[email protected]] += [email protected];
break;
}
}else{
[email protected]_list[[email protected]_size] = [email protected]_id;
[email protected]_qty[[email protected]_size] = [email protected];
[email protected]_size++;
}
}
}
break;
Case 2:
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Pick an Item to Remove.";
[email protected] = select( [email protected]_menu$+" - Back" ) - 1;
if( [email protected] < [email protected]_size ){
mes "Removed "[email protected]_qty[[email protected]]+" x "+getitemname( [email protected]_list[[email protected]] );
deletearray [email protected]_list[[email protected]],1;
deletearray [email protected]_qty[[email protected]],1;
[email protected]_size--;
}
default: break;
}
if( [email protected] < 3 ) next;
}while( [email protected] < 3 );
break;
Case 5: // class limitation
if( [email protected]_job_bitmask ){
// enable all job by default.
for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ ){
[email protected]_value = ( 1 << [email protected] );
[email protected]_job_bitmask |= [email protected]_value;
}
// enable all inherited classes by default.
for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ ){
[email protected]_value = ( 1 << [email protected] );
[email protected]_branch_bitmask |= [email protected]_value;
}
}
 
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Level Range: "+( ( [email protected]_range[1] )? "^777777"[email protected]_range[0]+" ~ "[email protected]_range[1]:"^FF0000-incomplete-" )+"^000000";
mes "Available Job Setting";
if( [email protected]_job_bitmask ){
for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ )
if( [email protected]_job_bitmask & ( 1 << [email protected] ) )
mes " ^777777 ~ "+jobname( roclass( .base_job[[email protected]] ) )+" ^000000";
}else{
mes " ^FF0000 -incomplete-^000000";
}
mes " ";
mes "Inherited Branch Setting";
if( [email protected]_branch_bitmask ){
for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ )
if( [email protected]_branch_bitmask & ( 1 << [email protected] ) )
mes " ^777777 ~ "+.job_branch_name$[[email protected]]+" ^000000"; 
}else{
mes " ^FF0000 -incomplete-^000000";
} 
next;
[email protected] = select( "Edit Base Job","Edit Job Branch","Edit Level Range","- Back" );
switch( [email protected] ){
Case 1:
dispbottom "[ Base Job Class ] RED = Disable , GREEN = Enable";
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Available Job List:";
[email protected]_job_menu$ = "";
for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ ){
[email protected]_name$ = jobname( roclass( .base_job[[email protected]] ) );
if( [email protected]_job_bitmask & ( 1 << [email protected] ) )
mes " ^777777 ~ "[email protected]_name$+" ^000000"; 
[email protected]_job_menu$ = [email protected]_job_menu$ + (( [email protected]_job_bitmask & ( 1 << [email protected] ) )?"^4EEE94":"^FF0000" ) + [email protected]_name$ +"^000000:";
}
next;
[email protected] = select( [email protected]_job_menu$+"- Back" ) - 1;
if( [email protected] < .base_job_size ){
[email protected]_value = ( 1 << [email protected] );
if( [email protected]_job_bitmask & [email protected]_value )
[email protected]_job_bitmask -= [email protected]_value;
else
[email protected]_job_bitmask |= [email protected]_value;
}
}while( [email protected] < .base_job_size );
break;
Case 2:
dispbottom "[ Inherited Job Branch ] RED = Disable , GREEN = Enable";
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Inherited Job Branch List:";
[email protected]_branch_menu$ = "";
for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ ){
if( [email protected]_branch_bitmask & ( 1 << [email protected] ) )
mes " ^777777 ~ "+.job_branch_name$[[email protected]]+" ^000000"; 
[email protected]_branch_menu$ = [email protected]_branch_menu$ + (( [email protected]_branch_bitmask & ( 1 << [email protected]i ) )?"^4EEE94":"^FF0000" ) + .job_branch_name$[[email protected]] +"^000000:";
}
next;
[email protected] = select( [email protected]_branch_menu$+"- Back" ) - 1;
if( [email protected] < .job_branch_size ){
[email protected]_value = ( 1 << [email protected] );
if( [email protected]_branch_bitmask & [email protected]_value )
[email protected]_branch_bitmask -= [email protected]_value;
else
[email protected]_branch_bitmask |= [email protected]_value;
}
}while( [email protected] < .job_branch_size );
break;
Case 3:
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Minimum Level";
input [email protected]_range[0],1,.server_max_level ;
mes "Maximum Level";
input [email protected]_range[1],[email protected]_range[0],.server_max_level;
default: break;
}
if( [email protected] < 4 ) next;
}while( [email protected] < 4 );
break;
Case 6: // mission limitation
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Can do: ^777777"+( ( [email protected] )?"Unlimited times":""[email protected] )+" time(s)^000000";
mes "Redo Delay: ^777777"+( ( [email protected]_delay )?"Unavailable":callsub( OnTime2Str,( ( [email protected]_delay * 3600 ) + gettimetick(2) ) ))+"^000000";
mes "Time Limit: ^777777"+( ( [email protected] )?"Unavailable":callsub( OnTime2Str,( [email protected] + gettimetick(2) ) ) )+"^000000";
[email protected] = select( "Edit Repeatable Status","Edit Time Limit","Edit Re-do Delay","Edit Required Mission","- Back" );
switch( [email protected] ){
Case 1:
mes "How many time can this mission repeat ??";
mes "^777777( 0 = unlimited )^000000";
input [email protected],0,100;
break;
Case 2:
mes "Time Limit of mission";
mes "      1 = 1 minute";
mes "    60 = 1 hour";
mes "1440 = 1 day";
input [email protected],0,50000;
[email protected] *= 60;
break;
Case 3:
mes "Time Delay to re-take the mission";
mes "     1 =  1 hour";
mes "   24 =  1 day";
mes " 720 = 30 day";
input [email protected]_delay,0,50000;
break;
Case 4:
mes "This is not fully implemented yet.. still in beta test";
break;
 
do{
mes "Required Mission:";
if( [email protected]_mission_size ){
for( [email protected] = 0; [email protected] < [email protected]_mission_size; [email protected]++ ){
mes " ^777777 ~ "[email protected]_mission$[[email protected]]+"^000000";
[email protected]_mission_menu$ = [email protected]_mission_menu$ + [email protected]_mission$[[email protected]] +":";
}
 
}else{
mes "^777777 none ^000000";
}
next;
[email protected]_option = select( ( [email protected]_mission_size < .max_required_mission )?"Add required mission":"",
( [email protected]_mission_size )?"Remove required mission":"",
"- Back");
switch( [email protected]_option ){
Case 1:
mes "Enter mission ID";
mes "^777777( enter 0 to cancel )^000000";
do{
input [email protected]_id$;
if( [email protected]_id$ == "0" ) break;
}while( compare( "|"[email protected]_mission_menu$+"|","|"[email protected]_id$+"|" ) );
[email protected]_id$ = replacestr( [email protected]_id$,":","" );
if( [email protected]_id$ != "0" ){
[email protected]_mission$[[email protected]_mission_size] = [email protected]_id$;
[email protected]_mission_size++;
}
break;
Case 2:
mes "Select a mission to remove.";
[email protected] = select( [email protected]_mission_menu$ ) - 1;
deletearray [email protected]_mission$[[email protected]],1;
default: break;
}
}while( [email protected]_option < 3 );
default: break;
}
if( [email protected] < 5 ) next;
}while( [email protected] < 5 );
break;
Case 7: // reward list
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Zeny: ^777777"+( ( [email protected] )? [email protected]:"None" )+"^000000";
mes "Reward Item List: ";
if( [email protected]_size ){
[email protected]_menu$ = "";
deletearray [email protected]_reward$;
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_name$ = getitemname( [email protected]_list[[email protected]] );
[email protected]_menu$ = [email protected]_menu$ + [email protected]_qty[[email protected]] +"x "[email protected]_name$ +":";
[email protected]_reward$[[email protected]] = [email protected]_name$;
mes " ^777777 ~ "[email protected]_qty[[email protected]]+" x "[email protected]_name$+"^000000";
}
[email protected]_reward_list$ = implode( [email protected]_reward$,"|" );
 
}else{
mes " ^777777 ~ none ^000000";
}
mes "Base EXP: ^777777"+( ( [email protected] )? [email protected]:"None" )+"^000000";
mes "Job EXP: ^777777"+( ( [email protected] )? [email protected]:"None" )+"^000000";
mes " ";
next;
[email protected] = select( ( [email protected]_size >= .max_required_item )?"":"Add Item Reward",
( [email protected]_size )?"Delete Item Reward":"",
"Edit Cash Reward",
"Edit Zeny Reward",
"Edit Base EXP Reward",
"Edit Job EXP Reward",
"- Back" );
mes "^0055FF[ "[email protected]_name$+" ]^000000";
switch( [email protected] ){
Case 1:
mes "Enter Reward Item ID";
do{
input [email protected]_id;
if( [email protected]_id ) break;
[email protected]_name$ = getitemname( [email protected]_id );
}while( [email protected]_name$ == "null" || [email protected]_name$ == "" );
if( [email protected]_id && [email protected]_name$ != "null" && [email protected]_name$ != "" ){
mes "How many "[email protected]_name$+" will be rewarded ?";
input [email protected],0,30000;
if( [email protected] ){
if( compare( "|"[email protected]_reward_list$+"|","|"[email protected]_name$+"|" ) ){
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
if( [email protected]_list[[email protected]] == [email protected]_id ){
[email protected]_qty[[email protected]] += [email protected];
break;
}
}else{
[email protected]_list[[email protected]_size] = [email protected]_id;
[email protected]_qty[[email protected]_size] = [email protected];
[email protected]_size++;
}
}
}
break;
Case 2:
mes "Pick an Reward to Remove.";
[email protected] = select( [email protected]_menu$ ) - 1;
mes "Removed "[email protected]_qty[[email protected]]+"x "+getitemname( [email protected]_list[[email protected]] );
deletearray [email protected]_list[[email protected]],1;
deletearray [email protected]_qty[[email protected]],1;
[email protected]_size--;
break;
Case 3:
mes "How many Cash will be given ?";
mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
input [email protected],0,.max_integer_value;
break;
Case 4:
mes "How many Zeny will be given ?";
mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
input [email protected],0,.max_integer_value;
break;
Case 5:
mes "How many Base EXP reward ?";
mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
input [email protected],0,.max_integer_value;
break;
Case 6:
mes "How many Job EXP reward ?";
mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
input [email protected],0,.max_integer_value;
default: break;
}
next;
}while( [email protected] < 7 );
break;
Case 8: // npc limitation
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "By default, the mission will be available from each mission board npc ^FF0000unless you have specified which NPC may offer this mission.^000000";
mes " ";
mes "Just pick all the NPC that may offer this mission if you wish.";
next;
if( !getarraysize( [email protected]_npc_array$ ) )
for( [email protected] = 0; [email protected] < .mission_npc_count; [email protected]++ ){
[email protected]_npc_array$[[email protected]] = ""[email protected];
[email protected]_npc_size++;
}
dispbottom "[ NPC Limitation ] RED = Disable , GREEN = Enable";
 
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Mission offered by: ";
[email protected]_npc_menu$ = "";
if( [email protected]_npc_size >= 2 ){
[email protected]_npc$ = "|"+implode( [email protected]_npc_array$,"|" )+"|";
}else{
[email protected]_npc$ = "|"[email protected]_npc_array$+"|";
}
for( [email protected] = 0; [email protected] < .mission_npc_count; [email protected]++ ){
getmapxy( [email protected]$,[email protected],[email protected],1,.npc_unique_list$[[email protected]] );
[email protected]_npc_name$ = ( ( compare( "|"[email protected]_npc$+"|","|"[email protected]+"|" ) )?"^44EE00":"^FF0000" );
[email protected]_npc_name$ = [email protected]_npc_name$ + .npc_name_list$[[email protected]];
mes "^777777("[email protected]$+") "[email protected]_npc_name$;
[email protected]_npc_menu$ = [email protected]_npc_menu$ + [email protected]_npc_name$ +":";
}
next;
[email protected] = select( [email protected]_npc_menu$+"^000000- Back" ) - 1;
if( [email protected] < .mission_npc_count ){
if( compare( "|"[email protected]_npc$+"|","|"[email protected]+"|" ) )
[email protected]_npc_array$[[email protected]] = "";
else
[email protected]_npc_array$[[email protected]] = ""[email protected];
[email protected]_npc_size = getarraysize( [email protected]_npc_array$ );
}
// dispbottom "["+rand(10,99)+"] "+implode( [email protected]_npc_array$,"|" );
}while( [email protected] < .mission_npc_count );
break;
default: break;
}
next;
}while( [email protected]_option < 9 );
 
// finalise all variable
if( [email protected]_size ){
[email protected]_mob_list$ = "|";
[email protected]_mob_qty$ = "|";
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_mob_list$ = [email protected]_mob_list$ + [email protected]_list[[email protected]] +"|";
[email protected]_mob_qty$ = [email protected]_mob_qty$ + [email protected]_qty[[email protected]] +"|";
} 
}
 
if( [email protected]_size ){
[email protected]_item_list$ = "|";
[email protected]_item_qty$ = "|";
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_item_list$ = [email protected]_item_list$ + [email protected]_list[[email protected]] +"|";
[email protected]_item_qty$ = [email protected]_item_qty$ + [email protected]_qty[[email protected]] +"|";
}
}
 
if( [email protected]_size ){
[email protected]_reward_list$ = "|";
[email protected]_reward_qty$ = "|";
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_reward_list$ = [email protected]_reward_list$ + [email protected]_list[[email protected]] +"|";
[email protected]_reward_qty$ = [email protected]_reward_qty$ + [email protected]_qty[[email protected]] +"|";
}
}
 
if( [email protected]_npc_size ){
[email protected]_npc_list$ = "|";
for( [email protected] = 0; [email protected] < [email protected]_npc_size; [email protected]++ )
[email protected]_npc_list$ = [email protected]_npc_list$ + [email protected]_npc_array$[[email protected]] +"|";
}
 
if( [email protected]_mission_id ){
[email protected]new_mission_id = gettimetick(2);
message strcharinfo(0),"Mission # "[email protected]_mission_id+" has been added.";
}else{
message strcharinfo(0),"Mission # "[email protected]_mission_id+" has been updated.";
// attach and inform other online players.
callsub( OnRemoveMission,[email protected]_mission_id,"A GM updated Mission # "[email protected]_mission_id );
}
 
// add new mission into SQL
query_sql( 
"REPLACE INTO `mission_board` VALUES ( " +
[email protected]_mission_id+", " +
"'"+escape_sql( [email protected]$ )+"', " +
"'"+escape_sql( [email protected]$ )+"', " +
"'"+escape_sql( [email protected]_mob_list$ )+"', " +
"'"+escape_sql( [email protected]_mob_qty$ )+"', " +
"'"+escape_sql( [email protected]_item_list$ )+"', " +
"'"+escape_sql( [email protected]_item_qty$ )+"', " +
[email protected]_job_bitmask+", " +
[email protected]_branch_bitmask+", " +
[email protected]_range[0]+", " +
[email protected]_range[1]+", " +
[email protected]+", " +
[email protected]+", " +
"'"+escape_sql( [email protected]_reward_list$ )+"', " +
"'"+escape_sql( [email protected]_reward_qty$ )+"', " +
[email protected]+", " +
[email protected]+", " +
[email protected]+", " +
[email protected]+", " +
getcharid(3)+", " +
"'"+escape_sql( strcharinfo(0) )+"', " +
"NOW(), " +
"'"+escape_sql( [email protected]_npc_list$ )+"', " +
[email protected]_delay +
" ); " 
);
break;
Case 6: // delete mission
do{
mes "^0055FF[ "[email protected]_name$+" ]^000000";
deletearray [email protected];
query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' LIMIT "+.max_page_size+" OFFSET "[email protected],[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
[email protected] += .max_page_size;
[email protected] = getarraysize( [email protected] );
if( [email protected] ){
mes "There are no available mission to update.";
close;
 
}else{
mes "Pick a mission.";
for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ )
[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
}
next;
[email protected] = select( [email protected]_menu$+ ( ( [email protected] < .max_page_size )?"":"- next page" ) ) - 1;
}while( [email protected] == [email protected] );
[email protected]_id = [email protected][[email protected]];
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "Are you sure to remove this mission ?";
if( select( "Ýes, remove mission.","Delete Mission" ) == 2 ){
query_sql( "DELETE FROM `mission_board` WHERE `id` = "[email protected]_id+" LIMIT 1" );
mes "Removed mission from mission list.";
 
// attach other online players and remove the missions.
callsub( OnRemoveMission,[email protected]_id,"A GM removed Mission # "[email protected]_id );
query_sql( "DELETE FROM `player_mission` WHERE `completion` = '0000-00-00 00:00:00' AND `mission_id` = "[email protected]_id );
mes "Removed mission from all players.";
}
default: break;
}
close;
 
OnInit:
initnpctimer "mission_board";
// initialize settings
if( strnpcinfo(0) == "mission_board" ){
 
// gm level to access panel
.gm_level = 90;
// max no. of required monster
.max_required_monster = 10;
// max no. of required item
.max_required_item = 10;
// max no. of required mission ( un-implement yet )
.max_required_mission = 10;
// max no. of available mission
.max_mission_available = 50;
// max value of integer input
.max_integer_value = 2000000000;
// max amount of mission per page
.max_page_size = 30;
// max mission per npc take by character
.max_mission_per_char = 3;
 
// predefined values.
.npc_name$ = strnpcinfo(0);
.server_max_level = getbattleflag( "max_lv" );
setarray .base_job,
EAJ_SWORDMAN,
EAJ_MAGE,
EAJ_ARCHER,
EAJ_ACOLYTE,
EAJ_MERCHANT,
EAJ_THIEF,
EAJ_TAEKWON,
EAJ_GUNSLINGER,
EAJ_NINJA;
.base_job_size = getarraysize( .base_job );
setarray .job_branch_name$,
"2-1 Classes",
"2-2 Classes",
"Rebirth Classes",
"Baby Classes",
"Third Classes";
setarray .job_branch,
EAJL_2_1,
EAJL_2_2,
EAJL_UPPER,
EAJL_BABY,
EAJL_THIRD;
.job_branch_size = getarraysize( .job_branch );
bindatcmd "mission", strnpcinfo(0)+"::OnCommand";
 
}else{
// delay the process
[email protected] = atoi( strnpcinfo(2) );
if( [email protected] && [email protected] <= 500 && .mission_npc_count < 100 ){
sleep( [email protected] + 1 );
.npc_name_list$[ .mission_npc_count ] = strnpcinfo(1);
.npc_unique_list$[ .mission_npc_count ] = strnpcinfo(0);
debugmes "["+.mission_npc_count+"]"+.npc_name_list$[ .mission_npc_count ]+"|"+.npc_unique_list$[ .mission_npc_count ];
.mission_npc_count++;
end;
 
}else if( [email protected] ){
debugmes "[Removed] "+strnpcinfo(0)+", invalid <num:'"+strnpcinfo(2)+"'>";
}else if( .mission_npc_count >= 100 ){
debugmes "[Skipped] "+strnpcinfo(0)+", max: 100 Total NPC.";
}
disablenpc strnpcinfo(0);
}
end;
 
// just used to display how many total Mission Board NPC.
OnTimer1000:
stopnpctimer;
debugmes "[ Mission Board ] Total NPC Loaded : "+.mission_npc_count+" ...";
end;
 
OnCommand:
if ( strnpcinfo(0) == .npc_name$ ) {
if ( @ms_size ) {
for ( [email protected] = 0; [email protected] < @ms_size; [email protected]++ ) {
[email protected]_size = getarraysize( getd( "@ms_"+ @ms_list$[[email protected]] +"_list" ) );
query_sql "select title, item_list, item_qty from mission_board where id = "+ @ms_list$[[email protected]], [email protected]$, [email protected]_id$, [email protected]_amount$;
if ( [email protected]_size ) {
for ( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
// dispbottom "[Mission '"+ [email protected]$ +"' Progress] Hunted "+ getd( "@ms_"+ @ms_list$[[email protected]] +"_hunt["+ [email protected] +"]" ) +"x "+ getmonsterinfo( getd( "@ms_"+ @ms_list$[[email protected]] +"_list["+ [email protected] +"]" ), MOB_NAME );
dispbottom "[Mission '"+ [email protected]$ +"' Progress] Hunted "+ getd( "@ms_"+ @ms_list$[[email protected]] +"_hunt["+ [email protected] +"]" ) +"/"+ getd( "@ms_"+ @ms_list$[[email protected]] +"_qty[" + [email protected] +"]" ) +" x "+ getmonsterinfo( getd( "@ms_"+ @ms_list$[[email protected]] +"_list["+ [email protected] +"]" ), MOB_NAME );
explode [email protected]_id_array$, [email protected]_id$, "|";
explode [email protected]_amount_array$, [email protected]_amount$, "|";
[email protected] = getarraysize( [email protected]_id_array$ );
for ( [email protected] = 1; [email protected] < [email protected]; [email protected]++ )
dispbottom "[Mission '"+ [email protected]$ +"' Progress] Collected "+ countitem( atoi( [email protected]_id_array$[[email protected]] ) ) +"/"+ [email protected]_amount_array$[[email protected]] +" x "+ getitemname( atoi( [email protected]_id_array$[[email protected]] ) );
}
}
}
}
end;
 
// OnWhisperGlobal:
OnPCLoginEvent:
if( strnpcinfo(0) == .npc_name$ ){
[email protected] = gettimetick(2);
query_sql( "SELECT `mission_id`,`expire`,`mob_hunt` FROM `player_mission` WHERE `completion` = '0000-00-00 00:00:00' AND `cid` = "+getcharid(0),@ms_list$,[email protected],[email protected]_hunt$ );
@ms_size = getarraysize( @ms_list$ );
if( @ms_size )
for( [email protected] = 0; [email protected] < @ms_size; [email protected]++ ){
if( [email protected] < [email protected][[email protected]] ){
[email protected] = ( [email protected][[email protected]] - [email protected] );
addtimer ( [email protected] * 1000 ),.npc_name$+"::OnTimeCheck";
//dispbottom "[ Mission Progress : "[email protected]_list$[[email protected]]+" , expire in "+callsub( OnTime2Str,( [email protected] + [email protected] ) )+" ]";
query_sql( "SELECT `mob_list`,`mob_qty` FROM `mission_board` WHERE `id` = "[email protected]_list$[[email protected]],[email protected]_list$,[email protected]_qty$ );
 
setd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ),[email protected][[email protected]];
if( callsub( OnExplodeArray,[email protected]_list$[[email protected]],getd( "@ms_"[email protected]_list$[[email protected]]+"_list" ),0 ) ){
callsub( OnExplodeArray,[email protected]_hunt$[[email protected]],getd( "@ms_"[email protected]_list$[[email protected]]+"_qty" ),0 );
[email protected]_size = callsub( OnExplodeArray,[email protected]_hunt$[[email protected]],getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt" ),0 );
// for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
// dispbottom  " ~ killed "+getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" )+"/"+getd( "@ms_"[email protected]_list$[[email protected]]+"_qty["[email protected]+"]" )+" x "+getmonsterinfo( getd( "@ms_"[email protected]_list$[[email protected]]+"_list["[email protected]+"]" ),MOB_NAME );
}
}
}
}
end;
 
OnPCLogoutEvent:
if( strnpcinfo(0) == .npc_name$ ){
if( @ms_size )
for( [email protected] = 0; [email protected] < @ms_size; [email protected]++ ){
debugmes "Saving "[email protected]_list$[[email protected]];
[email protected]_size = getarraysize( getd( "@ms_"[email protected]_list$[[email protected]]+"_list" ) );
if( [email protected]_size ){
copyarray [email protected]_array[0],getd( "@ms_"[email protected]_list$[[email protected]]+"_list[0]" ),[email protected]_size;
[email protected]_hunt$ = "|";
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
[email protected]_hunt$ = [email protected]_hunt$ + getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" ) +"|";
query_sql( "UPDATE `player_mission` SET `mob_hunt` = '"+escape_sql( [email protected]_hunt$ )+"' WHERE `mission_id` = "[email protected]_list$[[email protected]]+" AND `completion` = '0000-00-00 00:00:00' AND `cid` = "+getcharid(0) );
}
}
}
end;
 
OnNPCKillEvent:
if( strnpcinfo(0) == .npc_name$ ){
if( @ms_size ){
[email protected]$ = strcharinfo(3);
 
// by default mission wont work in PVP,GVG,Instance,Event maps
if( compare( [email protected]$,"@" ) || getmapflag( [email protected]$,mf_gvg ) || getmapflag( [email protected]$,mf_pvp )){
//dispbottom "[Mission Board] PvP, GvG, Instance and Event Map , include monsters will not affect Mission Progress.";
end;
}
 
[email protected] = gettimetick(2);
for( [email protected] = ( @ms_size - 1 ); [email protected] >= 0; [email protected] ){
[email protected]_size = getarraysize( getd( "@ms_"[email protected]_list$[[email protected]]+"_list" ) );
if( [email protected]_size ){
copyarray [email protected]_array[0],getd( "@ms_"[email protected]_list$[[email protected]]+"_list[0]" ),[email protected]_size;
for( [email protected] = 0; [email protected]_size; [email protected]++ )
if( [email protected]_array[[email protected]] == killedrid ){
[email protected] = getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" ) + 1;
setd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" ),[email protected];
dispbottom "[Mission #"[email protected]_list$[[email protected]]+" Progress] You have killed "[email protected]+"x "+getmonsterinfo( [email protected]_array[[email protected]],MOB_NAME );
break;
}
deletearray [email protected]_array;
}
}
}
}
end;
 
OnRemoveMission:
[email protected]_id = getarg(0);
[email protected]$ = getarg(1);
 
query_sql( "SELECT `aid`,`cid` FROM `player_mission` WHERE `cid` IN ( SELECT `char_id` FROM `char` WHERE `online` = 1 ) AND `mission_id` = "[email protected]_id+" AND `completion` = '0000-00-00 00:00:00' LIMIT 128",[email protected],[email protected] );
[email protected]_size = getarraysize( [email protected] );
[email protected] = 0;
[email protected]_aid = getcharid(3);
while( [email protected] < [email protected]_size ){
if( isloggedin( [email protected][[email protected]],[email protected][[email protected]] ) ){
attachrid( [email protected][[email protected]] );
for( [email protected] = @ms_size; [email protected] >= 0; [email protected] )
if( @ms_list$[[email protected]] == ""[email protected]_id ){
message strcharinfo(0),[email protected]$;
dispbottom "Please visit Mission NPC to gain latest information.";
setd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ),0;
deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_list" );
deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_qty" );
deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt" );
deletearray @ms_list$[[email protected]],1;
@ms_size--;
break;
}
detachrid;
[email protected]++;
}
[email protected]++;
}
attachrid( [email protected]_aid );
dispbottom "Total "[email protected]+" online players affected.";
return;
 
// usage :
// [email protected] = callsub( OnTime2Str,<time> );
OnTime2Str:
[email protected] = getarg(0);
[email protected] = ( [email protected] - gettimetick(2) );
[email protected] = ( [email protected] / 3600 );
[email protected] = ( [email protected] % 3600 / 60 );
[email protected] = ( [email protected] % 60 );
if( [email protected] ) 
return "none";
else
return "^777777"+( ( [email protected] )? [email protected]+" hr ":"" ) + ( ( [email protected] || [email protected] )? [email protected]+" min ":"" ) [email protected]+" sec^000000";
  
  
// usage : 
// [email protected]_array_size = callsub( OnExplodeArray,<old string variable>,<new array variable>,<save '0'> );
OnExplodeArray:
[email protected] = getarg(2);
explode( getarg(0),getarg(0),"|" );
[email protected] = getarraysize( getarg(0) );
while( [email protected] < [email protected] ){
if( [email protected] ){
[email protected] = atoi( getelementofarray( getarg(0),[email protected] ) );
if( [email protected] ){
set getelementofarray( getarg(1),[email protected]_size ),[email protected];
[email protected]_size++;
}
}else{
set getelementofarray( getarg(1),[email protected]_size ),getelementofarray( getarg(0),[email protected] );
[email protected]_size++;
}
[email protected]++;
}
 
return [email protected]_size;
 
 
// display mission information + optional progress checking
OnDisplayMissionInfo:
[email protected]_id = getarg(0);
[email protected]$ = getarg(1);
[email protected]$ = getarg(2);
[email protected] = getarg(4);
[email protected] = getarg(5);
[email protected]_size = getarraysize( getarg(6) );
[email protected]_size = getarraysize( getarg(8) );
[email protected]_job_bitmask = getarg(10);
[email protected]_branch_bitmask = getarg(11);
[email protected] = getarg(12);
[email protected] = getarg(13);
[email protected] = getarg(14);
[email protected] = getarg(15);
[email protected]_size = getarraysize( getarg(16) );
[email protected]_npc_size = getarraysize( getarg(18) );
[email protected]_update$ = getarg(19);
[email protected]_delay = getarg(20);
[email protected]_progress = getarg(21);
 
if( [email protected]_progress & 8 )
[email protected] = eaclass();
 
// display mission info
mes ""+(( [email protected]_id )? "^FF0000Mission ID # "[email protected]_id:" " )+"^000000";
mes "Title: "+( ( [email protected]$ != "" )?"^777777"[email protected]$:"^FF0000-incomplete-" )+"^000000";
mes "Description: "+( ( [email protected]$ != "" )?"^777777"[email protected]$:"^FF0000-incomplete-" )+"^000000";
mes "Level Range: "+( ( getelementofarray( getarg(3),0 ) )? "^777777"+getelementofarray( getarg(3),0 )+" ~ "+getelementofarray( getarg(3),1 ):"^FF0000-incomplete-" )+"^000000";
if( [email protected]_progress & 1 )
if( BaseLevel >= getelementofarray( getarg(3),0 ) && BaseLevel <= getelementofarray( getarg(3),1 ) )
[email protected]_progress = 1;
 
mes "Can do: ^777777"+( ( [email protected] )?"Repeatedly":[email protected]+" time(s)" )+"^000000";
mes "Re-do Delay: ^777777"+( ( [email protected]_delay )?"Unavailable":callsub( OnTime2Str,( ( [email protected]_delay * 3600 ) + gettimetick(2) ) ) )+"^000000";
 
[email protected]$ = (( [email protected]ster_size && [email protected]_size )?"^FF0000Incomplete":"^777777Unavailable" );
mes "Monsters to kill: "+( ( [email protected]_size )?"":[email protected]$ )+"^000000";
if( [email protected]_size )
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_id = getelementofarray( getarg(6),[email protected] );
[email protected] = getelementofarray( getarg(7),[email protected] );
if( [email protected]_progress & 2 ){
[email protected]_count = getd( "@ms_"[email protected]_id+"_hunt["[email protected]+"]" );
if( [email protected]_count >= [email protected] ){
[email protected]_progress++;
[email protected]_color$ = "44EE99";
}else{
[email protected]_color$ = "FF0000";
}
}
mes " ^777777"[email protected]+" x "+getmonsterinfo( [email protected]_id,MOB_NAME )+"  "+( ( [email protected]_progress & 2 )?"^"[email protected]_color$+"(killed "[email protected]_count+")":"" )+"^000000";
}
mes "Items to collect: "+( ( [email protected]_size )?"":[email protected]$ )+"^000000";
if( [email protected]_size )
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_id = getelementofarray( getarg(8),[email protected] );
[email protected] = getelementofarray( getarg(9),[email protected] );
[email protected]_type = getiteminfo( [email protected]_id,2 );
if( [email protected]_progress & 4 ){
[email protected]_count = countitem( [email protected]_id );
if( [email protected]_count >= [email protected] ){
[email protected]_progress++;
[email protected]_color$ = "44EE99";
}else{
[email protected]_color$ = "FF0000";
}
}
mes " ^777777"[email protected]+" x "+getitemname( [email protected]_id )+" "+( ( [email protected]_type == 4 || [email protected]_type == 5 )?"["+getitemslots( [email protected]_id )+"]":"" )+"  "+( ( [email protected]_progress & 4 )?"^"[email protected]_color$+"(have "[email protected]_count+")":"" )+"^000000";
}
mes " ";
mes "EXP Rewards: ";
mes "^777777 ~ Base EXP: "+( ( [email protected] )? [email protected]:"None" )+"^000000";
mes "^777777 ~ Job EXP: "+( ( [email protected] )? [email protected]:"None" )+"^000000";
mes " ";
mes "Item / Zeny Rewards: "+( ( [email protected]_size )?"":"^777777Unavailable" )+"^000000";
mes "^777777  ~ "+( ( [email protected] )? [email protected]+" Zeny":"  ~ No Zeny Reward" )+"^000000";
if( [email protected]_size )
for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
[email protected]_id = getelementofarray( getarg(16),[email protected] );
[email protected]_type = getiteminfo( [email protected]_id,2 );
mes " ^777777 ~ "+getelementofarray( getarg(17),[email protected] )+" x "+getitemname( [email protected]_id )+" "+( ( [email protected]_type == 4 || [email protected]_type == 5 )?"["+getitemslots( [email protected]_id )+"]":"" )+"^000000";
}
mes " ";
 
if( [email protected]_update$ != "0000-00-00 00:00:00" && [email protected]_update$ != "" ){
mes "Last Mission Update:";
mes "^777777"[email protected]_update$+"^000000";
}
 
if( [email protected]_progress ){
if( [email protected]_progress & 1 && [email protected]_progress ){
dispbottom "[Failed] Your level didnt meet the requirements.";
[email protected]_result |= 1;
}
if( [email protected]_progress & 2 && [email protected]_size != [email protected]_progress ){
dispbottom "[Failed] Your Monsters Hunt didnt meet the requirements.";
[email protected]_result |= 2;
}
if( [email protected]_progress & 4 && [email protected]_size != [email protected]_progress ){
dispbottom "[Failed] Your Items collecting didnt meet the requirements.";
[email protected]_result |= 4;
}
}
return [email protected]_result; 
}
 
 
// the number behind the NPC name must be NUMBER with range of ( 1 ~ 500 )
// the number should stay the same for eternity, if you change it frequently, it might affect your missions for each NPC.
// ( to conclude, once you assigned the number, dont change it for the sake of your mission board ... )
 
harmonia,173,90,1 duplicate(mission_board) Mission Board#1 837
//prontera,105,238,4 duplicate(mission_board) Mission B#2 837
//prontera,105,236,4 duplicate(mission_board) Mission C#3 837
//prontera,105,234,4 duplicate(mission_board) Mission D#4 837
 
//prontera,108,238,4 duplicate(mission_board) Mission E#5 837
//prontera,108,236,4 duplicate(mission_board) Mission F#6 837
//prontera,108,234,4 duplicate(mission_board) Mission G#7 837
//prontera,108,232,4 duplicate(mission_board) Mission H#8
Edited by Helena
Link to comment
Share on other sites

 

Hey Emistry, thank you for the awesome script!

 

I have one problem. The re-do delay and repeatable doesn't work for me for some reason. If I put 24 hours, it still let's me pick the mission over and over after completion, same with the repeatable status, it's always infinite.

 

I have to admit i did make some changes, but I believe nothing to have that result.

 

Another request if it isn't too much to ask, how do i make it so that when i put repeatable 1, the player can only do it once? Basically a "Can Do: 1 Time(s).

I'm having the same problem too ♥

Link to comment
Share on other sites

http://rathena.org/board/pastebin/4ryaa5wz3bu1/

- fix mission completion will update every rows on that player's mission ID, it should only update on non-completed mission

- fix repeatable option doesn't work correctly

- fix redo-delay doesn't work at all

Link to comment
Share on other sites

I can't load it, this error message appears

9ObUW76.png

i haven't touched the script at all

/*
DROP TABLE IF EXISTS `mission_board`;
 
CREATE TABLE IF NOT EXISTS `mission_board` (
	`id` int(11) unsigned NOT NULL,
	`title` varchar(30) NOT NULL default '',
	`desc` varchar(255) NOT NULL default '',
	`mob_list` varchar(50) NOT NULL default '',
	`mob_qty` varchar(50) NOT NULL default '',
	`item_list` varchar(50) NOT NULL default '',
	`item_qty` varchar(50) NOT NULL default '',
	`class_limitation` int(11) unsigned NOT NULL default '0',
	`class_branch` int(11) unsigned NOT NULL default '0',
	`min_lv` smallint(6) unsigned NOT NULL default '1',
	`max_lv` smallint(6) unsigned NOT NULL default '99',
	`repeat` smallint(6) unsigned NOT NULL default '0',
	`duration` int(11) unsigned NOT NULL default '0',
	`reward_list` varchar(50) NOT NULL default '',
	`reward_qty` varchar(50) NOT NULL default '',
	`base_exp` int(11) unsigned NOT NULL default '0',
	`job_exp` int(11) unsigned NOT NULL default '0',
	`zeny` int(11) unsigned NOT NULL default '0',
	`cash` int(11) unsigned NOT NULL default '0',
	`aid` int(11) unsigned NOT NULL default '0',
	`name` varchar(30) NOT NULL default '',
	`time_update` datetime NOT NULL default '0000-00-00 00:00:00',
	`npc_id` varchar(255) NOT NULL default '',
	`redo_delay` smallint(6) unsigned NOT NULL default '0',
	PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
DROP TABLE IF EXISTS `player_mission`;
CREATE TABLE IF NOT EXISTS `player_mission` (
	`id` int(11) unsigned NOT NULL,
	`mission_id` int(11) unsigned NOT NULL,
	`aid` int(11) unsigned NOT NULL default '0',
	`cid` int(11) unsigned NOT NULL default '0',
	`name` varchar(30) NOT NULL default '',
	`mob_hunt` varchar(50) NOT NULL default '',
	`expire` int(11) unsigned NOT NULL default '0',
	`starting` datetime NOT NULL default '0000-00-00 00:00:00',
	`completion` datetime NOT NULL default '0000-00-00 00:00:00',
	PRIMARY KEY  (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
 
*/
-	script	mission_board	-1,{
[email protected]_level = getgmlevel();
[email protected]_name$ = strnpcinfo(1);
[email protected]_npc_num = atoi( strnpcinfo(2) );
 
// check npc if it's a valid npc with number 1 ~ 500
if( [email protected]_npc_num || [email protected]_npc_num > 500 ){
	message strcharinfo(0),"This NPC isnt working, invalid <'"+strnpcinfo(2)+"'>";
	disablenpc strnpcinfo(0);
	end;
}
 
// to assign offset index.
[email protected]_npc_num--;
query_sql( "SELECT COUNT(`id`) FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' ",[email protected]_count );
query_sql( "SELECT `id`,`mission_id`,`mob_hunt`,`expire` FROM `player_mission` WHERE `mission_id` IN ( SELECT `id` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' ) AND `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' ",[email protected],[email protected]_id,[email protected]_hunt$,[email protected] );
[email protected]_mission_size = getarraysize( [email protected] );
 
mes "^0055FF[ "[email protected]_name$+" ]^000000";
mes "A mission board may provide various missions for adventures. Each players may pick ";
mes "   ^FF0000"+.max_mission_per_char+" missions^000000";
mes "from each mission npc.";
next;
switch( select( ( [email protected]_mission_size )?"Submit Mission":"",
				( [email protected]_mission_size < .max_mission_per_char )?"Pick Mission":"",
				( [email protected]_mission_size )?"Drop Mission":"",
				( [email protected]_level < .gm_level || [email protected]_count )?"":"^FF0000[GM] Update Mission^000000",
				( [email protected]_level < .gm_level )?"":"^FF0000[GM] Setup Mission^000000",
				( [email protected]_level < .gm_level || [email protected]_count  )?"":"^FF0000[GM] Delete Mission^000000" ) ){
	case 1:
		[email protected]_time = gettimetick(2);
		query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' AND `id` IN ( SELECT `mission_id` FROM `player_mission` WHERE `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' )",[email protected]_id,[email protected]$,[email protected]_lv,[email protected]_lv );
		[email protected] = getarraysize( [email protected]_id );
		for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ ){
			if( [email protected][[email protected]] && [email protected][[email protected]] < [email protected]_time )
				[email protected]_menu$ = [email protected]_menu$ + "^FF0000[Expired]^000000";
			[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
		}
		[email protected] = select( [email protected]_menu$ ) - 1;
 
		if( [email protected][[email protected]] && [email protected][[email protected]] < [email protected]_time ){
			dispbottom " ~ Mission expired "+callsub( OnTime2Str,( gettimetick(2) + ( [email protected]_time - [email protected][[email protected]] ) ) )+" ago.";
			dispbottom " ~ You may drop this mission.";
			close;
		}
 
		// get mission data from sql
		query_sql( "SELECT * FROM `mission_board` WHERE `id` = "[email protected]_id[[email protected]]+" LIMIT 1",
			[email protected]_id,
			[email protected]$,
			[email protected]$,
			[email protected]_list$,
			[email protected]_qty$,
			[email protected]_list$,
			[email protected]_qty$,
			[email protected]_job_bitmask,
			[email protected]_branch_bitmask,
			[email protected]_lv,
			[email protected]_lv,
			[email protected],
			[email protected],
			[email protected]_list$,
			[email protected]_qty$,
			[email protected],
			[email protected],
			[email protected],
			[email protected],
			[email protected],
			[email protected]$,
			[email protected]_update$,
			[email protected]_id$,
			[email protected]_delay
		);
 
		// explode all saved strings to array value.
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		if( [email protected]_size )
			callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		if( [email protected]_size )
			callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		if( [email protected]_size )
			callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_npc_size = callsub( OnExplodeArray,[email protected]_id$,[email protected]_npc_array$,1 );
 
		setarray [email protected]_range,[email protected]_lv,[email protected]_lv;
 
		// display the information of mission
		[email protected] = callsub( OnDisplayMissionInfo,
					[email protected]_id,
					[email protected]$,
					[email protected]$,
					[email protected]_range,
					[email protected],
					[email protected][[email protected]],
					[email protected]_list,
					[email protected]_qty,
					[email protected]_list,
					[email protected]_qty,
					[email protected]_job_bitmask,
					[email protected]_branch_bitmask,
					[email protected],
					[email protected],
					[email protected],
					[email protected],
					[email protected]_list,
					[email protected]_qty,
					[email protected]_npc_array$,
					[email protected]_update$,
					[email protected]_delay,
					1|2|4|8
				);
 
		// submit mission or not
		if( [email protected] ){
			message strcharinfo(0),"Failed to submit this mission.";
		}else{
			next;
			if( select( "Submit Completed Mission","Cancel" ) == 1 ){
				for( [email protected] = ( @ms_size - 1 ); [email protected] >= 0; [email protected] )
					if( @ms_list$[[email protected]] == ""[email protected]_id ){
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						query_sql( "UPDATE `player_mission` SET `completion` = NOW() WHERE `cid` = "+getcharid(0)+" AND `mission_id` = "[email protected]_id +" AND `completion` = '0000-00-00 00:00:00'" );
						mes "Mission accomplished.";
						@ms_size--;
 
						// clear requirement.
						setd( "@ms_"[email protected]_id+"_expire" ),0;
						deletearray getd( "@ms_"[email protected]_id+"_list" );
						deletearray getd( "@ms_"[email protected]_id+"_qty" );
						deletearray getd( "@ms_"[email protected]_id+"_hunt" );
						if( [email protected]_size )
							for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
								// debugmes getitemname( [email protected]_list[[email protected]] )+" - "[email protected]_qty[[email protected]];
								delitem [email protected]_list[[email protected]],[email protected]_qty[[email protected]];
							}
 
						mes "Gained some mission's rewards.";
						// rewards
						getexp [email protected],[email protected];
						if( [email protected]_size )
							for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
								getitem [email protected]_list[[email protected]],[email protected]_qty[[email protected]];
						#CASHPOINTS += [email protected];
						Zeny += [email protected];
						break;
					}
				mes "Something went wrong ..";
			}
		}
		break;
	case 2:
		// get info from SQL.
		do{
			mes "^0055FF[ "[email protected]_name$+" ]^000000";
			deletearray [email protected];
			query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' AND `id` NOT IN ( SELECT `mission_id` FROM `player_mission` WHERE `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' ) LIMIT "+.max_page_size+" OFFSET "[email protected],[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
			[email protected] += .max_page_size;
			[email protected] = getarraysize( [email protected] );
			if( [email protected] ){
				mes "There are no other available missions to pick.";
				close;
 
			}else{
				mes "Pick a mission.";
				[email protected]_menu$ = "";
				for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ )
					[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
			}
			next;
			[email protected] = select( [email protected]_menu$+ ( ( [email protected] < .max_page_size )?"":"- next page" ) ) - 1;
		}while( [email protected] == [email protected] );
 
		query_sql( "SELECT * FROM `mission_board` WHERE `id` = "[email protected][[email protected]]+" LIMIT 1",
			[email protected]_id,
			[email protected]$,
			[email protected]$,
			[email protected]_list$,
			[email protected]_qty$,
			[email protected]_list$,
			[email protected]_qty$,
			[email protected]_job_bitmask,
			[email protected]_branch_bitmask,
			[email protected]_lv,
			[email protected]_lv,
			[email protected],
			[email protected],
			[email protected]_list$,
			[email protected]_qty$,
			[email protected],
			[email protected],
			[email protected],
			[email protected],
			[email protected],
			[email protected]$,
			[email protected]_update$,
			[email protected]_id$,
			[email protected]_delay
		);
 
		// explode all saved strings to array value.
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_npc_size = callsub( OnExplodeArray,[email protected]_id$,[email protected]_npc_array$,1 );
 
		setarray [email protected]_range,[email protected]_lv,[email protected]_lv;
 
		// display the information of mission
		[email protected] = callsub( OnDisplayMissionInfo,
				[email protected]_id,
				[email protected]$,
				[email protected]$,
				[email protected]_range,
				[email protected],
				( [email protected] + gettimetick(2) ),
				[email protected]_list,
				[email protected]_qty,
				[email protected]_list,
				[email protected]_qty,
				[email protected]_job_bitmask,
				[email protected]_branch_bitmask,
				[email protected],
				[email protected],
				[email protected],
				[email protected],
				[email protected]_list,
				[email protected]_qty,
				[email protected]_npc_array$,
				[email protected]_update$,
				[email protected]_delay,
				1|8
		);
 
		// check completed how many times.
		if ( [email protected] ) {
			query_sql "select count(id) from player_mission where mission_id = "+ [email protected][[email protected]] +" and completion != '0000-00-00 00:00:00' and cid = "+ getcharid(0), [email protected]_completed;
			if( [email protected]_completed >= [email protected] ) {
				next;
				mes "^0055FF[ "[email protected]_name$+" ]^000000";
				mes " ";
				mes "You cant pick this mission, you have mission completion reach the max repeatable attempt of "[email protected]_completed+" times.";
				close;
			}
		}
 
		if ( [email protected]_delay ) {
			query_sql "select timestampdiff( hour, completion, now() ), unix_timestamp( date_add( completion, interval "+ [email protected]_delay +" hour ) ) from player_mission where cid = "+ getcharid(0) +" and mission_id = "+ [email protected][[email protected]] +" order by completion desc limit 1", [email protected]_delay, [email protected]_time;
			if ( [email protected]_delay < [email protected]_delay ) {
				next;
				mes "^0055FF[ "[email protected]_name$+" ]^000000";
				mes " ";
				mes "You cant pick this mission, you have mission redo delay isnt finish yet.";
				mes "^FF0000"+ callfunc( "Time2Str", [email protected]_time ) +"^000000";
				close;
			}
		}
 
		if( [email protected] ){
			message strcharinfo(0),"Failed to pick this mission.";
		}else{
			if( select( "Pick Mission","Cancel" ) == 1 ){
				query_sql( "INSERT INTO `player_mission` VALUES ( "+gettimetick(2)+","[email protected]_id+","+getcharid(3)+","+getcharid(0)+",'"+escape_sql( strcharinfo(0) )+"','',"+( ( [email protected] )? ( [email protected] + gettimetick(2) ) : 0 )+",NOW(),'0000-00-00 00:00:00' );" );
				message strcharinfo(0),"Picked Mission # "[email protected]_id;
 
				@ms_list$[ @ms_size ] = ""[email protected]_id;
				@ms_size++;
 
				copyarray getd( "@ms_"[email protected]_id+"_list[0]" ),[email protected]_list[0],[email protected]_size;
				copyarray getd( "@ms_"[email protected]_id+"_qty[0]" ),[email protected]_qty[0],[email protected]_size;
				deletearray getd( "@ms_"[email protected]_id+"_hunt" );
				if ( [email protected] ) {
					setd( "@ms_"[email protected]_id+"_expire" ),( [email protected] + gettimetick(2) );
					addtimer ( [email protected] * 1000 ),.npc_name$+"::OnTimeCheck";
				}
			}
		}
		break;
	case 3:
		query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' AND `id` IN ( SELECT `mission_id` FROM `player_mission` WHERE `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' )",[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
		[email protected]_size = getarraysize( [email protected] );
		for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
			[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
		mes "^0055FF[ "[email protected]_name$+" ]^000000";
		mes "Pick a Mission to remove.";
		next;
		[email protected] = select( [email protected]_menu$ ) - 1;
		mes "^0055FF[ "[email protected]_name$+" ]^000000";
		mes "Confirm remove ^0055FFMission # "[email protected][[email protected]]+"^000000?";
		mes "Title : ^0055FF"[email protected]$[[email protected]]+"^000000";
		mes "^777777( this cant be un-done )^000000";
		if( select( "nope","Confirm" ) == 2 ){
			message strcharinfo(0),"Dropped Mission # "[email protected][[email protected]];
			query_sql( "DELETE FROM `player_mission` WHERE `mission_id` = "[email protected][[email protected]]+" AND `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00'" );
			setd( "@ms_"[email protected][[email protected]]+"_expire" ),0;
			deletearray getd( "@ms_"[email protected][[email protected]]+"_list" );
			deletearray getd( "@ms_"[email protected][[email protected]]+"_qty" );
			deletearray getd( "@ms_"[email protected][[email protected]]+"_hunt" );
			for( [email protected] = 0; [email protected] < @ms_size; [email protected]++ )
				if( ""[email protected][[email protected]] == @ms_list$[[email protected]] ){
					deletearray @ms_list$[[email protected]],1;
					@ms_size--;
					break;
				}
		}
		break;
	case 4:
		// get info from SQL.
		do{
			mes "^0055FF[ "[email protected]_name$+" ]^000000";
			deletearray [email protected];
			query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' LIMIT "+.max_page_size+" OFFSET "[email protected],[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
			[email protected] += .max_page_size;
			[email protected] = getarraysize( [email protected] );
			if( [email protected] ){
				mes "There are no available mission to update.";
				close;
 
			}else{
				mes "Pick a mission.";
				[email protected]_menu$ = "";
				for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ )
					[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
			}
			next;
			[email protected] = select( [email protected]_menu$+ ( ( [email protected] < .max_page_size )?"":"- next page" ) ) - 1;
		}while( [email protected] == [email protected] );
		query_sql( "SELECT * FROM `mission_board` WHERE `id` = "[email protected][[email protected]],
			[email protected]_mission_id,
			[email protected]$,
			[email protected]$,
			[email protected]_list$,
			[email protected]_qty$,
			[email protected]_list$,
			[email protected]_qty$,
			[email protected]_job_bitmask,
			[email protected]_branch_bitmask,
			[email protected]_lv,
			[email protected]_lv,
			[email protected],
			[email protected],
			[email protected]_list$,
			[email protected]_qty$,
			[email protected],
			[email protected],
			[email protected],
			[email protected],
			[email protected],
			[email protected]$,
			[email protected]_update$,
			[email protected]_id$,
			[email protected]_delay
		);
		// explode all saved strings to array value.
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_size = callsub( OnExplodeArray,[email protected]_list$,[email protected]_list,0 );
		[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,[email protected]_qty,0 );
 
		[email protected]_npc_size = callsub( OnExplodeArray,[email protected]_id$,[email protected]_npc_array$,1 );
 
		setarray [email protected]_range,[email protected]_lv,[email protected]_lv;
 
	case 5:
		do{
			mes "^0055FF[ "[email protected]_name$+" ]^000000";
			// display the information of mission
			callsub( OnDisplayMissionInfo,
				[email protected]_mission_id,
				[email protected]$,
				[email protected]$,
				[email protected]_range,
				[email protected],
				( [email protected] + gettimetick(2) ),
				[email protected]_list,
				[email protected]_qty,
				[email protected]_list,
				[email protected]_qty,
				[email protected]_job_bitmask,
				[email protected]_branch_bitmask,
				[email protected],
				[email protected],
				[email protected],
				[email protected],
				[email protected]_list,
				[email protected]_qty,
				[email protected]_npc_array$,
				[email protected]_update$,
				[email protected]_delay,
				0
			);
 
			// check if required info complete for setup mission
			[email protected] = 0;
			if( [email protected]$ == "" ) [email protected] |= 1;
			if( [email protected]$ == "" ) [email protected] |= 2;
			if( [email protected]_size && [email protected]_size ) [email protected] |= 4;
			if( getarraysize( [email protected]_range ) != 2 || [email protected]_job_bitmask || [email protected]_branch_bitmask ) [email protected] |= 8;
			if( [email protected]_size && [email protected] && [email protected] && [email protected] && [email protected] ) [email protected] |= 16;
			if( [email protected]_npc_size ) [email protected] |= 32;
 
			[email protected]_option = select( "Edit Title "+(( [email protected] & 1 )?"^FF0000-incomplete-^000000":"" ),
							"Edit Description "+(( [email protected] & 2 )?"^FF0000-incomplete-^000000":"" ),
							"Edit Monster List "+(( [email protected] & 4 )?"^FF0000-incomplete-^000000":( ( [email protected]_size )?"^777777-none-^000000":"" )),
							"Edit Item List "+(( [email protected] & 4 )?"^FF0000-incomplete-^000000":( ( [email protected]_size )?"^777777-none-^000000":"" )),
							"Edit Class/Level Limitation "+(( [email protected] & 8 )?"^FF0000-incomplete-^000000":"" ),
							"Edit Time/Repeat/Mission Limitation ",
							"Edit Reward List "+(( [email protected] & 16 )?"^FF0000-incomplete-^000000":"" ),
							"Edit NPC Limitation "+(( [email protected] & 32 )?"^FF0000-incomplete-^000000":"" ),
							( [email protected] )?"":"^0055FF - Complete Setup Mission^000000" );
			next;				
			switch( [email protected]_option ){
				case 1:
					mes "^0055FF[ "[email protected]_name$+" ]^000000";
					mes "Enter Title";
					mes "^777777( Length: 4 ~ 30 )^000000";
					while( input( [email protected]$,4,30 ) );
					[email protected]_result = replacestr( [email protected]$,":"," " );
					break;
				case 2:
					[email protected]$ = "";
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes "Enter Description";
						mes "^777777( Length: 4 ~ 255 )^000000";
						mes " ";
						mes "^0055FF"[email protected]$+"^000000";
						[email protected] = getstrlen( [email protected]$ );
						do{
							[email protected]_result = input( [email protected]_input$,4,255 );
							if( [email protected]_result )
								message strcharinfo(0),"Input length must between 4 ~ 255";
						}while( [email protected]_result );
						[email protected]$ = [email protected]$ + " "+ [email protected]_input$;
						mes "^0055FF"[email protected]_input$+"^000000";
						[email protected] = getstrlen( [email protected]$ );
						next;
					}while( select( ( [email protected] >= 255 )?"":"add more ^777777( left "+( 255 - [email protected] )+" words )^000000","-back" ) == 1 );
					[email protected]$  = replacestr( [email protected]$,":"," " );
					break;
				case 3:
					if( [email protected]_mission_id ){
						dispbottom "Editing monster list might caused unwanted behaviours of scripts.  Which may included :";
						dispbottom " > Script/Missions isnt working properly.";
						dispbottom " > Deletion of player mission's progress.";
						dispbottom " > etc.";
						dispbottom "Overall it's not suggested to edit monster list that you have set early.";
						dispbottom "( Recommend for Re-Adding mission, if needed )";
					}
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes "Monster List:";
						if( [email protected]_size ){
							[email protected]_menu$ = "";
							[email protected]_mob_list$ = "|";
							deletearray [email protected]_mob$;
							for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
								[email protected]_name$ = getmonsterinfo( [email protected]_list[[email protected]],MOB_NAME );
								[email protected]_menu$ = [email protected]_menu$ + [email protected]_qty[[email protected]] +" x "[email protected]_name$ +":";
								mes " ^777777 ~ "[email protected]_qty[[email protected]]+" x "[email protected]_name$+"^000000";
								[email protected]_mob_list$ = [email protected]_mob_list$ + [email protected]_list[[email protected]] +"|";
							}
 
						}else{
							mes " ^777777 ~ none ^000000";
						}
						mes " ";
						[email protected] = select( ( [email protected]_size >= .max_required_monster )?"":"Add Monster",( [email protected]_size )?"Delete Monster":"","- Back" );
						switch( [email protected] ){
							case 1:
								mes "Enter Monster ID";
								do{
									input [email protected]_id;
									if( [email protected]_id ) break;
									[email protected]_name$ = getmonsterinfo( [email protected]_id,MOB_NAME );
								}while( [email protected]_name$ == "null" );
								if( [email protected]_name$ != "null" && [email protected]_id ){
									mes "How many "[email protected]_name$+" need to hunt ?";
									input [email protected],0,30000;
									if( [email protected] ){
										if( compare( "|"[email protected]_mob_list$+"|","|"[email protected]_id+"|" ) ){
											for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
												if( [email protected]_list[[email protected]] == [email protected]_id ){
													[email protected]_qty[[email protected]] += [email protected];
													break;
												}
 
										}else{
											[email protected]_list[[email protected]_size] = [email protected]_id;
											[email protected]_qty[[email protected]_size] = [email protected];
											[email protected]_size++;
										}
									}
								}
								break;
							case 2:
								mes "^0055FF[ "[email protected]_name$+" ]^000000";
								mes "Pick a Monster to Remove.";
								[email protected] = select( [email protected]_menu$+"- Back" ) - 1;
								if( [email protected] < [email protected]_size ){
									deletearray [email protected]_list[[email protected]],1;
									deletearray [email protected]_qty[[email protected]],1;
									[email protected]_size--;
								}
							default: break;
						}
						if( [email protected] < 3 ) next;
					}while( [email protected] < 3 );
					break;
				case 4:
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes "Required Item List: ";
						if( [email protected]_size ){
							[email protected]_menu$ = "";
							[email protected]_item_list$ = "|";
							deletearray [email protected]_item$;
							for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
								[email protected]_name$ = getitemname( [email protected]_list[[email protected]] );
								[email protected]_menu$ = [email protected]_menu$ + [email protected]_qty[[email protected]] +"x "[email protected]_name$ +":";
								mes " ^777777 ~ "[email protected]_qty[[email protected]]+" x "[email protected]_name$+"^000000";
								[email protected]_item_list$ = [email protected]_item_list$ + [email protected]_list[[email protected]] + "|";
							}
 
						}else{
							mes " ^777777 ~ none ^000000";
						}
						mes " ";
						[email protected] = select( ( [email protected]_size >= .max_required_item )?"":"Add Item",( [email protected]_size )?"Delete Item":"","- Back" );
						switch( [email protected] ){
							case 1:
								do{
									input [email protected]_id;
									if( [email protected]_id ) break;
									[email protected]_name$ = getitemname( [email protected]_id );
								}while( [email protected]_name$ == "null" || [email protected]_name$ == "" );
								if( [email protected]_id && [email protected]_name$ != "null" && [email protected]_name$ != "" ){
									mes "How many "[email protected]_name$+" need to collect ?";
									input [email protected],0,30000;
									if( [email protected] ){
										if( compare( "|"[email protected]_item_list$+"|","|"[email protected]_id+"|" ) ){
											for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
												if( [email protected]_list[[email protected]] == [email protected]_id ){
													[email protected]_qty[[email protected]] += [email protected];
													break;
												}
										}else{
											[email protected]_list[[email protected]_size] = [email protected]_id;
											[email protected]_qty[[email protected]_size] = [email protected];
											[email protected]_size++;
										}
									}
								}
								break;
							case 2:
								mes "^0055FF[ "[email protected]_name$+" ]^000000";
								mes "Pick an Item to Remove.";
								[email protected] = select( [email protected]_menu$+" - Back" ) - 1;
								if( [email protected] < [email protected]_size ){
									mes "Removed "[email protected]_qty[[email protected]]+" x "+getitemname( [email protected]_list[[email protected]] );
									deletearray [email protected]_list[[email protected]],1;
									deletearray [email protected]_qty[[email protected]],1;
									[email protected]_size--;
								}
							default: break;
						}
						if( [email protected] < 3 ) next;
					}while( [email protected] < 3 );
					break;
				case 5: // class limitation
					if( [email protected]_job_bitmask ){
						// enable all job by default.
						for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ ){
							[email protected]_value = ( 1 << [email protected] );
							[email protected]_job_bitmask |= [email protected]_value;
						}
						// enable all inherited classes by default.
						for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ ){
							[email protected]_value = ( 1 << [email protected] );
							[email protected]_branch_bitmask |= [email protected]_value;
						}
					}
 
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes "Level Range : "+( ( [email protected]_range[1] )? "^777777"[email protected]_range[0]+" ~ "[email protected]_range[1]:"^FF0000-incomplete-" )+"^000000";
						mes "Available Job Setting";
						if( [email protected]_job_bitmask ){
							for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ )
								if( [email protected]_job_bitmask & ( 1 << [email protected] ) )
									mes " ^777777 ~ "+jobname( roclass( .base_job[[email protected]] ) )+" ^000000";
						}else{
							mes " ^FF0000 -incomplete-^000000";
						}
						mes " ";
						mes "Inherited Branch Setting";
						if( [email protected]_branch_bitmask ){
							for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ )
								if( [email protected]_branch_bitmask & ( 1 << [email protected] ) )
									mes " ^777777 ~ "+.job_branch_name$[[email protected]]+" ^000000";	
						}else{
							mes " ^FF0000 -incomplete-^000000";
						}	
						next;
						[email protected] = select( "Edit Base Job","Edit Job Branch","Edit Level Range","- Back" );
						switch( [email protected] ){
							case 1:
								dispbottom "[ Base Job Class ] RED = Disable , GREEN = Enable";
								do{
									mes "^0055FF[ "[email protected]_name$+" ]^000000";
									mes "Available Job List:";
									[email protected]_job_menu$ = "";
									for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ ){
										[email protected]_name$ = jobname( roclass( .base_job[[email protected]] ) );
										if( [email protected]_job_bitmask & ( 1 << [email protected] ) )
											mes " ^777777 ~ "[email protected]_name$+" ^000000";						
										[email protected]_job_menu$ = [email protected]_job_menu$ + (( [email protected]_job_bitmask & ( 1 << [email protected] ) )?"^4EEE94":"^FF0000" ) + [email protected]_name$ +"^000000:";
									}
									next;
									[email protected] = select( [email protected]_job_menu$+"- Back" ) - 1;
									if( [email protected] < .base_job_size ){
										[email protected]_value = ( 1 << [email protected] );
										if( [email protected]_job_bitmask & [email protected]_value )
											[email protected]_job_bitmask -= [email protected]_value;
										else
											[email protected]_job_bitmask |= [email protected]_value;
									}
								}while( [email protected] < .base_job_size );
								break;
							case 2:
								dispbottom "[ Inherited Job Branch ] RED = Disable , GREEN = Enable";
								do{
									mes "^0055FF[ "[email protected]_name$+" ]^000000";
									mes "Inherited Job Branch List:";
									[email protected]_branch_menu$ = "";
									for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ ){
										if( [email protected]_branch_bitmask & ( 1 << [email protected] ) )
											mes " ^777777 ~ "+.job_branch_name$[[email protected]]+" ^000000";						
										[email protected]_branch_menu$ = [email protected]_branch_menu$ + (( [email protected]_branch_bitmask & ( 1 << [email protected] ) )?"^4EEE94":"^FF0000" ) + .job_branch_name$[[email protected]] +"^000000:";
									}
									next;
									[email protected] = select( [email protected]_branch_menu$+"- Back" ) - 1;
									if( [email protected] < .job_branch_size ){
										[email protected]_value = ( 1 << [email protected] );
										if( [email protected]_branch_bitmask & [email protected]_value )
											[email protected]_branch_bitmask -= [email protected]_value;
										else
											[email protected]_branch_bitmask |= [email protected]_value;
									}
								}while( [email protected] < .job_branch_size );
								break;
							case 3:
								mes "^0055FF[ "[email protected]_name$+" ]^000000";
								mes "Minimum Level";
								input [email protected]_range[0],1,.server_max_level ;
								mes "Maximum Level";
								input [email protected]_range[1],[email protected]_range[0],.server_max_level;
							default: break;
						}
						if( [email protected] < 4 ) next;
					}while( [email protected] < 4 );
					break;
				case 6: // mission limitation
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes "Repeatable: ^777777"+( ( [email protected] )?"unlimit":""[email protected] )+" time^000000";
						mes "Redo Delay: ^777777"+( ( [email protected]_delay )?"none":callsub( OnTime2Str,( ( [email protected]_delay * 3600 ) + gettimetick(2) ) ))+"^000000";
						mes "Time Limit: ^777777"+( ( [email protected] )?"none":callsub( OnTime2Str,( [email protected] + gettimetick(2) ) ) )+"^000000";
						[email protected] = select( "Edit Repeatable Status","Edit Time Limit","Edit Re-do Delay","Edit Required Mission","- Back" );
						switch( [email protected] ){
							case 1:
								mes "How many time can this mission repeat ??";
								mes "^777777( 0 = unlimited )^000000";
								input [email protected],0,100;
								break;
							case 2:
								mes "Time Limit of mission";
								mes "      1 = 1 minute";
								mes "    60 = 1 hour";
								mes "1440 = 1 day";
								input [email protected],0,50000;
								[email protected] *= 60;
								break;
							case 3:
								mes "Time Delay to re-take the mission";
								mes "     1 =  1 hour";
								mes "   24 =  1 day";
								mes " 720 = 30 day";
								input [email protected]_delay,0,50000;
								break;
							case 4:
								mes "This is not fully implemented yet.. still in beta test";
								break;
 
								do{
									mes "Required Mission:";
									if( [email protected]_mission_size ){
										for( [email protected] = 0; [email protected] < [email protected]_mission_size; [email protected]++ ){
											mes " ^777777 ~ "[email protected]_mission$[[email protected]]+"^000000";
											[email protected]_mission_menu$ = [email protected]_mission_menu$ + [email protected]_mission$[[email protected]] +":";
										}
 
									}else{
										mes "^777777 none ^000000";
									}
									next;
									[email protected]_option = select( ( [email protected]_mission_size < .max_required_mission )?"Add required mission":"",
														( [email protected]_mission_size )?"Remove required mission":"",
														"- Back");
									switch( [email protected]_option ){
										case 1:
											mes "Enter mission ID";
											mes "^777777( enter 0 to cancel )^000000";
											do{
												input [email protected]_id$;
												if( [email protected]_id$ == "0" ) break;
											}while( compare( "|"[email protected]_mission_menu$+"|","|"[email protected]_id$+"|" ) );
											[email protected]_id$ = replacestr( [email protected]_id$,":","" );
											if( [email protected]_id$ != "0" ){
												[email protected]_mission$[[email protected]_mission_size] = [email protected]_id$;
												[email protected]_mission_size++;
											}
											break;
										case 2:
											mes "Select a mission to remove.";
											[email protected] = select( [email protected]_mission_menu$ ) - 1;
											deletearray [email protected]_mission$[[email protected]],1;
										default: break;
									}
								}while( [email protected]_option < 3 );
							default: break;
						}
						if( [email protected] < 5 ) next;
					}while( [email protected] < 5 );
					break;
				case 7: // reward list
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes " ";
						mes "Cash : ^777777"+( ( [email protected] )? [email protected]:"none" )+"^000000";
						mes "Zeny : ^777777"+( ( [email protected] )? [email protected]:"none" )+"^000000";
						mes "Reward Item List: ";
						if( [email protected]_size ){
							[email protected]_menu$ = "";
							deletearray [email protected]_reward$;
							for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
								[email protected]_name$ = getitemname( [email protected]_list[[email protected]] );
								[email protected]_menu$ = [email protected]_menu$ + [email protected]_qty[[email protected]] +"x "[email protected]_name$ +":";
								[email protected]_reward$[[email protected]] = [email protected]_name$;
								mes " ^777777 ~ "[email protected]_qty[[email protected]]+" x "[email protected]_name$+"^000000";
							}
							[email protected]_reward_list$ = implode( [email protected]_reward$,"|" );
 
						}else{
							mes " ^777777 ~ none ^000000";
						}
						mes "Base EXP : ^777777"+( ( [email protected] )? [email protected]:"none" )+"^000000";
						mes "Job EXP : ^777777"+( ( [email protected] )? [email protected]:"none" )+"^000000";
						mes " ";
						next;
						[email protected] = select( ( [email protected]_size >= .max_required_item )?"":"Add Item Reward",
										( [email protected]_size )?"Delete Item Reward":"",
										"Edit Cash Reward",
										"Edit Zeny Reward",
										"Edit Base EXP Reward",
										"Edit Job EXP Reward",
										"- Back" );
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						switch( [email protected] ){
							case 1:
								mes "Enter Reward Item ID";
								do{
									input [email protected]_id;
									if( [email protected]_id ) break;
									[email protected]_name$ = getitemname( [email protected]_id );
								}while( [email protected]_name$ == "null" || [email protected]_name$ == "" );
								if( [email protected]_id && [email protected]_name$ != "null" && [email protected]_name$ != "" ){
									mes "How many "[email protected]_name$+" will be rewarded ?";
									input [email protected],0,30000;
									if( [email protected] ){
										if( compare( "|"[email protected]_reward_list$+"|","|"[email protected]_name$+"|" ) ){
											for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
												if( [email protected]_list[[email protected]] == [email protected]_id ){
													[email protected]_qty[[email protected]] += [email protected];
													break;
												}
										}else{
											[email protected]_list[[email protected]_size] = [email protected]_id;
											[email protected]_qty[[email protected]_size] = [email protected];
											[email protected]_size++;
										}
									}
								}
								break;
							case 2:
								mes "Pick an Reward to Remove.";
								[email protected] = select( [email protected]_menu$ ) - 1;
								mes "Removed "[email protected]_qty[[email protected]]+"x "+getitemname( [email protected]_list[[email protected]] );
								deletearray [email protected]_list[[email protected]],1;
								deletearray [email protected]_qty[[email protected]],1;
								[email protected]_size--;
								break;
							case 3:
								mes "How many Cash will be given ?";
								mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
								input [email protected],0,.max_integer_value;
								break;
							case 4:
								mes "How many Zeny will be given ?";
								mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
								input [email protected],0,.max_integer_value;
								break;
							case 5:
								mes "How many Base EXP reward ?";
								mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
								input [email protected],0,.max_integer_value;
								break;
							case 6:
								mes "How many Job EXP reward ?";
								mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
								input [email protected],0,.max_integer_value;
							default: break;
						}
						next;
					}while( [email protected] < 7 );
					break;
				case 8: // npc limitation
					mes "^0055FF[ "[email protected]_name$+" ]^000000";
					mes "By default, the mission will be available from each mission board npc ^FF0000unless you have specified which NPC may offer this mission.^000000";
					mes " ";
					mes "Just pick all the NPC that may offer this mission if you wish.";
					next;
					if( !getarraysize( [email protected]_npc_array$ ) )
						for( [email protected] = 0; [email protected] < .mission_npc_count; [email protected]++ ){
							[email protected]_npc_array$[[email protected]] = ""[email protected];
							[email protected]_npc_size++;
						}
					dispbottom "[ NPC Limitation ] RED = Disable , GREEN = Enable";
 
					do{
						mes "^0055FF[ "[email protected]_name$+" ]^000000";
						mes "Mission offered by: ";
						[email protected]_npc_menu$ = "";
						if( [email protected]_npc_size >= 2 ){
							[email protected]_npc$ = "|"+implode( [email protected]_npc_array$,"|" )+"|";
						}else{
							[email protected]_npc$ = "|"[email protected]_npc_array$+"|";
						}
						for( [email protected] = 0; [email protected] < .mission_npc_count; [email protected]++ ){
							getmapxy( [email protected]$,[email protected],[email protected],1,.npc_unique_list$[[email protected]] );
							[email protected]_npc_name$ = ( ( compare( "|"[email protected]_npc$+"|","|"[email protected]+"|" ) )?"^44EE00":"^FF0000" );
							[email protected]_npc_name$ = [email protected]_npc_name$ + .npc_name_list$[[email protected]];
							mes "^777777("[email protected]$+") "[email protected]_npc_name$;
							[email protected]_npc_menu$ = [email protected]_npc_menu$ + [email protected]_npc_name$ +":";
						}
						next;
						[email protected] = select( [email protected]_npc_menu$+"^000000- Back" ) - 1;
						if( [email protected] < .mission_npc_count ){
							if( compare( "|"[email protected]_npc$+"|","|"[email protected]+"|" ) )
								[email protected]_npc_array$[[email protected]] = "";
							else
								[email protected]_npc_array$[[email protected]] = ""[email protected];
							[email protected]_npc_size = getarraysize( [email protected]_npc_array$ );
						}
						// dispbottom "["+rand(10,99)+"] "+implode( [email protected]_npc_array$,"|" );
					}while( [email protected] < .mission_npc_count );
					break;
				default: break;
			}
			next;
		}while( [email protected]_option < 9 );
 
		// finalise all variable
		if( [email protected]_size ){
			[email protected]_mob_list$ = "|";
			[email protected]_mob_qty$ = "|";
			for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
				[email protected]_mob_list$ = [email protected]_mob_list$ + [email protected]_list[[email protected]] +"|";
				[email protected]_mob_qty$ = [email protected]_mob_qty$ + [email protected]_qty[[email protected]] +"|";
			}	
		}
 
		if( [email protected]_size ){
			[email protected]_item_list$ = "|";
			[email protected]_item_qty$ = "|";
			for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
				[email protected]_item_list$ = [email protected]_item_list$ + [email protected]_list[[email protected]] +"|";
				[email protected]_item_qty$ = [email protected]_item_qty$ + [email protected]_qty[[email protected]] +"|";
			}
		}
 
		if( [email protected]_size ){
			[email protected]_reward_list$ = "|";
			[email protected]_reward_qty$ = "|";
			for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
				[email protected]_reward_list$ = [email protected]_reward_list$ + [email protected]_list[[email protected]] +"|";
				[email protected]_reward_qty$ = [email protected]_reward_qty$ + [email protected]_qty[[email protected]] +"|";
			}
		}
 
		if( [email protected]_npc_size ){
			[email protected]_npc_list$ = "|";
			for( [email protected] = 0; [email protected] < [email protected]_npc_size; [email protected]++ )
				[email protected]_npc_list$ = [email protected]_npc_list$ + [email protected]_npc_array$[[email protected]] +"|";
		}
 
		if( [email protected]_mission_id ){
			[email protected]_mission_id = gettimetick(2);
			message strcharinfo(0),"Mission # "[email protected]_mission_id+" has been added.";
		}else{
			message strcharinfo(0),"Mission # "[email protected]_mission_id+" has been updated.";
			// attach and inform other online players.
			callsub( OnRemoveMission,[email protected]_mission_id,"A GM updated Mission # "[email protected]_mission_id );
		}
 
		// add new mission into SQL
		query_sql( 
			"REPLACE INTO `mission_board` VALUES ( " +
				[email protected]_mission_id+", " +
				"'"+escape_sql( [email protected]$ )+"', " +
				"'"+escape_sql( [email protected]$ )+"', " +
				"'"+escape_sql( [email protected]_mob_list$ )+"', " +
				"'"+escape_sql( [email protected]_mob_qty$ )+"', " +
				"'"+escape_sql( [email protected]_item_list$ )+"', " +
				"'"+escape_sql( [email protected]_item_qty$ )+"', " +
				[email protected]_job_bitmask+", " +
				[email protected]_branch_bitmask+", " +
				[email protected]_range[0]+", " +
				[email protected]_range[1]+", " +
				[email protected]+", " +
				[email protected]+", " +
				"'"+escape_sql( [email protected]_reward_list$ )+"', " +
				"'"+escape_sql( [email protected]_reward_qty$ )+"', " +
				[email protected]+", " +
				[email protected]+", " +
				[email protected]+", " +
				[email protected]+", " +
				getcharid(3)+", " +
				"'"+escape_sql( strcharinfo(0) )+"', " +
				"NOW(), " +
				"'"+escape_sql( [email protected]_npc_list$ )+"', " +
				[email protected]_delay +
			" ); " 
		);
		break;
	case 6: // delete mission
		do{
			mes "^0055FF[ "[email protected]_name$+" ]^000000";
			deletearray [email protected];
			query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"[email protected]_npc_num+"|%' LIMIT "+.max_page_size+" OFFSET "[email protected],[email protected],[email protected]$,[email protected]_lv,[email protected]_lv );
			[email protected] += .max_page_size;
			[email protected] = getarraysize( [email protected] );
			if( [email protected] ){
				mes "There are no available mission to update.";
				close;
 
			}else{
				mes "Pick a mission.";
				for( [email protected] = 0; [email protected] < [email protected]; [email protected]++ )
					[email protected]_menu$ = [email protected]_menu$ + "["[email protected]_lv[[email protected]]+"~"[email protected]_lv[[email protected]]+"] "[email protected]$[[email protected]] +":";
			}
			next;
			[email protected] = select( [email protected]_menu$+ ( ( [email protected] < .max_page_size )?"":"- next page" ) ) - 1;
		}while( [email protected] == [email protected] );
		[email protected]_id = [email protected][[email protected]];
		mes "^0055FF[ "[email protected]_name$+" ]^000000";
		mes "Are you sure to remove this mission ?";
		if( select( "nope","Delete Mission" ) == 2 ){
			query_sql( "DELETE FROM `mission_board` WHERE `id` = "[email protected]_id+" LIMIT 1" );
			mes "Removed mission from mission list.";
 
			// attach other online players and remove the missions.
			callsub( OnRemoveMission,[email protected]_id,"A GM removed Mission # "[email protected]_id );
			query_sql( "DELETE FROM `player_mission` WHERE `completion` = '0000-00-00 00:00:00' AND `mission_id` = "[email protected]_id );
			mes "Removed mission from all players.";
		}
	default: break;
}
close;
 
OnInit:
initnpctimer "mission_board";
// initialize settings
if( strnpcinfo(0) == "mission_board" ){
 
	// gm level to access panel
	.gm_level = 90;
	// max no. of required monster
	.max_required_monster = 10;
	// max no. of required item
	.max_required_item = 10;
	// max no. of required mission ( un-implement yet )
	.max_required_mission = 10;
	// max no. of available mission
	.max_mission_available = 50;
	// max value of integer input
	.max_integer_value = 2000000000;
	// max amount of mission per page
	.max_page_size = 30;
	// max mission per npc take by character
	.max_mission_per_char = 4;
 
	// predefined values.
	.npc_name$ = strnpcinfo(0);
	.server_max_level = getserverdef( VAR_MAX_LEVEL );
	setarray .base_job,
		EAJ_SWORDMAN,
		EAJ_MAGE,
		EAJ_ARCHER,
		EAJ_ACOLYTE,
		EAJ_MERCHANT,
		EAJ_THIEF,
		EAJ_TAEKWON,
		EAJ_GUNSLINGER,
		EAJ_NINJA;
	.base_job_size = getarraysize( .base_job );
	setarray .job_branch_name$,
		"2-1 Classes",
		"2-2 Classes",
		"Rebirth Classes",
		"Baby Classes",
		"Third Classes";
	setarray .job_branch,
		EAJL_2_1,
		EAJL_2_2,
		EAJL_UPPER,
		EAJL_BABY,
		EAJL_THIRD;
	.job_branch_size = getarraysize( .job_branch );
 
	bindatcmd "mission", strnpcinfo(0)+"::OnCommand";
 
}else{
	// delay the process
	[email protected] = atoi( strnpcinfo(2) );
	if( [email protected] && [email protected] <= 500 && .mission_npc_count < 100 ){
		sleep( [email protected] + 1 );
		.npc_name_list$[ .mission_npc_count ] = strnpcinfo(1);
		.npc_unique_list$[ .mission_npc_count ] = strnpcinfo(0);
		// debugmes "["+.mission_npc_count+"]"+.npc_name_list$[ .mission_npc_count ]+"|"+.npc_unique_list$[ .mission_npc_count ];
		.mission_npc_count++;
		end;
 
	}else if( [email protected] ){
		debugmes "[Removed] "+strnpcinfo(0)+", invalid <num:'"+strnpcinfo(2)+"'>";
	}else if( .mission_npc_count >= 100 ){
		debugmes "[Skipped] "+strnpcinfo(0)+", max: 100 Total NPC.";
	}
	disablenpc strnpcinfo(0);
}
end;
 
// just used to display how many total Mission Board NPC.
OnTimer1000:
	stopnpctimer;
	debugmes "[ Mission Board ] Total NPC Loaded : "+.mission_npc_count+" ...";
	end;
 
OnCommand:
	if ( !strcmp( strnpcinfo(0), .npc_name$ ) ) {
		if ( @ms_size ) {
			for ( [email protected] = 0; [email protected] < @ms_size; [email protected]++ ) {
				[email protected]_size = getarraysize( getd( "@ms_"+ @ms_list$[[email protected]] +"_list" ) );
				query_sql "select id, title, item_list, item_qty from mission_board where id = "+ @ms_list$[[email protected]], [email protected]_id, [email protected]$, [email protected]_id$, [email protected]_amount$;
				if ( [email protected]_size ) {
					if ( getd( "@ms_"+ [email protected]_id +"_expire" ) )
						dispbottom "[Mission '"+ [email protected]$ +"' Progress] Time limit -> "+ callfunc( "Time2Str", getd( "@ms_"+ [email protected]_id +"_expire" ) );
					for ( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
						dispbottom "[Mission '"+ [email protected]$ +"' Progress] Hunted "+ getd( "@ms_"+ @ms_list$[[email protected]] +"_hunt["+ [email protected] +"]" ) +"/"+ getd( "@ms_"+ @ms_list$[[email protected]] +"_qty[" + [email protected] +"]" ) +" x "+ getmonsterinfo( getd( "@ms_"+ @ms_list$[[email protected]] +"_list["+ [email protected] +"]" ), MOB_NAME );
					explode [email protected]_id_array$, [email protected]_id$, "|";
					explode [email protected]_amount_array$, [email protected]_amount$, "|";
					[email protected] = getarraysize( [email protected]_id_array$ );
					for ( [email protected] = 1; [email protected] < [email protected]; [email protected]++ )
						dispbottom "[Mission '"+ [email protected]$ +"' Progress] Collected "+ countitem( atoi( [email protected]_id_array$[[email protected]] ) ) +"/"+ [email protected]_amount_array$[[email protected]] +" x "+ getitemname( atoi( [email protected]_id_array$[[email protected]] ) );
				}
			}
		}
	}
	end;
 
OnPCLoginEvent:
if( strnpcinfo(0) == .npc_name$ ){
	[email protected] = gettimetick(2);
	[email protected] = query_sql( "SELECT `mission_id`,`expire`,`mob_hunt` FROM `player_mission` WHERE `completion` = '0000-00-00 00:00:00' AND `cid` = "+getcharid(0),@ms_list$,[email protected],[email protected]_hunt$ );
	@ms_size = [email protected];
	if( @ms_size )
		for( [email protected] = 0; [email protected] < @ms_size; [email protected]++ ) {
			if ( [email protected][[email protected]] ) {
				[email protected] = ( [email protected][[email protected]] - [email protected] );
				addtimer ( [email protected] * 1000 ),.npc_name$+"::OnTimeCheck";
				dispbottom "[ Mission Progress : "[email protected]_list$[[email protected]]+" , expire in "+ callfunc( "Time2Str", [email protected] + [email protected] )+" ]";
			}
			else
				dispbottom "[ Mission Progress : "[email protected]_list$[[email protected]] +" ]";
			query_sql( "SELECT `mob_list`,`mob_qty` FROM `mission_board` WHERE `id` = "[email protected]_list$[[email protected]],[email protected]_list$,[email protected]_qty$ );
			setd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ),[email protected][[email protected]];
			if( callsub( OnExplodeArray,[email protected]_list$,getd( "@ms_"[email protected]_list$[[email protected]]+"_list" ),0 ) ){
				callsub( OnExplodeArray,[email protected]_hunt$[[email protected]],getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt" ),0 );
				[email protected]_size = callsub( OnExplodeArray,[email protected]_qty$,getd( "@ms_"[email protected]_list$[[email protected]]+"_qty" ),0 );
//				for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
//					dispbottom  " ~ killed "+getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" )+"/"+getd( "@ms_"[email protected]_list$[[email protected]]+"_qty["[email protected]+"]" )+" x "+getmonsterinfo( getd( "@ms_"[email protected]_list$[[email protected]]+"_list["[email protected]+"]" ),MOB_NAME );
			}
		}
}
end;
 
OnPCLogoutEvent:
if( strnpcinfo(0) == .npc_name$ ){
	if( @ms_size )
		for( [email protected] = 0; [email protected] < @ms_size; [email protected]++ ){
			debugmes "Saving "[email protected]_list$[[email protected]];
			[email protected]_size = getarraysize( getd( "@ms_"[email protected]_list$[[email protected]]+"_list" ) );
			if( [email protected]_size ){
				copyarray [email protected]_array[0],getd( "@ms_"[email protected]_list$[[email protected]]+"_list[0]" ),[email protected]_size;
				[email protected]_hunt$ = "|";
				for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
					[email protected]_hunt$ = [email protected]_hunt$ + getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" ) +"|";
				query_sql( "UPDATE `player_mission` SET `mob_hunt` = '"+escape_sql( [email protected]_hunt$ )+"' WHERE `mission_id` = "[email protected]_list$[[email protected]]+" AND `completion` = '0000-00-00 00:00:00' AND `cid` = "+getcharid(0) );
			}
		}
}
end;
 
OnNPCKillEvent:
if( strnpcinfo(0) == .npc_name$ ){
	if( @ms_size ){
		[email protected]$ = strcharinfo(3);
 
		// by default mission wont work in PVP,GVG,Instance,Event maps
		if( compare( [email protected]$,"@" ) || getmapflag( [email protected]$,mf_gvg ) || getmapflag( [email protected]$,mf_pvp )){
			// dispbottom "[Mission Board] PvP/GvG Map , Instance Map , Event Map , include monsters will not affect Mission Progress.";
			end;
		}
 
		[email protected] = gettimetick(2);
		for( [email protected] = ( @ms_size - 1 ); [email protected] >= 0; [email protected] ){
			if( getd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ) && getd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ) < [email protected] ){
				setd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ),0;
				deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_list" );
				deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_qty" );
				deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt" );
				dispbottom "[Mission # "[email protected]_list$[[email protected]]+"] Mission removed due to expired. ";
				deletearray @ms_list$[[email protected]],1;
				@ms_size--;
 
			}else{
				[email protected]_size = getarraysize( getd( "@ms_"[email protected]_list$[[email protected]]+"_list" ) );
				if( [email protected]_size ){
					copyarray [email protected]_array[0],getd( "@ms_"[email protected]_list$[[email protected]]+"_list[0]" ),[email protected]_size;
					for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
						if( [email protected]_array[[email protected]] == killedrid ){
							[email protected] = getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" ) + 1;
							setd( "@ms_"[email protected]_list$[[email protected]]+"_hunt["[email protected]+"]" ),[email protected];
							// dispbottom "[Mission # "[email protected]_list$[[email protected]]+" Progress] Hunted "[email protected]+" x "+getmonsterinfo( [email protected]_array[[email protected]],MOB_NAME );
							break;
						}
					deletearray [email protected]_array;
				}
			}
		}
	}
}
end;
 
OnTimeCheck:
	if( @ms_size ){
		[email protected] = gettimetick(2);
		for( [email protected] = ( @ms_size - 1 ); [email protected] >= 0; [email protected] ){
			if( getd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ) <= [email protected] ){
				setd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ),0;
				deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_list" );
				deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_qty" );
				deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt" );
				dispbottom "[Mission # "[email protected]_list$[[email protected]]+"] Mission removed due to expired. ";
				deletearray @ms_list$[[email protected]],1;
				@ms_size--;
			}
		}
	}
	end;
 
OnRemoveMission:
	[email protected]_id = getarg(0);
	[email protected]$ = getarg(1);
 
	query_sql( "SELECT `aid`,`cid` FROM `player_mission` WHERE `cid` IN ( SELECT `char_id` FROM `char` WHERE `online` = 1 ) AND `mission_id` = "[email protected]_id+" AND `completion` = '0000-00-00 00:00:00' LIMIT 128",[email protected],[email protected] );
	[email protected]_size = getarraysize( [email protected] );
	[email protected] = 0;
	[email protected]_aid = getcharid(3);
	while( [email protected] < [email protected]_size ){
		if( isloggedin( [email protected][[email protected]],[email protected][[email protected]] ) ){
			attachrid( [email protected][[email protected]] );
			for( [email protected] = @ms_size; [email protected] >= 0; [email protected] )
				if( @ms_list$[[email protected]] == ""[email protected]_id ){
					message strcharinfo(0),[email protected]$;
					dispbottom "Please visit Mission NPC to gain latest information.";
					setd( "@ms_"[email protected]_list$[[email protected]]+"_expire" ),0;
					deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_list" );
					deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_qty" );
					deletearray getd( "@ms_"[email protected]_list$[[email protected]]+"_hunt" );
					deletearray @ms_list$[[email protected]],1;
					@ms_size--;
					break;
				}
			detachrid;
			[email protected]++;
		}
		[email protected]++;
	}
	attachrid( [email protected]_aid );
	dispbottom "Total "[email protected]+" online players affected.";
	return;
 
// usage :
// [email protected] = callsub( OnTime2Str,<time> );
OnTime2Str:
	[email protected] = getarg(0);
	[email protected] = ( [email protected] - gettimetick(2) );
	[email protected] = ( [email protected] / 3600 );
	[email protected] = ( [email protected] % 3600 / 60 );
	[email protected] = ( [email protected] % 60 );
	if( [email protected] ) 
		return "none";
	else
		return "^777777"+( ( [email protected] )? [email protected]+" hr ":"" ) + ( ( [email protected] || [email protected] )? [email protected]+" min ":"" ) [email protected]+" sec^000000";
 
 
// usage : 
// [email protected]_array_size = callsub( OnExplodeArray,<old string variable>,<new array variable>,<save '0'> );
OnExplodeArray:
	[email protected] = getarg(2);
	explode( getarg(0),getarg(0),"|" );
	[email protected] = getarraysize( getarg(0) );
	if ( [email protected] )
		return 0;
	while( [email protected] < [email protected] ){
		if( [email protected] ){
			[email protected] = atoi( getelementofarray( getarg(0),[email protected] ) );
			if( [email protected] ){
				set getelementofarray( getarg(1),[email protected]_size ),[email protected];
				[email protected]_size++;
			}
		}else{
			set getelementofarray( getarg(1),[email protected]_size ),getelementofarray( getarg(0),[email protected] );
			[email protected]_size++;
		}
		[email protected]++;
	}
 
	return [email protected]_size;
 
 
// display mission information + optional progress checking
OnDisplayMissionInfo:
		[email protected]_id = getarg(0);
		[email protected]$ = getarg(1);
		[email protected]$ = getarg(2);
		[email protected] = getarg(4);
		[email protected] = getarg(5);
		[email protected]_size = getarraysize( getarg(6) );
		[email protected]_size = getarraysize( getarg(8) );
		[email protected]_job_bitmask = getarg(10);
		[email protected]_branch_bitmask = getarg(11);
		[email protected] = getarg(12);
		[email protected] = getarg(13);
		[email protected] = getarg(14);
		[email protected] = getarg(15);
		[email protected]_size = getarraysize( getarg(16) );
		[email protected]_npc_size = getarraysize( getarg(18) );
		[email protected]_update$ = getarg(19);
		[email protected]_delay = getarg(20);
		[email protected]_progress = getarg(21);
 
		if( [email protected]_progress & 8 )
			[email protected] = eaclass();
 
		// display mission info
		mes ""+(( [email protected]_id )? "^FF0000Mission ID # "[email protected]_id:" " )+"^000000";
		mes "Title : "+( ( [email protected]$ != "" )?"^777777"[email protected]$:"^FF0000-incomplete-" )+"^000000";
		mes "Description : "+( ( [email protected]$ != "" )?"^777777"[email protected]$:"^FF0000-incomplete-" )+"^000000";
		mes "Level Range : "+( ( getelementofarray( getarg(3),0 ) )? "^777777"+getelementofarray( getarg(3),0 )+" ~ "+getelementofarray( getarg(3),1 ):"^FF0000-incomplete-" )+"^000000";
		if( [email protected]_progress & 1 )
			if( BaseLevel >= getelementofarray( getarg(3),0 ) && BaseLevel <= getelementofarray( getarg(3),1 ) )
				[email protected]_progress = 1;
 
		mes "Repeatable: ^777777"+( ( [email protected] )?"unlimit":[email protected]+" time" )+"^000000";
		mes "Redo Delay: ^777777"+( ( [email protected]_delay )?"none":callsub( OnTime2Str,( ( [email protected]_delay * 3600 ) + gettimetick(2) ) ) )+"^000000";
		mes "Expire in: ^777777"+( ( [email protected] )?"none":callsub( OnTime2Str,[email protected] ) )+"^000000";
		mes " ";
 
		[email protected]$ = (( [email protected]_size && [email protected]_size )?"^FF0000incomplete":"^777777none" );
		mes "Monster List : "+( ( [email protected]_size )?"":[email protected]$ )+"^000000";
		if( [email protected]_size )
			for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
				[email protected]_id = getelementofarray( getarg(6),[email protected] );
				[email protected] = getelementofarray( getarg(7),[email protected] );
				if( [email protected]_progress & 2 ){
					[email protected]_count = getd( "@ms_"[email protected]_id+"_hunt["[email protected]+"]" );
					if( [email protected]_count >= [email protected] ){
						[email protected]_progress++;
						[email protected]_color$ = "44EE99";
					}else{
						[email protected]_color$ = "FF0000";
					}
				}
				mes " ^777777"[email protected]+" x "+getmonsterinfo( [email protected]_id,MOB_NAME )+"  "+( ( [email protected]_progress & 2 )?"^"[email protected]_color$+"(killed "[email protected]_count+")":"" )+"^000000";
			}
		mes "Item List : "+( ( [email protected]_size )?"":[email protected]$ )+"^000000";
		if( [email protected]_size )
			for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
				[email protected]_id = getelementofarray( getarg(8),[email protected] );
				[email protected] = getelementofarray( getarg(9),[email protected] );
				[email protected]_type = getiteminfo( [email protected]_id,2 );
				if( [email protected]_progress & 4 ){
					[email protected]_count = countitem( [email protected]_id );
					if( [email protected]_count >= [email protected] ){
						[email protected]_progress++;
						[email protected]_color$ = "44EE99";
					}else{
						[email protected]_color$ = "FF0000";
					}
				}
				mes " ^777777"[email protected]+" x "+getitemname( [email protected]_id )+" "+( ( [email protected]_type == 4 || [email protected]_type == 5 )?"["+getitemslots( [email protected]_id )+"]":"" )+"  "+( ( [email protected]_progress & 4 )?"^"[email protected]_color$+"(have "[email protected]_count+")":"" )+"^000000";
			}
		mes " ";
		mes "Available Job Classes :";
		if( [email protected]_job_bitmask ){
			deletearray [email protected]_job$;
			deletearray [email protected]_branch$;
			[email protected]_job_size = 0;
			[email protected]_branch_size = 0;
			for( [email protected] = 0; [email protected] < .base_job_size; [email protected]++ )
				if( [email protected]_job_bitmask & ( 1 << [email protected] ) ){
					[email protected] = roclass( .base_job[[email protected]] );
					[email protected]_job$[[email protected]_job_size] = jobname( [email protected] );
					if( [email protected]_progress & 8 && BaseClass == [email protected] )
						[email protected]_progress = 1;
					[email protected]_job_size++;
				}
			mes " ^777777"+implode( [email protected]_job$,"," )+" ^000000";	
			if( [email protected]_branch_bitmask && [email protected]_progress ){
				for( [email protected] = 0; [email protected] < .job_branch_size; [email protected]++ )
					if( [email protected]_branch_bitmask & ( 1 << [email protected] ) ){
						if( [email protected]_progress & 8 && ( [email protected] & .job_branch[[email protected]] ) )
							[email protected]_progress++;
						[email protected]_branch$[[email protected]_branch_size] = .job_branch_name$[[email protected]];	
						[email protected]_branch_size++;
					}
				mes "Inherited: ^777777"+implode( [email protected]_branch$,", " )+" ^000000";			
			}
		}else{
			mes " ^FF0000-incomplete^000000";
		}
 
		mes " ";
		mes "Reward List : ";
		mes "^777777 ~ Base EXP: "+( ( [email protected] )? [email protected]:"none" )+"^000000";
		mes "^777777 ~ Job EXP: "+( ( [email protected] )? [email protected]:"none" )+"^000000";
		mes "^777777 ~ Cash: "+( ( [email protected] )? [email protected]:"none" )+"^000000";
		mes "^777777 ~ Zeny: "+( ( [email protected] )? [email protected]:"none" )+"^000000";
		mes "Reward Item List: "+( ( [email protected]_size )?"":"^777777none" )+"^000000";
		if( [email protected]_size )
			for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ ){
				[email protected]_id = getelementofarray( getarg(16),[email protected] );
				[email protected]_type = getiteminfo( [email protected]_id,2 );
				mes " ^777777 ~ "+getelementofarray( getarg(17),[email protected] )+" x "+getitemname( [email protected]_id )+" "+( ( [email protected]_type == 4 || [email protected]_type == 5 )?"["+getitemslots( [email protected]_id )+"]":"" )+"^000000";
			}
		mes " ";
 
		mes "Mission Offered by: "+( ( [email protected]_npc_size )?"":"^FF0000-incomplete" )+"^000000";
		if( [email protected]_npc_size ){
			if( [email protected]_npc_size >= 2 )
				[email protected]_npc$ = "|"+implode( getarg(18),"|" )+"|";
			else
				[email protected]_npc$ = "|"+getarg(18)+"|";
			for( [email protected] = 0; [email protected] < .mission_npc_count; [email protected]++ )
				if( ( compare( "|"[email protected]_npc$+"|","|"[email protected]+"|" ) ) ){
					getmapxy( [email protected]$,[email protected],[email protected],1,.npc_unique_list$[[email protected]] );
					[email protected]_npc_name$ = "^777777("[email protected]$+") ";
					[email protected]_npc_name$ = [email protected]_npc_name$ + .npc_name_list$[[email protected]] + "^000000";
					mes " ~ "[email protected]_npc_name$;
				}
			mes " ";
		}
		if( [email protected]_update$ != "0000-00-00 00:00:00" && [email protected]_update$ != "" ){
			mes "Last Mission Update:";
			mes "^777777"[email protected]_update$+"^000000";
		}
 
		if( [email protected]_progress ){
			if( [email protected]_progress & 1 && [email protected]_progress ){
				dispbottom "[Failed] Your level didnt meet the requirements.";
				[email protected]_result |= 1;
			}
			if( [email protected]_progress & 2 && [email protected]_size != [email protected]_progress ){
				dispbottom "[Failed] Your Monsters Hunt didnt meet the requirements.";
				[email protected]_result |= 2;
			}
			if( [email protected]_progress & 4 && [email protected]_size != [email protected]_progress ){
				dispbottom "[Failed] Your Items collecting didnt meet the requirements.";
				[email protected]_result |= 4;
			}
			if( [email protected]_progress & 8 && ( [email protected]_progress && [email protected]_progress ) ){
				dispbottom "[Failed] Your Class didnt meet the requirements.";
				[email protected]_result |= 8;
			}
		}
	return [email protected]_result;	
}
 
 
// the number behind the NPC name must be NUMBER with range of ( 1 ~ 500 )
// the number should stay the same for eternity, if you change it frequently, it might affect your missions for each NPC.
// ( to conclude, once you assigned the number, dont change it for the sake of your mission board ... )
 
turbo_room,105,139,5	duplicate(mission_board)	Weapon Master#1	628
//prontera,154,174,4	duplicate(mission_board)	Mission B#2	837
//prontera,156,176,4	duplicate(mission_board)	Mission C#3	837
//prontera,159,179,4	duplicate(mission_board)	Mission D#4	837
//prontera,151,161,4	duplicate(mission_board)	Mission E#5	837
//prontera,154,164,4	duplicate(mission_board)	Mission F#6	837
//prontera,156,166,4	duplicate(mission_board)	Mission G#7	837
//prontera,159,169,4	duplicate(mission_board)	Mission H#8	837

but this line

turbo_room,105,139,5	duplicate(mission_board)	Weapon Master#1	628
Link to comment
Share on other sites

SUGGESTIONS:

 

-if possible time attack quest (quest with time limit)

for example: quest "Byalan Blitz" kill plankton 10x, swordfish 10x, merman 20x, king dramoh x30 for 30mins!

 

-callfunction rewards (for example "function kagerou"  this function script will execute atcommand @changejob 4211)

with this concept we can assign a job quest, homevolution quest, quest to warp to exclusive maps , unique quest like "Joining a party" you know the script will check if you created a party or a guild and many amazing things!!!!!!!!!!!!!!!1

 

 

-craft quest (after acquiring all item quest crafting system follows, crafting has a success chance set by the gm)

 

-exp reward improvements: if possible GM can set an exp reward not only the value of exp they inputted but also GM must have an option of "EXP PERCENTAGE"

for example:  Bexp 10% Jexp 35%

 

-custom variable requirements (custom variable requirements that you can obtain from your other scripts or systems)

for example: quest "Biggest loser"  requirements for this quest is Death variable from your pvp scripts :3

 

 

 

ahahahhahah thats all for now, im going to edit this when i got new ideas :3

i love you script sir Emistry im looking forward to this script :3

Edited by joelolopez
Link to comment
Share on other sites

Well...Same Error

 

 

[Error]:  Loading NPC file: npc/custom/missionfilds.txt
script error on npc/custom/missionfilds.txt line 1019
    parse_line: expect command, missing function name or calling undeclared function
  1014 :        // max mission per npc take by character
  1015 :        .max_mission_per_char = 4;
  1016 :
  1017 :        // predefined values.
  1018 :        .npc_name$ = strnpcinfo(0);
* 1019 :        .server_max_level = getserverdef( 'V'AR_MAX_LEVEL );
  1020 :        setarray .base_job,
  1021 :                EAJ_SWORDMAN,
  1022 :                EAJ_MAGE,
  1023 :                EAJ_ARCHER,
  1024 :                EAJ_ACOLYTE,
 

 

I've updated my rAthena, and no work.

Link to comment
Share on other sites

Well...Same Error

 

 

[Error]:  Loading NPC file: npc/custom/missionfilds.txt

script error on npc/custom/missionfilds.txt line 1019

    parse_line: expect command, missing function name or calling undeclared function

  1014 :        // max mission per npc take by character

  1015 :        .max_mission_per_char = 4;

  1016 :

  1017 :        // predefined values.

  1018 :        .npc_name$ = strnpcinfo(0);

* 1019 :        .server_max_level = getserverdef( 'V'AR_MAX_LEVEL );

  1020 :        setarray .base_job,

  1021 :                EAJ_SWORDMAN,

  1022 :                EAJ_MAGE,

  1023 :                EAJ_ARCHER,

  1024 :                EAJ_ACOLYTE,

 

 

I've updated my rAthena, and no work.

 

i got that same error too so i'm not using it ):

Link to comment
Share on other sites

Ok,the main problem has been fixed  , but i have another problem on "NPC Limitation" When I try to select the letter A, the letter B is selects
I mean that if i active the letter "A" doesn't work, only the letter "B", and if I select the letter "C" doesnt works,  and works letter "D"

And so continuously with the other options. -_-

prontera,151,171,4 duplicate(mission_board) Mission A#1 837
prontera,154,174,4 duplicate(mission_board) Mission B#2 837
prontera,156,176,4 duplicate(mission_board) Mission C#3 837
prontera,159,179,4 duplicate(mission_board) Mission D#4 837

prontera,151,161,4 duplicate(mission_board) Mission E#5 837
prontera,154,164,4 duplicate(mission_board) Mission F#6 837
prontera,156,166,4 duplicate(mission_board) Mission G#7 837
prontera,159,169,4 duplicate(mission_board) Mission H#8 837

 

I've well the duplicates npcs

 

and the options when i try select is disordered without alphabetical order

 

sorry for my bad english.

 

 

post-2679-0-21925500-1397751741_thumb.jpg

Link to comment
Share on other sites

Ok,the main problem has been fixed  , but i have another problem on "NPC Limitation" When I try to select the letter A, the letter B is selects

I mean that if i active the letter "A" doesn't work, only the letter "B", and if I select the letter "C" doesnt works,  and works letter "D"

And so continuously with the other options. -_-

prontera,151,171,4 duplicate(mission_board) Mission A#1 837

prontera,154,174,4 duplicate(mission_board) Mission B#2 837

prontera,156,176,4 duplicate(mission_board) Mission C#3 837

prontera,159,179,4 duplicate(mission_board) Mission D#4 837

prontera,151,161,4 duplicate(mission_board) Mission E#5 837

prontera,154,164,4 duplicate(mission_board) Mission F#6 837

prontera,156,166,4 duplicate(mission_board) Mission G#7 837

prontera,159,169,4 duplicate(mission_board) Mission H#8 837

 

I've well the duplicates npcs

 

and the options when i try select is disordered without alphabetical order

 

sorry for my bad english.

cool o: may i know how you solve that if we are using same rev. o: ?

 

huh for the list errors, if i remember correctly, there was a config to make it random or in a order (?) 

Link to comment
Share on other sites

Hi, i updated my rAthena to latest and i still have the same error ):

kxvKAZg.png

 

the script

http://upaste.me/6e2912259a39ef09e

 

im using latest rathena ):

 

ps: i just modified the config part and nothing else, ah right i commented the last npcs because i just wanted to test first with only one

 

i also have the tables player_mission and mission_board on my sql ):

Link to comment
Share on other sites

    I have a few questions i havent been able to figure out on my own.

 

http://i61.tinypic.com/ok95ip.jpg

 

How do I make the OnNPCKillEvent: Show the mission name instead of the numbers and make it stop listing the kills after you reached the amount required and tell you the mission is complete to return to the mission board?

 

And how do i change the cash point reward to free points? 

						mes "Gained some mission's rewards.";
						// rewards
						getexp [email protected],[email protected];
						if( [email protected]_size )
							for( [email protected] = 0; [email protected] < [email protected]_size; [email protected]++ )
								getitem [email protected]_list[[email protected]],[email protected]_qty[[email protected]];
						#CASHPOINTS += [email protected];
						Zeny += [email protected];
						break;
					}
				mes "Something went wrong ..";
			}

I assumed it was the #cashpoints but changing it to #Points doesnt work and ive found nowhere else in the script that controlled they rewards.

Link to comment
Share on other sites

ehm how can I change the cash points to #mission_points ?

 

edit2:

and dispbottom for mob kill does not go

Edited by EL Dragon
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use and Privacy Policy.