Jump to content

Mistique

Members
  • Posts

    53
  • Joined

  • Last visited

Posts posted by Mistique

  1. On 2/2/2019 at 9:03 PM, Functor said:

    You can change it by using any HEX editor.

    offset 19400E change:

    6A 64 8D 45 D8 68 E4 58 CF 00 50 C7 45 EC 0F 00 00 00

    to:

    8D 45 D8 C7 00 2F 32 30 30 C7 40 04 00 00 00 00 EB 13

    My apologies for necro-bumping this but I am looking for the same. Functor, would you know the HEX code to change it for 2016-12-28aRagexeRE ?

    I cannot find that hex string. ?

  2. Hello! Maybe I am asking something very complex here, but I am looking for a simple custom skill that when using it, prompts a window like pharmacy/weapon refine and lets me create items from produce_db.txt Practically the same as a npc quest script but through skill. It would go like this:

    1) Click custom skill (10sp per use)
    2) Menu pops up with available items to generate (defined in produce_db)
    3) Select item in the menu
    4) Checks for materials  (defined in produce_db)
    5) If all there> create item.

    There don't need to be fancy calculations, success rate increases or points to store in a list like the pharmacy/weapon refine skills (/alchemist, /blacksmith).    Oh! And unlike pharmacy and weapon refine I prefer not to have the generated items named (i.e 'Mistique's Coat') so it will still allow me to slot them.

    Could anyone help me out please? ?

  3. Hi all.

    I am having a problem that I can't find the problem of- When I equip any (official or custom) robe costume in-game it works perfectly fine. No sprite or texture errors. Then, however, when I ESC and move back to character selection, it would crash the client. Logging in normally to an account with a garment costume would crash the client upon character selection too.

    What's odd is that when I log into another account (without character that has a robe costume equipped), open the 4, 5 and 6 character slot window, then disconnect from it and re-connect with the account that has the character with the costume garment and with it navigate back to the 1, 2 and 3 character slot window, the client doesn't crash. O.o

    What could be the cause of this?

  4. On 5/18/2019 at 5:16 AM, anacondaq said:

    Recompile.

    Hi anacondaq, sorry for the super delayed reply. Completely forgot this thread was here. I went through the steps you pointed out above once more but it still gives the same error message. battle_conf was not declared.

    I can't/prefer not to update my rA. Do you happen to have any suggestion how I could fix this error manually? Thanks. ? 

  5. 28 minutes ago, rongmauhong said:

    @Mistique Hi, try this code

    
    function	script	AddPointsFixed	{
    	.@map$ = instance_mapname(strcharinfo(3));
    	if (compare(.@map$, "@")) {
    		set .@accountID, getarg(0);
    		set .@amount, getarg(1);
    	 
    		getitem 677, 3;
    	  	message rid2name(.@accountID), "[ Instance ] : You've obtained 3 Coin(s) for completing instance!";
    	}
    	return;	
    }

    There are many ways to do this, but since each instance has different code, if you have a special instance, you have to do it separately.

    Hey, thanks! I've tried it, but unfortunately it doesn't work. ? Both characters still get warped to valkyrie (even the one outside the instance map), but neither of them get an item rewards.

    I should add the map does have a '@' in it like all instance maps, so that can't be the problem.

  6. Hey @Alayne awesome collection! Is there any chance you can help me out with this?

    Here the reward code as well as the finished instance code. The problem is, players that aren't in the instance map but are in the instance party can basically hoard rewards while not doing anything. What I want is that only the players/party members in the instance map can benefit from the reward. As of now they get points as well as warped while they may not even be present in the instance map. That shouldn't be right.

    Thanks in advance. ?

    OnFinished:
    
    	instance_announce instance_id(), "Congratulation! You have completed the challenge!",bc_map,"0x00ff99";
    				sleep2 2000;						
    				instance_announce instance_id(), "You'll soon be warped to Valhalla",bc_map,"0x00ff99";
    				sleep2 2000;
    				instance_destroy AA_INSTANCE_ID;
    				getpartymember getcharid(1),2;
    				copyarray .@partymemberaid, $@partymemberaid, $@partymembercount;
    				detachrid;
    				for ( set .@i, 0; .@i < $@partymembercount; set .@i, .@i +1 ) {
    					if (attachrid(.@partymemberaid[.@i]))
    					{
    						callfunc("AddPointsFixed", getcharid(3), 1 * $difficulty_level);
    						set AARENA, AARENA + 1;
    						warp "valkyrie",49,48;
    	
    					}
    				}
    				
    				getpartymember getcharid(1),2;
    				for( set .@i, 0; .@i < $@partymembercount; set .@i, .@i+1 )
    					if( attachrid( $@partymemberaid[.@i] ) && AA_INSTANCE_ID > 0){
    						set AA_INSTANCE_ID, -1;
    					}
    			}

     

    function	script	AddPointsFixed	{
    if(instance_mapname(strcharinfo(3)) != instance_mapname("1@va") ){end;}
    	set .@accountID, getarg(0);
    	set .@amount, getarg(1);
     
    	getitem 677, 3;
      	message rid2name(.@accountID), "[ Instance ] : You've obtained 3 Coin(s) for completing instance!";
    	return;
    }
  7. On 7/30/2019 at 8:35 AM, Tokei said:

    Heya,

    I presume you're talking about the "Preview" button from the item descriptions? If so, then it's not a file, this is decided server-side. How you receive the item makes the button appear or not. If you look in the clif_vendinglist function, you'll see some item packets sent to the client have 6 extra bytes. This part in particular:

    
    WFIFOL(fd,offset+47+i*item_length) = pc_equippoint_sub(sd,data);
    WFIFOW(fd,offset+51+i*item_length) = data->look;

    The data->look is the actual view ID that will be shown on the client for the item after clicking the button. The pc_equippoint_sub decides whether the client should display the button or not.

    The problem with that system is that many packets don't have that feature. If you try to preview the item from a shop NPC, it won't give you the option either. If you put the item in your cart, the button will disappear as well, etc. It's just very unreliable overall.

    kRO added more "locations" where this feature is available, though.

     

    Hi Tokei. Thanks for your reply! That's right, the preview/wear costume button.

    How the item is received? Hmm, ok. you're right, I noticed that the preview button doesn't appear in the cash shop interface nor when players are vending costumes. However, when I purchase the items through the CS or their vend stand and they appear in my inventory, it does show the button. Yet, not for all IDs, which I still find strange if they're obtained the same way?

    I could take ID 20286 and copy/paste it into 20285 both server and client side and generate both through the @item command- 20286 would have the button while 20285 would not, isn't that odd?

     

    On 7/30/2019 at 9:52 PM, Tokei said:

    Yes, when you "receive" the item in your inventory, the button will display properly because it uses the clif_additem packet. I meant how you receive the item information packet-wise, not the source of where it came from (though that's related of course).

    As for why 20285 shows up and 20286 doesn't, that is because 20285 has a hat effect and these are not displayed on the client with the feature. You can remove the item from the list by opening hateffectinfo.lub and then removing the ids from effectHatItemTable. It's probably best to keep the button disabled for that one though.

    Awesome, thanks for helping me locate the file! That's exactly what I needed to know. ? 

     

    I'm having a similar problem now... exactly the opposite. I've created a custom item (ID 20207) that is no costume (it's a regular garment), but the button is there. o_o

    Where do I look for to get rid of it? I've already checked the loc, the iteminfo, the effecthatitemtable and for possible duplicated entries in the item_dbs, but all this seems to be just fine. 

     

    *Edit* Nevermind. My custom item is a garment item, apparently all garments in the game have this button. That's kind of odd, because regular garments have no sprite to preview.... oh well.  I hope this thread will be useful for anyone else running into similar problems in the future. 

  8. Hi rA!

    I wonder, where exactly is defined which IDs have the 'wear costume' button and which don't?  Not that I want to get rid of it, I like the feature but I have quite a few costumes and there are a few among them that don't have the button, whereas some other non-headgear items do have this button. 

    Also yes, I did triple check the 'loc' in the item_db. All these items are confirmed to have the top costume loc (1024).

    Thanks. Help is appreciated. ? 

    *Edit* Okay so update. Changing the ID made the button appear. It's interesting because I'm running a Pre-RE server with my own created set of costumes so I'm not using the ones in the db/re/item_db, though they do use some of those IDs. One of the costumes that didn't show the button was the costume with ID 20285, which originally (in RE) has a special effect. But that shouldn't matter, should it? Since my server isn't reading the RE dirs. Trying to understand what's happening here because it doesn't make much sense. O_o

  9. On 5/15/2019 at 10:49 AM, anacondaq said:

    Try this https://gist.github.com/anacondaq/3479caee38df5738d81ea1ab5454c512

    Not tested, I just wrote the code while doing something else, it can not work at all, or can have dozens of bugs, or even critical problems or even crashes. Use it on your own risk.

     

    cashshop_ui_itemid_as_currency.diff 2.99 kB · 3 downloads

    Cool! Thanks I will give this a go later today. ?

    Hi @anacondaq I tried it, but it's returning this error message when compiling:

    error.png.abf656f1c4179185a38e21b8c081b564.png

    Not declared... but I put it in items.conf like it said in the diff.

  10. On 5/10/2019 at 9:23 AM, sader1992 said:

    https://github.com/rathena/rathena/blob/120ffc122bf8b0d36ba2a9b6f7ad62ac75e2513e/doc/script_commands.txt#L8930

    
    ---------------------------------------
    
    *instance_mapname("<map name>"{,<instance id>})
    
    Returns the unique name of the instanced map. If no instance ID is specified,
    the instance the script is attached to is used. If that fails, the command
    returns an empty string instead.
    
    ---------------------------------------

     

    Thanks Sader, I tried that! But I don't really want to define a fixed map name- instead have the reward function adapt whatever map is currently active as instance for the party. The function npc is working for different scripts/instances so I'm wondering if I can make it read multiple maps? i.e 1@tower, 2@new, 1@bnest, 1@nyd, etc?

    Sorry for necro bumping but still looking for a solution for this. ? 

    Still looking to get this fixed. Willing to pay if need be.

  11. Hi all!

    I'm using a custom instance of Alanye and I'm wondering if it's possible to set the reward function to not be given to characters outside of the instance maps? 

    Right now, party members not in the map get the same reward as party members in it.  As you can imagine this is quite troublesome because they can just hoard the coins with double clients.

    What should I be changing? Here are the reward scripts.

    Thank you! Help would be much appreciated! ❤️ 

    OnFinished:
    
    	instance_announce instance_id(), "Congratulation! You have completed the challenge!",bc_map,"0x00ff99";
    				sleep2 2000;						
    				instance_announce instance_id(), "You'll soon be warped to Valhalla",bc_map,"0x00ff99";
    				sleep2 2000;
    				instance_destroy AA_INSTANCE_ID;
    				getpartymember getcharid(1),2;
    				copyarray .@partymemberaid, $@partymemberaid, $@partymembercount;
    				detachrid;
    				for ( set .@i, 0; .@i < $@partymembercount; set .@i, .@i +1 ) {
    					if (attachrid(.@partymemberaid[.@i]))
    					{
    						callfunc("AddPointsFixed", getcharid(3), 1 * $difficulty_level);
    						set AARENA, AARENA + 1;
    						warp "valkyrie",49,48;
    	
    					}
    				}
    				
    				getpartymember getcharid(1),2;
    				for( set .@i, 0; .@i < $@partymembercount; set .@i, .@i+1 )
    					if( attachrid( $@partymemberaid[.@i] ) && AA_INSTANCE_ID > 0){
    						set AA_INSTANCE_ID, -1;
    					}
    			}

     

    function	script	AddPointsFixed	{
    if(instance_mapname(strcharinfo(3)) != instance_mapname("1@va") ){end;}
    	set .@accountID, getarg(0);
    	set .@amount, getarg(1);
     
    	getitem 677, 3;
      	message rid2name(.@accountID), "[ Instance ] : You've obtained 3 Coin(s) for completing instance!";
    	return;
    }

     

  12. Hi community.

    I've been going crazy over this script and decided to reach out for some assistance. The script I want is very basic (I think?)- an identifier and repair NPC combined. He would charge 3000z total for the choice they select in the menu (3000 total, not per unidentified/broken item).

    As you can see I've messed around with the script in hope to achieve desired result but alas. Help would be greatly appreciated. Thank you. ?

    [Header]
    	mes "[Equip Assistant]";
    	mes "Hello, do you need your help with your equipment?";
    	menu "Identify - 3,000 Zeny",-,"Repair - 3,000 Zeny",L_Repair;
    
    set .@Price, 3000;
    getinventorylist;
    for(set .@i,0; .@i<@inventorylist_count; set .@i,.@i+1) {
    	if (@inventorylist_identify[.@i]) continue;
    	if (Zeny < .@Price) {
    		dispbottom "It costs "+.@Price+" Zeny to identify an item."; break; }
    	set Zeny, Zeny-.@Price;
    	delitem2 @inventorylist_id[.@i],1,0,0,0,0,0,0,0;
    	getitem @inventorylist_id[.@i],1;
    	setarray .@Total[0], .@Total[0]+1, .@Total[1]+.@Price; }
    if (!.@Total[0]) {
    	message strcharinfo(0),"No items identified."; end; }
    specialeffect2 154;
    message strcharinfo(0),"Identified "+.@Total[0]+" items"+((.@Total[1])?" for "+.@Total[1]+" Zeny":"")+".";
    end;
    
    L_Repair:
    		if (Zeny < .@Price) {
    			dispbottom "It costs "+.@Price+" Zeny to repair your items.";
    			close;
    			}
    
    if (getbrokenid(1) == 0){
    	message strcharinfo(0),"No broken items detected.";
    	 end;
    	 }
    	
    while (getbrokenid(1)) {
    	repair(1);
    
    	}
    	if (.@i) message strcharinfo(0),"Repaired "+ .@i + " items for "+.@Price+" Zeny."; // How to make this part show?
    	set Zeny, Zeny-.@Price;
    	end;
    	}

     

  13. Thank you very much annie. Hmm, this can't be done with something like

    OnPCKillEvent:

    if (countitem(909) > 0 && countitem(909) < 11 ){

    dispbottom "You currently have [ "+ ( countitem(909) ) +" / 10 ] Jellopies.";

    end;

     

    I know that still goes by kill, but basically, in order to get a item you first need to kill something (if not bought from NPC or picked up from another player)...

     

    Or will that not do? Sorry, I'm kinda new at this. I'm trying to explore the possibilities hehe. xP

  14. Ah wow you're serious? I didnt know that function was in there already, thank you very much for pointing it out annie. :)

    Is there a similar function for gathering items?

     

    Also on a related note, I also saw this upon looking for the line you mentioned:

    // dispbottom  " ~ killed "+getd( "@ms_"+@ms_list$[.@i]+"_hunt["+.@mob+"]" )+"/"+getd( "@ms_"+@ms_list$[.@i]+"_qty["+.@mob+"]" )+" x "+getmonsterinfo( getd( "@ms_"+@ms_list$[.@i]+"_list["+.@mob+"]" ),MOB_NAME );
     
    What is that for? It looks similar but sorta more... complicated.
  15. Hello all. 

     

    I was wondering if someone was willing to give me a hand here. I'm using Emistry's mission board, now what I want to is (example, say) a mission is to kill 10 porings, that a character who accepted the mission gets a announcement that says something like "Mission Board: Killed [ 1 / 10 ] Porings.".

     

    I know it's done with bc_self and OnPCKillEvent, but I have troubles finding the right lables that determines the monsters ID and required amount to kill cause its such a massive script.

     

    This would also be amazing if it could work with the item collecting function, like "Mission Board: Gathered [ 1 / 10 ] Jelloppies.

     

    Hope this is not too much to ask, thank you for anyone willing to help :)

     

    Here is the script:

     

    - script mission_board -1,{
    .@gm_level = getgmlevel();
    .@npc_name$ = strnpcinfo(1);
    .@mission_npc_num = atoi( strnpcinfo(2) );
     
    // check npc if it's a valid npc with number 1 ~ 500
    if( !.@mission_npc_num || .@mission_npc_num > 500 ){
    message strcharinfo(0),"This NPC isnt working, invalid <'"+strnpcinfo(2)+"'>";
    disablenpc strnpcinfo(0);
    end;
    }
     
    // to assign offset index.
    .@mission_npc_num--;
    query_sql( "SELECT COUNT(`id`) FROM `mission_board` WHERE `npc_id` LIKE '%|"+.@mission_npc_num+"|%' ",.@mission_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 '%|"+.@mission_npc_num+"|%' ) AND `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' ",.@id,.@mission_id,.@mob_hunt$ );
    .@current_mission_size = getarraysize( .@id );
     
    mes "^0055FF[ "+.@npc_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[ "+.@npc_name$+" ]^000000";
    mes "Every player may pick up to ^FF0000"+.max_mission_per_char+" missions^000000 from the Mission Board.";
    next;
    switch( select( ( .@current_mission_size )?"Submit Mission":"",
    ( .@current_mission_size < .max_mission_per_char )?"Pick Mission":"",
    ( .@current_mission_size )?"Drop Mission":"",
    ( .@gm_level < .gm_level || !.@mission_count )?"":"^FF0000[GM] Update Mission^000000",
    ( .@gm_level < .gm_level )?"":"^FF0000[GM] Setup Mission^000000",
    ( .@gm_level < .gm_level || !.@mission_count  )?"":"^FF0000[GM] Delete Mission^000000" ) ){
    Case 1:
     
    // get mission data from sql
    query_sql( "SELECT * FROM `mission_board` WHERE `id` = "+.@mission_id[.@i]+" LIMIT 1",
    .@mission_id,
    .@title$,
    .@description$,
    .@mob_list$,
    .@mob_qty$,
    .@item_list$,
    .@item_qty$,
    .@base_job_bitmask,
    .@job_branch_bitmask,
    .@min_lv,
    .@max_lv,
    .@repeatable,
    .@timelimit,
    .@reward_list$,
    .@reward_qty$,
    .@baseexp,
    .@jobexp,
    .@zeny,
    .@cash,
    .@aid,
    .@name$,
    .@time_update$,
    .@npc_id$,
    .@redo_delay
    );
     
    // explode all saved strings to array value.
    .@monster_size = callsub( OnExplodeArray,.@mob_list$,.@monster_list,0 );
    if( .@monster_size )
    callsub( OnExplodeArray,.@mob_qty$,.@monster_qty,0 );
     
    .@item_size = callsub( OnExplodeArray,.@item_list$,.@item_list,0 );
    if( .@item_size )
    callsub( OnExplodeArray,.@item_qty$,.@item_qty,0 );
     
    .@reward_size = callsub( OnExplodeArray,.@reward_list$,.@reward_list,0 );
    if( .@reward_size )
    callsub( OnExplodeArray,.@reward_qty$,.@reward_qty,0 );
     
    .@selected_npc_size = callsub( OnExplodeArray,.@npc_id$,.@selected_npc_array$,1 );
     
    setarray .@level_range,.@min_lv,.@max_lv;
     
    // display the information of mission
    .@result = callsub( OnDisplayMissionInfo,
    .@mission_id,
    .@title$,
    .@description$,
    .@level_range,
    .@repeatable,
    .@expire[.@i],
    .@monster_list,
    .@monster_qty,
    .@item_list,
    .@item_qty,
    .@base_job_bitmask,
    .@job_branch_bitmask,
    .@baseexp,
    .@jobexp,
    .@cash,
    .@zeny,
    .@reward_list,
    .@reward_qty,
    .@selected_npc_array$,
    .@time_update$,
    .@redo_delay,
    1|2|4|8
    );
     
    // submit mission or not
    if( .@result ){
    message strcharinfo(0),"Failed to submit this mission.";
    }else{
    next;
    if( select( "Submit Completed Mission","Cancel" ) == 1 ){
    for( .@ms = ( @ms_size - 1 ); .@ms >= 0; .@ms-- )
    if( @ms_list$[.@ms] == ""+.@mission_id ){
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    query_sql( "UPDATE `player_mission` SET `completion` = NOW() WHERE `cid` = "+getcharid(0)+" AND `mission_id` = "+.@mission_id );
    mes "Mission accomplished.";
    @ms_size--;
     
    // clear requirement.
    setd( "@ms_"+.@mission_id+"_expire" ),0;
    deletearray getd( "@ms_"+.@mission_id+"_list" );
    deletearray getd( "@ms_"+.@mission_id+"_qty" );
    deletearray getd( "@ms_"+.@mission_id+"_hunt" );
    if( .@item_size )
    for( .@i = 0; .@i < .@item_size; .@i++ ){
    debugmes getitemname( .@item_list[.@i] )+" - "+.@item_qty[.@i];
    }
    // delitem .@item_list[.@i],.@item_qty[.@i];
     
    mes "Gained some mission's rewards.";
    // rewards
    getexp .@baseexp,.@jobexp;
    if( .@reward_size )
    for( .@i = 0; .@i < .@reward_size; .@i++ )
    getitem .@reward_list[.@i],.@reward_qty[.@i];
    #CASHPOINTS += .@cash;
    Zeny += .@zeny;
    break;
    }
    mes " ";
    }
    }
    break;
    Case 2:
    // get info from SQL.
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    deletearray .@id;
    query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"+.@mission_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 "+.@offset,.@id,.@title$,.@min_lv,.@max_lv );
    .@offset += .max_page_size;
    .@size = getarraysize( .@id );
    if( !.@size ){
    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!";
    .@mission_menu$ = "";
    for( .@i = 0; .@i < .@size; .@i++ )
    .@mission_menu$ = .@mission_menu$ + "["+.@min_lv[.@i]+"~"+.@max_lv[.@i]+"] "+.@title$[.@i] +":";
    }
    next;
    .@i = select( .@mission_menu$+ ( ( .@size < .max_page_size )?"":"- next page" ) ) - 1;
    }while( .@i == .@size );
     
    query_sql( "SELECT * FROM `mission_board` WHERE `id` = "+.@id[.@i]+" LIMIT 1",
    .@mission_id,
    .@title$,
    .@description$,
    .@mob_list$,
    .@mob_qty$,
    .@item_list$,
    .@item_qty$,
    .@base_job_bitmask,
    .@job_branch_bitmask,
    .@min_lv,
    .@max_lv,
    .@repeatable,
    .@timelimit,
    .@reward_list$,
    .@reward_qty$,
    .@baseexp,
    .@jobexp,
    .@zeny,
    .@cash,
    .@aid,
    .@name$,
    .@time_update$,
    .@npc_id$,
    .@redo_delay
    );
     
    // explode all saved strings to array value.
    .@monster_size = callsub( OnExplodeArray,.@mob_list$,.@monster_list,0 );
    .@monster_size = callsub( OnExplodeArray,.@mob_qty$,.@monster_qty,0 );
     
    .@item_size = callsub( OnExplodeArray,.@item_list$,.@item_list,0 );
    .@item_size = callsub( OnExplodeArray,.@item_qty$,.@item_qty,0 );
     
    .@reward_size = callsub( OnExplodeArray,.@reward_list$,.@reward_list,0 );
    .@reward_size = callsub( OnExplodeArray,.@reward_qty$,.@reward_qty,0 );
     
    .@selected_npc_size = callsub( OnExplodeArray,.@npc_id$,.@selected_npc_array$,1 );
     
    setarray .@level_range,.@min_lv,.@max_lv;
     
    // display the information of mission
    .@result = callsub( OnDisplayMissionInfo,
    .@mission_id,
    .@title$,
    .@description$,
    .@level_range,
    .@repeatable,
    ( .@timelimit + gettimetick(2) ),
    .@monster_list,
    .@monster_qty,
    .@item_list,
    .@item_qty,
    .@base_job_bitmask,
    .@job_branch_bitmask,
    .@baseexp,
    .@jobexp,
    .@cash,
    .@zeny,
    .@reward_list,
    .@reward_qty,
    .@selected_npc_array$,
    .@time_update$,
    .@redo_delay,
    1|8
    );
     
    // check completed how many times.
    if( .@repeatable[.@i] ){
    query_sql( "SELECT COUNT(`id`),TIMESTAMPDIFF( HOUR,`completion`,NOW() ),DATE_ADD( `completion`, INTERVAL "+.@redo_delay+" HOUR) FROM `player_mission` WHERE `mission_id` = "+.@id[.@i]+" AND `completion` <> '0000-00-00 00:00:00'",.@mission_completed,.@diff_delay,.@day$ );
    if( .@repeatable[.@i] && ( ( .@mission_completed >= .@repeatable[.@i] ) || ( .@diff_delay && .@diff_delay <= .@redo_delay ) ) ){
    next;
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes " ";
    if( .@mission_completed >= .@repeatable[.@i] ){
    mes "You cant pick this mission, you have mission completion reach the max repeatable attempt of "+.@mission_completed+" times.";
    close;
    }
    if( .@diff_delay && .@diff_delay <= .@redo_delay ){
    mes "You cant pick this mission, you have mission redo delay isnt finish yet.";
    mes "Approximate : ^FF0000"+.@day$+"^000000";
    close;
    }
    }
    }
     
    if( .@result ){
    message strcharinfo(0),"Failed to pick this mission.";
    }else{
    if( select( "Pick Mission","Cancel" ) == 1 ){
    query_sql( "INSERT INTO `player_mission` VALUES ( "+gettimetick(2)+","+.@mission_id+","+getcharid(3)+","+getcharid(0)+",'"+escape_sql( strcharinfo(0) )+"','',"+( .@timelimit + gettimetick(2) )+",NOW(),'0000-00-00 00:00:00' );" );
    message strcharinfo(0),"Picked Mission # "+.@mission_id;
     
    @ms_list$[ @ms_size ] = ""+.@mission_id;
    @ms_size++;
     
    copyarray getd( "@ms_"+.@mission_id+"_list[0]" ),.@monster_list[0],.@monster_size;
    copyarray getd( "@ms_"+.@mission_id+"_qty[0]" ),.@monster_qty[0],.@monster_size;
    deletearray getd( "@ms_"+.@mission_id+"_hunt" );
    addtimer ( .@timelimit * 1000 ),.npc_name$+"::OnTimeCheck";
    }
    }
    break;
    Case 3:
    query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"+.@mission_npc_num+"|%' AND `id` IN ( SELECT `mission_id` FROM `player_mission` WHERE `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00' )",.@id,.@title$,.@min_lv,.@max_lv );
    .@id_size = getarraysize( .@id );
    for( .@i = 0; .@i < .@id_size; .@i++ )
    .@mission_menu$ = .@mission_menu$ + "["+.@min_lv[.@i]+"~"+.@max_lv[.@i]+"] "+.@title$[.@i] +":";
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Pick a Mission to remove.";
    next;
    .@i = select( .@mission_menu$ ) - 1;
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Confirm remove ^0055FFMission # "+.@id[.@i]+"^000000?";
    mes "Title: ^0055FF"+.@title$[.@i]+"^000000";
    mes "^777777( this cant be un-done )^000000";
    if( select( "Yes, drop mission.","Confirm" ) == 2 ){
    message strcharinfo(0),"Dropped Mission # "+.@id[.@i];
    query_sql( "DELETE FROM `player_mission` WHERE `mission_id` = "+.@id[.@i]+" AND `cid` = "+getcharid(0)+" AND `completion` = '0000-00-00 00:00:00'" );
    setd( "@ms_"+.@id[.@i]+"_expire" ),0;
    deletearray getd( "@ms_"+.@id[.@i]+"_list" );
    deletearray getd( "@ms_"+.@id[.@i]+"_qty" );
    deletearray getd( "@ms_"+.@id[.@i]+"_hunt" );
    for( .@ms = 0; .@ms < @ms_size; .@ms++ )
    if( ""+.@id[.@i] == @ms_list$[.@ms] ){
    deletearray @ms_list$[.@ms],1;
    @ms_size--;
    break;
    }
    }
    break;
    Case 4:
    // get info from SQL.
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    deletearray .@id;
    query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"+.@mission_npc_num+"|%' LIMIT "+.max_page_size+" OFFSET "+.@offset,.@id,.@title$,.@min_lv,.@max_lv );
    .@offset += .max_page_size;
    .@size = getarraysize( .@id );
    if( !.@size ){
    mes "There are no available mission to update.";
    close;
     
    }else{
    mes "Pick a mission.";
    .@mission_menu$ = "";
    for( .@i = 0; .@i < .@size; .@i++ )
    .@mission_menu$ = .@mission_menu$ + "["+.@min_lv[.@i]+"~"+.@max_lv[.@i]+"] "+.@title$[.@i] +":";
    }
    next;
    .@i = select( .@mission_menu$+ ( ( .@size < .max_page_size )?"":"- next page" ) ) - 1;
    }while( .@i == .@size );
    query_sql( "SELECT * FROM `mission_board` WHERE `id` = "+.@id[.@i],
    .@new_mission_id,
    .@title$,
    .@description$,
    .@mob_list$,
    .@mob_qty$,
    .@item_list$,
    .@item_qty$,
    .@base_job_bitmask,
    .@job_branch_bitmask,
    .@min_lv,
    .@max_lv,
    .@repeatable,
    .@timelimit,
    .@reward_list$,
    .@reward_qty$,
    .@baseexp,
    .@jobexp,
    .@zeny,
    .@cash,
    .@aid,
    .@name$,
    .@time_update$,
    .@npc_id$,
    .@redo_delay
    );
    // explode all saved strings to array value.
    .@monster_size = callsub( OnExplodeArray,.@mob_list$,.@monster_list,0 );
    .@monster_size = callsub( OnExplodeArray,.@mob_qty$,.@monster_qty,0 );
     
    .@item_size = callsub( OnExplodeArray,.@item_list$,.@item_list,0 );
    .@item_size = callsub( OnExplodeArray,.@item_qty$,.@item_qty,0 );
     
    .@reward_size = callsub( OnExplodeArray,.@reward_list$,.@reward_list,0 );
    .@reward_size = callsub( OnExplodeArray,.@reward_qty$,.@reward_qty,0 );
     
    .@selected_npc_size = callsub( OnExplodeArray,.@npc_id$,.@selected_npc_array$,1 );
     
    setarray .@level_range,.@min_lv,.@max_lv;
     
    Case 5:
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    // display the information of mission
    callsub( OnDisplayMissionInfo,
    .@new_mission_id,
    .@title$,
    .@description$,
    .@level_range,
    .@repeatable,
    ( .@timelimit + gettimetick(2) ),
    .@monster_list,
    .@monster_qty,
    .@item_list,
    .@item_qty,
    .@base_job_bitmask,
    .@job_branch_bitmask,
    .@baseexp,
    .@jobexp,
    .@cash,
    .@zeny,
    .@reward_list,
    .@reward_qty,
    .@selected_npc_array$,
    .@time_update$,
    .@redo_delay,
    0
    );
     
    // check if required info complete for setup mission
    .@incomplete = 0;
    if( .@title$ == "" ) .@incomplete |= 1;
    if( .@description$ == "" ) .@incomplete |= 2;
    if( !.@monster_size && !.@item_size ) .@incomplete |= 4;
    if( getarraysize( .@level_range ) != 2 || !.@base_job_bitmask || !.@job_branch_bitmask ) .@incomplete |= 8;
    if( !.@reward_size && !.@baseexp && !.@jobexp && !.@cash && !.@zeny ) .@incomplete |= 16;
    if( !.@selected_npc_size ) .@incomplete |= 32;
     
    .@main_option = select( "Edit Title "+(( .@incomplete & 1 )?"^FF0000-incomplete-^000000":"" ),
    "Edit Description "+(( .@incomplete & 2 )?"^FF0000-incomplete-^000000":"" ),
    "Edit Monster List "+(( .@incomplete & 4 )?"^FF0000-incomplete-^000000"  ( !.@monster_size )?"^777777-none-^000000":"" )),
    "Edit Item List "+(( .@incomplete & 4 )?"^FF0000-incomplete-^000000"  ( !.@item_size )?"^777777-none-^000000":"" )),
    "Edit Class/Level Limitation "+(( .@incomplete & 8 )?"^FF0000-incomplete-^000000":"" ),
    "Edit Time/Repeat/Mission Limitation ",
    "Edit Reward List "+(( .@incomplete & 16 )?"^FF0000-incomplete-^000000":"" ),
    "Edit NPC Limitation "+(( .@incomplete & 32 )?"^FF0000-incomplete-^000000":"" ),
    ( .@incomplete )?"":"^0055FF - Complete Setup Mission^000000" );
    next; 
    switch( .@main_option ){
    Case 1:
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Enter Title";
    mes "^777777( Length: 4 ~ 30 )^000000";
    while( input( .@title$,4,30 ) );
    .@input_result = replacestr( .@title$,":"," " );
    break;
    Case 2:
    .@description$ = "";
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Enter Description";
    mes "^777777( Length: 4 ~ 255 )^000000";
    mes " ";
    mes "^0055FF"+.@description$+"^000000";
    .@length = getstrlen( .@description$ );
    do{
    .@input_result = input( .@temp_input$,4,255 );
    if( .@input_result )
    message strcharinfo(0),"Input length must between 4 ~ 255";
    }while( .@input_result );
    .@description$ = .@description$ + " "+ .@temp_input$;
    mes "^0055FF"+.@temp_input$+"^000000";
    .@length = getstrlen( .@description$ );
    next;
    }while( select( ( .@length >= 255 )?"":"add more ^777777( left "+( 255 - .@length )+" words )^000000","-back" ) == 1 );
    .@description$  = replacestr( .@description$,":"," " );
    break;
    Case 3:
    if( .@new_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[ "+.@npc_name$+" ]^000000";
    mes "Monsters to kill:";
    if( .@monster_size ){
    .@mob_menu$ = "";
    .@current_mob_list$ = "|";
    deletearray .@current_mob$;
    for( .@i = 0; .@i < .@monster_size; .@i++ ){
    .@mob_name$ = getmonsterinfo( .@monster_list[.@i],MOB_NAME );
    .@mob_menu$ = .@mob_menu$ + .@monster_qty[.@i] +" x "+.@mob_name$ +":";
    mes " ^777777 ~ "+.@monster_qty[.@i]+" x "+.@mob_name$+"^000000";
    .@current_mob_list$ = .@current_mob_list$ + .@monster_list[.@i] +"|";
    }
     
    }else{
    mes " ^777777 ~ Unavailable ^000000";
    }
    mes " ";
    .@option = select( ( .@monster_size >= .max_required_monster )?"":"Add Monster",( .@monster_size )?"Delete Monster":"","- Back" );
    switch( .@option ){
    Case 1:
    mes "Enter Monster ID";
    do{
    input .@mob_id;
    if( !.@mob_id ) break;
    .@mob_name$ = getmonsterinfo( .@mob_id,MOB_NAME );
    }while( .@mob_name$ == "null" );
    if( .@mob_name$ != "null" && .@mob_id ){
    mes "How many "+.@mob_name$+" need to hunt ?";
    input .@amount,0,30000;
    if( .@amount ){
    if( compare( "|"+.@current_mob_list$+"|","|"+.@mob_id+"|" ) ){
    for( .@i = 0; .@i < .@monster_size; .@i++ )
    if( .@monster_list[.@i] == .@mob_id ){
    .@monster_qty[.@i] += .@amount;
    break;
    }
     
    }else{
    .@monster_list[.@monster_size] = .@mob_id;
    .@monster_qty[.@monster_size] = .@amount;
    .@monster_size++;
    }
    }
    }
    break;
    Case 2:
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Pick a Monster to Remove.";
    .@i = select( .@mob_menu$+"- Back" ) - 1;
    if( .@i < .@monster_size ){
    deletearray .@monster_list[.@i],1;
    deletearray .@monster_qty[.@i],1;
    .@monster_size--;
    }
    default: break;
    }
    if( .@option < 3 ) next;
    }while( .@option < 3 );
    break;
    Case 4:
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Required Item List: ";
    if( .@item_size ){
    .@item_menu$ = "";
    .@current_item_list$ = "|";
    deletearray .@current_item$;
    for( .@i = 0; .@i < .@item_size; .@i++ ){
    .@item_name$ = getitemname( .@item_list[.@i] );
    .@item_menu$ = .@item_menu$ + .@item_qty[.@i] +"x "+.@item_name$ +":";
    mes " ^777777 ~ "+.@item_qty[.@i]+" x "+.@item_name$+"^000000";
    .@current_item_list$ = .@current_item_list$ + .@item_list[.@i] + "|";
    }
     
    }else{
    mes " ^777777 ~ Unavailable ^000000";
    }
    mes " ";
    .@option = select( ( .@item_size >= .max_required_item )?"":"Add Item",( .@item_size )?"Delete Item":"","- Back" );
    switch( .@option ){
    Case 1:
    do{
    input .@item_id;
    if( !.@item_id ) break;
    .@item_name$ = getitemname( .@item_id );
    }while( .@item_name$ == "null" || .@item_name$ == "" );
    if( .@item_id && .@item_name$ != "null" && .@item_name$ != "" ){
    mes "How many "+.@item_name$+" need to collect ?";
    input .@amount,0,30000;
    if( .@amount ){
    if( compare( "|"+.@current_item_list$+"|","|"+.@item_id+"|" ) ){
    for( .@i = 0; .@i < .@item_size; .@i++ )
    if( .@item_list[.@i] == .@item_id ){
    .@item_qty[.@i] += .@amount;
    break;
    }
    }else{
    .@item_list[.@item_size] = .@item_id;
    .@item_qty[.@item_size] = .@amount;
    .@item_size++;
    }
    }
    }
    break;
    Case 2:
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Pick an Item to Remove.";
    .@i = select( .@item_menu$+" - Back" ) - 1;
    if( .@i < .@item_size ){
    mes "Removed "+.@item_qty[.@i]+" x "+getitemname( .@item_list[.@i] );
    deletearray .@item_list[.@i],1;
    deletearray .@item_qty[.@i],1;
    .@item_size--;
    }
    default: break;
    }
    if( .@option < 3 ) next;
    }while( .@option < 3 );
    break;
    Case 5: // class limitation
    if( !.@base_job_bitmask ){
    // enable all job by default.
    for( .@i = 0; .@i < .base_job_size; .@i++ ){
    .@bitmask_value = ( 1 << .@i );
    .@base_job_bitmask |= .@bitmask_value;
    }
    // enable all inherited classes by default.
    for( .@i = 0; .@i < .job_branch_size; .@i++ ){
    .@bitmask_value = ( 1 << .@i );
    .@job_branch_bitmask |= .@bitmask_value;
    }
    }
     
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Level Range: "+( ( .@level_range[1] )? "^777777"+.@level_range[0]+" ~ "+.@level_range[1]:"^FF0000-incomplete-" )+"^000000";
    mes "Available Job Setting";
    if( .@base_job_bitmask ){
    for( .@i = 0; .@i < .base_job_size; .@i++ )
    if( .@base_job_bitmask & ( 1 << .@i ) )
    mes " ^777777 ~ "+jobname( roclass( .base_job[.@i] ) )+" ^000000";
    }else{
    mes " ^FF0000 -incomplete-^000000";
    }
    mes " ";
    mes "Inherited Branch Setting";
    if( .@job_branch_bitmask ){
    for( .@i = 0; .@i < .job_branch_size; .@i++ )
    if( .@job_branch_bitmask & ( 1 << .@i ) )
    mes " ^777777 ~ "+.job_branch_name$[.@i]+" ^000000"; 
    }else{
    mes " ^FF0000 -incomplete-^000000";
    } 
    next;
    .@option = select( "Edit Base Job","Edit Job Branch","Edit Level Range","- Back" );
    switch( .@option ){
    Case 1:
    dispbottom "[ Base Job Class ] RED = Disable , GREEN = Enable";
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Available Job List:";
    .@base_job_menu$ = "";
    for( .@i = 0; .@i < .base_job_size; .@i++ ){
    .@job_name$ = jobname( roclass( .base_job[.@i] ) );
    if( .@base_job_bitmask & ( 1 << .@i ) )
    mes " ^777777 ~ "+.@job_name$+" ^000000"; 
    .@base_job_menu$ = .@base_job_menu$ + (( .@base_job_bitmask & ( 1 << .@i ) )?"^4EEE94":"^FF0000" ) + .@job_name$ +"^000000:";
    }
    next;
    .@i = select( .@base_job_menu$+"- Back" ) - 1;
    if( .@i < .base_job_size ){
    .@bitmask_value = ( 1 << .@i );
    if( .@base_job_bitmask & .@bitmask_value )
    .@base_job_bitmask -= .@bitmask_value;
    else
    .@base_job_bitmask |= .@bitmask_value;
    }
    }while( .@i < .base_job_size );
    break;
    Case 2:
    dispbottom "[ Inherited Job Branch ] RED = Disable , GREEN = Enable";
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Inherited Job Branch List:";
    .@job_branch_menu$ = "";
    for( .@i = 0; .@i < .job_branch_size; .@i++ ){
    if( .@job_branch_bitmask & ( 1 << .@i ) )
    mes " ^777777 ~ "+.job_branch_name$[.@i]+" ^000000"; 
    .@job_branch_menu$ = .@job_branch_menu$ + (( .@job_branch_bitmask & ( 1 << .@i ) )?"^4EEE94":"^FF0000" ) + .job_branch_name$[.@i] +"^000000:";
    }
    next;
    .@i = select( .@job_branch_menu$+"- Back" ) - 1;
    if( .@i < .job_branch_size ){
    .@bitmask_value = ( 1 << .@i );
    if( .@job_branch_bitmask & .@bitmask_value )
    .@job_branch_bitmask -= .@bitmask_value;
    else
    .@job_branch_bitmask |= .@bitmask_value;
    }
    }while( .@i < .job_branch_size );
    break;
    Case 3:
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Minimum Level";
    input .@level_range[0],1,.server_max_level ;
    mes "Maximum Level";
    input .@level_range[1],.@level_range[0],.server_max_level;
    default: break;
    }
    if( .@option < 4 ) next;
    }while( .@option < 4 );
    break;
    Case 6: // mission limitation
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Can do: ^777777"+( ( !.@repeatable )?"Unlimited times":""+.@repeatable )+" time^000000";
    mes "Redo Delay: ^777777"+( ( !.@redo_delay )?"Unavailable":callsub( OnTime2Str,( ( .@redo_delay * 3600 ) + gettimetick(2) ) ))+"^000000";
    mes "Time Limit: ^777777"+( ( !.@timelimit )?"Unavailable":callsub( OnTime2Str,( .@timelimit + gettimetick(2) ) ) )+"^000000";
    .@option = select( "Edit Repeatable Status","Edit Time Limit","Edit Re-do Delay","Edit Required Mission","- Back" );
    switch( .@option ){
    Case 1:
    mes "How many time can this mission repeat ??";
    mes "^777777( 0 = unlimited )^000000";
    input .@repeatable,0,100;
    break;
    Case 2:
    mes "Time Limit of mission";
    mes "      1 = 1 minute";
    mes "    60 = 1 hour";
    mes "1440 = 1 day";
    input .@timelimit,0,50000;
    .@timelimit *= 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 .@redo_delay,0,50000;
    break;
    Case 4:
    mes "This is not fully implemented yet.. still in beta test";
    break;
     
    do{
    mes "Required Mission:";
    if( .@required_mission_size ){
    for( .@i = 0; .@i < .@required_mission_size; .@i++ ){
    mes " ^777777 ~ "+.@required_mission$[.@i]+"^000000";
    .@required_mission_menu$ = .@required_mission_menu$ + .@required_mission$[.@i] +":";
    }
     
    }else{
    mes "^777777 none ^000000";
    }
    next;
    .@sub_option = select( ( .@required_mission_size < .max_required_mission )?"Add required mission":"",
    ( .@required_mission_size )?"Remove required mission":"",
    "- Back");
    switch( .@sub_option ){
    Case 1:
    mes "Enter mission ID";
    mes "^777777( enter 0 to cancel )^000000";
    do{
    input .@mission_id$;
    if( .@mission_id$ == "0" ) break;
    }while( compare( "|"+.@required_mission_menu$+"|","|"+.@mission_id$+"|" ) );
    .@mission_id$ = replacestr( .@mission_id$,":","" );
    if( .@mission_id$ != "0" ){
    .@required_mission$[.@required_mission_size] = .@mission_id$;
    .@required_mission_size++;
    }
    break;
    Case 2:
    mes "Select a mission to remove.";
    .@i = select( .@required_mission_menu$ ) - 1;
    deletearray .@required_mission$[.@i],1;
    default: break;
    }
    }while( .@sub_option < 3 );
    default: break;
    }
    if( .@option < 5 ) next;
    }while( .@option < 5 );
    break;
    Case 7: // reward list
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Zeny: ^777777"+( ( .@zeny )? .@zeny:"None" )+"^000000";
    mes "Reward Item List: ";
    if( .@reward_size ){
    .@reward_menu$ = "";
    deletearray .@current_reward$;
    for( .@i = 0; .@i < .@reward_size; .@i++ ){
    .@reward_name$ = getitemname( .@reward_list[.@i] );
    .@reward_menu$ = .@item_menu$ + .@reward_qty[.@i] +"x "+.@reward_name$ +":";
    .@current_reward$[.@i] = .@reward_name$;
    mes " ^777777 ~ "+.@reward_qty[.@i]+" x "+.@reward_name$+"^000000";
    }
    .@current_reward_list$ = implode( .@current_reward$,"|" );
     
    }else{
    mes " ^777777 ~ none ^000000";
    }
    mes "Base EXP: ^777777"+( ( .@baseexp )? .@baseexp:"None" )+"^000000";
    mes "Job EXP: ^777777"+( ( .@jobexp )? .@jobexp:"None" )+"^000000";
    mes " ";
    next;
    .@option = select( ( .@reward_size >= .max_required_item )?"":"Add Item Reward",
    ( .@reward_size )?"Delete Item Reward":"",
    "Edit Cash Reward",
    "Edit Zeny Reward",
    "Edit Base EXP Reward",
    "Edit Job EXP Reward",
    "- Back" );
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    switch( .@option ){
    Case 1:
    mes "Enter Reward Item ID";
    do{
    input .@reward_id;
    if( !.@reward_id ) break;
    .@reward_name$ = getitemname( .@reward_id );
    }while( .@reward_name$ == "null" || .@reward_name$ == "" );
    if( .@reward_id && .@reward_name$ != "null" && .@reward_name$ != "" ){
    mes "How many "+.@reward_name$+" will be rewarded ?";
    input .@amount,0,30000;
    if( .@amount ){
    if( compare( "|"+.@current_reward_list$+"|","|"+.@reward_name$+"|" ) ){
    for( .@i = 0; .@i < .@reward_size; .@i++ )
    if( .@reward_list[.@i] == .@item_id ){
    .@reward_qty[.@i] += .@amount;
    break;
    }
    }else{
    .@reward_list[.@reward_size] = .@reward_id;
    .@reward_qty[.@reward_size] = .@amount;
    .@reward_size++;
    }
    }
    }
    break;
    Case 2:
    mes "Pick an Reward to Remove.";
    .@i = select( .@reward_menu$ ) - 1;
    mes "Removed "+.@reward_qty[.@i]+"x "+getitemname( .@reward_list[.@i] );
    deletearray .@reward_list[.@i],1;
    deletearray .@reward_qty[.@i],1;
    .@reward_size--;
    break;
    Case 3:
    mes "How many Cash will be given ?";
    mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
    input .@cash,0,.max_integer_value;
    break;
    Case 4:
    mes "How many Zeny will be given ?";
    mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
    input .@zeny,0,.max_integer_value;
    break;
    Case 5:
    mes "How many Base EXP reward ?";
    mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
    input .@baseexp,0,.max_integer_value;
    break;
    Case 6:
    mes "How many Job EXP reward ?";
    mes "^777777( value: 0 ~ "+.max_integer_value+" )^000000";
    input .@jobexp,0,.max_integer_value;
    default: break;
    }
    next;
    }while( .@option < 7 );
    break;
    Case 8: // npc limitation
    mes "^0055FF[ "+.@npc_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( .@selected_npc_array$ ) )
    for( .@i = 0; .@i < .mission_npc_count; .@i++ ){
    .@selected_npc_array$[.@i] = ""+.@i;
    .@selected_npc_size++;
    }
    dispbottom "[ NPC Limitation ] RED = Disable , GREEN = Enable";
     
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    mes "Mission offered by: ";
    .@selected_npc_menu$ = "";
    if( .@selected_npc_size >= 2 ){
    .@selected_npc$ = "|"+implode( .@selected_npc_array$,"|" )+"|";
    }else{
    .@selected_npc$ = "|"+.@selected_npc_array$+"|";
    }
    for( .@i = 0; .@i < .mission_npc_count; .@i++ ){
    getmapxy( .@map$,.@x,.@y,1,.npc_unique_list$[.@i] );
    .@sub_npc_name$ = ( ( compare( "|"+.@selected_npc$+"|","|"+.@i+"|" ) )?"^44EE00":"^FF0000" );
    .@sub_npc_name$ = .@sub_npc_name$ + .npc_name_list$[.@i];
    mes "^777777("+.@map$+") "+.@sub_npc_name$;
    .@selected_npc_menu$ = .@selected_npc_menu$ + .@sub_npc_name$ +":";
    }
    next;
    .@option = select( .@selected_npc_menu$+"^000000- Back" ) - 1;
    if( .@option < .mission_npc_count ){
    if( compare( "|"+.@selected_npc$+"|","|"+.@option+"|" ) )
    .@selected_npc_array$[.@option] = "";
    else
    .@selected_npc_array$[.@option] = ""+.@option;
    .@selected_npc_size = getarraysize( .@selected_npc_array$ );
    }
    // dispbottom "["+rand(10,99)+"] "+implode( .@selected_npc_array$,"|" );
    }while( .@option < .mission_npc_count );
    break;
    default: break;
    }
    next;
    }while( .@main_option < 9 );
     
    // finalise all variable
    if( .@monster_size ){
    .@final_mob_list$ = "|";
    .@final_mob_qty$ = "|";
    for( .@i = 0; .@i < .@monster_size; .@i++ ){
    .@final_mob_list$ = .@final_mob_list$ + .@monster_list[.@i] +"|";
    .@final_mob_qty$ = .@final_mob_qty$ + .@monster_qty[.@i] +"|";
    } 
    }
     
    if( .@item_size ){
    .@final_item_list$ = "|";
    .@final_item_qty$ = "|";
    for( .@i = 0; .@i < .@item_size; .@i++ ){
    .@final_item_list$ = .@final_item_list$ + .@item_list[.@i] +"|";
    .@final_item_qty$ = .@final_item_qty$ + .@item_qty[.@i] +"|";
    }
    }
     
    if( .@reward_size ){
    .@final_reward_list$ = "|";
    .@final_reward_qty$ = "|";
    for( .@i = 0; .@i < .@reward_size; .@i++ ){
    .@final_reward_list$ = .@final_reward_list$ + .@reward_list[.@i] +"|";
    .@final_reward_qty$ = .@final_reward_qty$ + .@reward_qty[.@i] +"|";
    }
    }
     
    if( .@selected_npc_size ){
    .@final_npc_list$ = "|";
    for( .@i = 0; .@i < .@selected_npc_size; .@i++ )
    .@final_npc_list$ = .@final_npc_list$ + .@selected_npc_array$[.@i] +"|";
    }
     
    if( !.@new_mission_id ){
    .@new_mission_id = gettimetick(2);
    message strcharinfo(0),"Mission # "+.@new_mission_id+" has been added.";
    }else{
    message strcharinfo(0),"Mission # "+.@new_mission_id+" has been updated.";
    // attach and inform other online players.
    callsub( OnRemoveMission,.@new_mission_id,"A GM updated Mission # "+.@new_mission_id );
    }
     
    // add new mission into SQL
    query_sql( 
    "REPLACE INTO `mission_board` VALUES ( " +
    .@new_mission_id+", " +
    "'"+escape_sql( .@title$ )+"', " +
    "'"+escape_sql( .@description$ )+"', " +
    "'"+escape_sql( .@final_mob_list$ )+"', " +
    "'"+escape_sql( .@final_mob_qty$ )+"', " +
    "'"+escape_sql( .@final_item_list$ )+"', " +
    "'"+escape_sql( .@final_item_qty$ )+"', " +
    .@base_job_bitmask+", " +
    .@job_branch_bitmask+", " +
    .@level_range[0]+", " +
    .@level_range[1]+", " +
    .@repeatable+", " +
    .@timelimit+", " +
    "'"+escape_sql( .@final_reward_list$ )+"', " +
    "'"+escape_sql( .@final_reward_qty$ )+"', " +
    .@baseexp+", " +
    .@jobexp+", " +
    .@zeny+", " +
    .@cash+", " +
    getcharid(3)+", " +
    "'"+escape_sql( strcharinfo(0) )+"', " +
    "NOW(), " +
    "'"+escape_sql( .@final_npc_list$ )+"', " +
    .@redo_delay +
    " ); " 
    );
    break;
    Case 6: // delete mission
    do{
    mes "^0055FF[ "+.@npc_name$+" ]^000000";
    deletearray .@id;
    query_sql( "SELECT `id`,`title`,`min_lv`,`max_lv` FROM `mission_board` WHERE `npc_id` LIKE '%|"+.@mission_npc_num+"|%' LIMIT "+.max_page_size+" OFFSET "+.@offset,.@id,.@title$,.@min_lv,.@max_lv );
    .@offset += .max_page_size;
    .@size = getarraysize( .@id );
    if( !.@size ){
    mes "There are no available mission to update.";
    close;
     
    }else{
    mes "Pick a mission.";
    for( .@i = 0; .@i < .@size; .@i++ )
    .@mission_menu$ = .@mission_menu$ + "["+.@min_lv[.@i]+"~"+.@max_lv[.@i]+"] "+.@title$[.@i] +":";
    }
    next;
    .@i = select( .@mission_menu$+ ( ( .@size < .max_page_size )?"":"- next page" ) ) - 1;
    }while( .@i == .@size );
    .@mission_id = .@id[.@i];
    mes "^0055FF[ "+.@npc_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` = "+.@mission_id+" LIMIT 1" );
    mes "Removed mission from mission list.";
     
    // attach other online players and remove the missions.
    callsub( OnRemoveMission,.@mission_id,"A GM removed Mission # "+.@mission_id );
    query_sql( "DELETE FROM `player_mission` WHERE `completion` = '0000-00-00 00:00:00' AND `mission_id` = "+.@mission_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 );
     
    }else{
    // delay the process
    .@num = atoi( strnpcinfo(2) );
    if( .@num && .@num <= 500 && .mission_npc_count < 100 ){
    sleep( .@num + 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( !.@num ){
    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;
     
    // OnWhisperGlobal:
    OnPCLoginEvent:
    if( strnpcinfo(0) == .npc_name$ ){
    .@timetick = 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$,.@expire,.@mob_hunt$ );
    @ms_size = getarraysize( @ms_list$ );
    if( @ms_size )
    for( .@i = 0; .@i < @ms_size; .@i++ ){
    if( .@timetick < .@expire[.@i] ){
    .@timeleft = ( .@expire[.@i] - .@timetick );
    addtimer ( .@timeleft * 1000 ),.npc_name$+"::OnTimeCheck";
    dispbottom "[ Mission Progress : "+@ms_list$[.@i]+" , expire in "+callsub( OnTime2Str,( .@timeleft + .@timetick ) )+" ]";
    query_sql( "SELECT `mob_list`,`mob_qty` FROM `mission_board` WHERE `id` = "+@ms_list$[.@i],.@mob_list$,.@mob_qty$ );
     
    setd( "@ms_"+@ms_list$[.@i]+"_expire" ),.@expire[.@i];
    if( callsub( OnExplodeArray,.@mob_list$[.@i],getd( "@ms_"+@ms_list$[.@i]+"_list" ),0 ) ){
    callsub( OnExplodeArray,.@mob_hunt$[.@i],getd( "@ms_"+@ms_list$[.@i]+"_qty" ),0 );
    .@monster_size = callsub( OnExplodeArray,.@mob_hunt$[.@i],getd( "@ms_"+@ms_list$[.@i]+"_hunt" ),0 );
    // for( .@mob = 0; .@mob < .@monster_size; .@mob++ )
    // dispbottom  " ~ killed "+getd( "@ms_"+@ms_list$[.@i]+"_hunt["+.@mob+"]" )+"/"+getd( "@ms_"+@ms_list$[.@i]+"_qty["+.@mob+"]" )+" x "+getmonsterinfo( getd( "@ms_"+@ms_list$[.@i]+"_list["+.@mob+"]" ),MOB_NAME );
    }
    }
    }
    }
    end;
     
    OnPCLogoutEvent:
    if( strnpcinfo(0) == .npc_name$ ){
    if( @ms_size )
    for( .@ms = 0; .@ms < @ms_size; .@ms++ ){
    debugmes "Saving "+@ms_list$[.@ms];
    .@mob_size = getarraysize( getd( "@ms_"+@ms_list$[.@ms]+"_list" ) );
    if( .@mob_size ){
    copyarray .@temp_array[0],getd( "@ms_"+@ms_list$[.@ms]+"_list[0]" ),.@mob_size;
    .@mob_hunt$ = "|";
    for( .@mob = 0; .@mob < .@mob_size; .@mob++ )
    .@mob_hunt$ = .@mob_hunt$ + getd( "@ms_"+@ms_list$[.@ms]+"_hunt["+.@mob+"]" ) +"|";
    query_sql( "UPDATE `player_mission` SET `mob_hunt` = '"+escape_sql( .@mob_hunt$ )+"' WHERE `mission_id` = "+@ms_list$[.@ms]+" AND `completion` = '0000-00-00 00:00:00' AND `cid` = "+getcharid(0) );
    }
    }
    }
    end;
     
    OnNPCKillEvent:
    if( strnpcinfo(0) == .npc_name$ ){
    if( @ms_size ){
    .@map$ = strcharinfo(3);
     
    // by default mission wont work in PVP,GVG,Instance,Event maps
    if( compare( .@map$,"@" ) || getmapflag( .@map$,mf_gvg ) || getmapflag( .@map$,mf_pvp )){
    // dispbottom "[Mission Board] PvP/GvG Map , Instance Map , Event Map , include monsters will not affect Mission Progress.";
    end;
    }
     
    .@timetick = gettimetick(2);
    for( .@ms = ( @ms_size - 1 ); .@ms >= 0; .@ms-- ){
    .@mob_size = getarraysize( getd( "@ms_"+@ms_list$[.@ms]+"_list" ) );
    if( .@mob_size ){
    copyarray .@temp_array[0],getd( "@ms_"+@ms_list$[.@ms]+"_list[0]" ),.@mob_size;
    for( .@mob = 0; .@mob_size; .@mob++ )
    if( .@temp_array[.@mob] == killedrid ){
    .@value = getd( "@ms_"+@ms_list$[.@ms]+"_hunt["+.@mob+"]" ) + 1;
    setd( "@ms_"+@ms_list$[.@ms]+"_hunt["+.@mob+"]" ),.@value;
    // dispbottom "[Mission # "+@ms_list$[.@ms]+" Progress] Hunted "+.@value+" x "+getmonsterinfo( .@temp_array[.@mob],MOB_NAME );
    break;
    }
    deletearray .@temp_array;
    }
    }
    }
    }
    end;
     
    OnRemoveMission:
    .@mission_id = getarg(0);
    .@message$ = getarg(1);
     
    query_sql( "SELECT `aid`,`cid` FROM `player_mission` WHERE `cid` IN ( SELECT `char_id` FROM `char` WHERE `online` = 1 ) AND `mission_id` = "+.@mission_id+" AND `completion` = '0000-00-00 00:00:00' LIMIT 128",.@aid,.@cid );
    .@aid_size = getarraysize( .@aid );
    .@i = 0;
    .@origin_aid = getcharid(3);
    while( .@i < .@aid_size ){
    if( isloggedin( .@aid[.@i],.@cid[.@i] ) ){
    attachrid( .@aid[.@i] );
    for( .@ms = @ms_size; .@ms >= 0; .@ms-- )
    if( @ms_list$[.@ms] == ""+.@mission_id ){
    message strcharinfo(0),.@message$;
    dispbottom "Please visit Mission NPC to gain latest information.";
    setd( "@ms_"+@ms_list$[.@ms]+"_expire" ),0;
    deletearray getd( "@ms_"+@ms_list$[.@ms]+"_list" );
    deletearray getd( "@ms_"+@ms_list$[.@ms]+"_qty" );
    deletearray getd( "@ms_"+@ms_list$[.@ms]+"_hunt" );
    deletearray @ms_list$[.@ms],1;
    @ms_size--;
    break;
    }
    detachrid;
    .@count++;
    }
    .@i++;
    }
    attachrid( .@origin_aid );
    dispbottom "Total "+.@count+" online players affected.";
    return;
     
    // usage :
    // .@timeleft = callsub( OnTime2Str,<time> );
    OnTime2Str:
    .@time = getarg(0);
    .@left = ( .@time - gettimetick(2) );
    .@hour = ( .@left / 3600 );
    .@min = ( .@left % 3600 / 60 );
    .@sec = ( .@left % 60 );
    if( !.@left ) 
    return "none";
    else
    return "^777777"+( ( .@hour )? .@hour+" hr ":"" ) + ( ( .@hour || .@min )? .@min+" min ":"" ) +.@sec+" sec^000000";
      
      
    // usage : 
    // .@new_array_size = callsub( OnExplodeArray,<old string variable>,<new array variable>,<save '0'> );
    OnExplodeArray:
    .@type = getarg(2);
    explode( getarg(0),getarg(0),"|" );
    .@size = getarraysize( getarg(0) );
    while( .@i < .@size ){
    if( !.@type ){
    .@value = atoi( getelementofarray( getarg(0),.@i ) );
    if( .@value ){
    set getelementofarray( getarg(1),.@new_size ),.@value;
    .@new_size++;
    }
    }else{
    set getelementofarray( getarg(1),.@new_size ),getelementofarray( getarg(0),.@i );
    .@new_size++;
    }
    .@i++;
    }
     
    return .@new_size;
     
     
    // display mission information + optional progress checking
    OnDisplayMissionInfo:
    .@mission_id = getarg(0);
    .@title$ = getarg(1);
    .@description$ = getarg(2);
    .@repeatable = getarg(4);
    .@timelimit = getarg(5);
    .@monster_size = getarraysize( getarg(6) );
    .@item_size = getarraysize( getarg(8) );
    .@base_job_bitmask = getarg(10);
    .@job_branch_bitmask = getarg(11);
    .@baseexp = getarg(12);
    .@jobexp = getarg(13);
    .@cash = getarg(14);
    .@zeny = getarg(15);
    .@reward_size = getarraysize( getarg(16) );
    .@selected_npc_size = getarraysize( getarg(18) );
    .@time_update$ = getarg(19);
    .@redo_delay = getarg(20);
    .@check_progress = getarg(21);
     
    if( .@check_progress & 8 )
    .@eac = eaclass();
     
    // display mission info
    mes ""+(( .@mission_id )? "^FF0000Mission ID # "+.@mission_id:" " )+"^000000";
    mes "Title: "+( ( .@title$ != "" )?"^777777"+.@title$:"^FF0000-incomplete-" )+"^000000";
    mes "Description: "+( ( .@description$ != "" )?"^777777"+.@description$:"^FF0000-incomplete-" )+"^000000";
    mes "Level Range: "+( ( getelementofarray( getarg(3),0 ) )? "^777777"+getelementofarray( getarg(3),0 )+" ~ "+getelementofarray( getarg(3),1 ):"^FF0000-incomplete-" )+"^000000";
    if( .@check_progress & 1 )
    if( BaseLevel >= getelementofarray( getarg(3),0 ) && BaseLevel <= getelementofarray( getarg(3),1 ) )
    .@lv_progress = 1;
     
    mes "Can do: ^777777"+( ( !.@repeatable )?"Repeatedly":.@repeatable+" time" )+"^000000";
    mes "Re-do Delay: ^777777"+( ( !.@redo_delay )?"Unavailable":callsub( OnTime2Str,( ( .@redo_delay * 3600 ) + gettimetick(2) ) ) )+"^000000";
     
    .@word$ = (( !.@monster_size && !.@item_size )?"^FF0000Incomplete":"^777777Unavailable" );
    mes "Monsters to kill: "+( ( .@monster_size )?"":.@word$ )+"^000000";
    if( .@monster_size )
    for( .@i = 0; .@i < .@monster_size; .@i++ ){
    .@mob_id = getelementofarray( getarg(6),.@i );
    .@quantity = getelementofarray( getarg(7),.@i );
    if( .@check_progress & 2 ){
    .@killed_count = getd( "@ms_"+.@mission_id+"_hunt["+.@i+"]" );
    if( .@killed_count >= .@quantity ){
    .@monster_progress++;
    .@temp_color$ = "44EE99";
    }else{
    .@temp_color$ = "FF0000";
    }
    }
    mes " ^777777"+.@quantity+" x "+getmonsterinfo( .@mob_id,MOB_NAME )+"  "+( ( .@check_progress & 2 )?"^"+.@temp_color$+"(killed "+.@killed_count+")":"" )+"^000000";
    }
    mes "Items to collect: "+( ( .@item_size )?"":.@word$ )+"^000000";
    if( .@item_size )
    for( .@i = 0; .@i < .@item_size; .@i++ ){
    .@item_id = getelementofarray( getarg(8),.@i );
    .@quantity = getelementofarray( getarg(9),.@i );
    .@item_type = getiteminfo( .@item_id,2 );
    if( .@check_progress & 4 ){
    .@item_count = countitem( .@item_id );
    if( .@item_count >= .@quantity ){
    .@item_progress++;
    .@temp_color$ = "44EE99";
    }else{
    .@temp_color$ = "FF0000";
    }
    }
    mes " ^777777"+.@quantity+" x "+getitemname( .@item_id )+" "+( ( .@item_type == 4 || .@item_type == 5 )?"["+getitemslots( .@item_id )+"]":"" )+"  "+( ( .@check_progress & 4 )?"^"+.@temp_color$+"(have "+.@item_count+")":"" )+"^000000";
    }
    mes " ";
    mes "EXP Rewards: ";
    mes "^777777 ~ Base EXP: "+( ( .@baseexp )? .@baseexp:"None" )+"^000000";
    mes "^777777 ~ Job EXP: "+( ( .@jobexp )? .@jobexp:"None" )+"^000000";
    mes " ";
    mes "Item / Zeny Rewards: "+( ( .@reward_size )?"":"^777777Unavailable" )+"^000000";
    mes "^777777  ~ "+( ( .@zeny )? .@zeny+" Zeny":"  ~ No Zeny Reward" )+"^000000";
    if( .@reward_size )
    for( .@i = 0; .@i < .@reward_size; .@i++ ){
    .@item_id = getelementofarray( getarg(16),.@i );
    .@item_type = getiteminfo( .@item_id,2 );
    mes " ^777777 ~ "+getelementofarray( getarg(17),.@i )+" x "+getitemname( .@item_id )+" "+( ( .@item_type == 4 || .@item_type == 5 )?"["+getitemslots( .@item_id )+"]":"" )+"^000000";
    }
    mes " ";
     
    if( .@time_update$ != "0000-00-00 00:00:00" && .@time_update$ != "" ){
    mes "Last Mission Update:";
    mes "^777777"+.@time_update$+"^000000";
    }
     
    if( .@check_progress ){
    if( .@check_progress & 1 && !.@lv_progress ){
    dispbottom "[Failed] Your level didnt meet the requirements.";
    .@check_result |= 1;
    }
    if( .@check_progress & 2 && .@monster_size != .@monster_progress ){
    dispbottom "[Failed] Your Monsters Hunt didnt meet the requirements.";
    .@check_result |= 2;
    }
    if( .@check_progress & 4 && .@item_size != .@item_progress ){
    dispbottom "[Failed] Your Items collecting didnt meet the requirements.";
    .@check_result |= 4;
    }
    }
    return .@check_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,155,79,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
×
×
  • Create New...