Jump to content

Mistique

Members
  • Posts

    53
  • Joined

  • Last visited

Everything posted by Mistique

  1. Thank you so much Functor! ? http://www.mediafire.com/file/2vxo4nfm60eu2t7/TestServer.rar/file
  2. Hi! I've checked this diff in the past and was wondering if there's a way I can un-do it without having to hex a client from scratch? My client has a lot of mods and other custom edits that I don't wish to lose. Any help will be greatly appreciated!
  3. 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. ?
  4. 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? ?
  5. 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?
  6. 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. ?
  7. 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.
  8. 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; }
  9. 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? 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.
  10. 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
  11. Cool! Thanks I will give this a go later today. ? Hi @anacondaq I tried it, but it's returning this error message when compiling: Not declared... but I put it in items.conf like it said in the diff.
  12. Thanks! Yes, the UI aka button cash shop, I am aware of the itemshop but would prefer the button interface. So almost not possible? I've seen servers do it though. ?
  13. Hi everyone. Not quite sure if this belongs into requests or support, but I'm trying to get the cash shop system to accept an item currency rather than regular cash points, let's say item ID 501. Does anyone know how that can be achieved? Thank you very much in advance! ?
  14. Hi @Secrets very awesome script. Thank you for sharing! ? I notice that the jRO costume dress resets upon re-logging while all the other style types don't. Any idea how I might fix it for the jRO costume? I've already set the permanent setting correctly.
  15. 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.
  16. 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; }
  17. Thank you guys! Much appreciated! ?
  18. 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; }
  19. I'm really eager to try that out, but it gives me this error on the map server.
  20. 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
  21. 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.
  22. 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
  23. Yes exactly what I needed! I can't thank you enough for this!
×
×
  • Create New...