//============================== //Hunting/Gathering Mission boards //by Derceto \o //============================== //TODO: "Back" button on more menu //TODO: Optimize arrays in ChDelMission //============================================================= //==================== Character variables ==================== //============================================================= //MD_Mission_SlotXX ~ 0 if mission is not taken; 1 if taken //MD_ID_SlotXX ~ Mission ID in slot //MD_MonsterCount_SlotXX ~ Target monster count //============================================================= //==================== Global variables ======================= //============================================================= //$MD_Name$[MissionID] ~ Mission name //$MD_Desc$[MissionID] ~ Mission description //$MD_bExp[MissionID] ~ Mission Base Experience reward //$MD_jExp[MissionID] ~ Mission Job Experience reward //$MD_Monster[MissionID] ~ Mission (Hunting) target monster ID //$MD_MonsterCount[MissionID] ~ Mission (Hunting) target monster count //$MD_Item[MissionID] ~ Mission (Gathering) target item ID //$MD_ItemCount[MissionID] ~ Mission (Gathering) target item count //$MD_Reward[MissionID] ~ Mission reward item ID //$MD_RewardCount[MissionID] ~ Mission reward item count //$MD_MaxLevel[MissionID] ~ Maximal allowed level to accept said mission //$MD_MinLevel[MissionID] ~ Minimal allowed level to accept said mission //$MD_Enabled[MissionID] ~ Set to 0 if mission shouldn't be accessible //$MD_OnPage ~ Number of missions on page //$MD_NPCcount ~ Number of board NPCs (for splitting) //$MD_Slots ~ Maximum number of allowed slots //$MD_GM ~ Minimal GM level to operate mission board //$MD_LevelLimit ~ Maximal level limit of mission board //============================================================= // F_GetMission [Slot] [Mission ID] // Slot: slot for mission function script F_GetMission { setd "MD_Mission_Slot"+getarg(0), 1; setd "MD_ID_Slot"+getarg(0), getarg(1); setd "MD_MonsterCount_Slot"+getarg(0), 0; return; } //============================================================ // F_CompleteMission [Slot] // Returns 1 if mission isn't completed yet; // Otherwise rewards player with his rewards and returns 0 // Returns 2 if player cannot carry stuff, skips mission completion function script F_CompleteMission { set .@mission, getd("MD_ID_Slot"+getarg(0)); if ($MD_Monster[.@mission]) { if (getd("MD_MonsterCount_Slot"+getarg(0)) < $MD_MonsterCount[.@mission]) return 1; } if ($MD_Item[.@mission]) { if (countitem($MD_Item[.@mission]) < $MD_ItemCount[.@mission]) return 1; } if ($MD_Reward[.@mission]) { if (!checkweight($MD_Reward[.@mission],$MD_RewardCount[.@mission])) { return 2; } } if ($MD_Item[.@mission])&&($MD_ItemCount[.@mission]) { delitem $MD_Item[.@mission], $MD_ItemCount[.@mission]; } getexp $MD_bExp[.@mission], $MD_jExp[.@mission]; getitem $MD_Reward[.@mission], $MD_RewardCount[.@mission]; callfunc "F_DropMission", getarg(0); return 0; } //============================================================ //F_MissionTaken [Mission ID] //Returns 1 if user has taken on this mission //Returns 0 if not function script F_MissionTaken { for (set .@i, 0; .@i < $MD_Slots; set .@i, .@i+1) { if (getd("MD_ID_Slot"+.@i) == getarg(0))&&(getd("MD_Mission_Slot"+.@i)) { return 1; } } return 0; } //============================================================ // F_DropMission [Slot] // Deletes a mission from [Slot] function script F_DropMission { setd "MD_Mission_Slot"+getarg(0), 0; setd "MD_ID_Slot"+getarg(0), 0; setd "MD_MonsterCount_Slot"+getarg(0), 0; return; } //============================================================ // F_FreeMissionSlot // Returns free mission slot if there is, or -1 if there is none function script F_FreeMissionSlot { for (set .@i, 0; .@i<$MD_Slots; set .@i, .@i + 1) { if (!getd("MD_Mission_Slot"+.@i)) { return .@i; } } return -1; } //============================================================ // F_ShowMission [Slot] // Shows mission progress on [Slot]. function script F_ShowMission { set .@slot, getarg(0); set .@mission, getd("MD_ID_Slot"+.@slot); mes "Mission name: "; mes "^0000F0"+$MD_Name$[.@mission]+"^000000"; //================== Monster hunt progress ================== if ($MD_Monster[.@mission])&&($MD_MonsterCount[.@mission]) { set .@monstercount, getd("MD_MonsterCount_Slot"+.@slot); mes "Target monster: "+getmonsterinfo($MD_Monster[.@mission],0); if (.@monstercount < $MD_MonsterCount[.@mission]) { mes "Hunted: ^F00000"+.@monstercount+"^000000/"+$MD_MonsterCount[.@mission]; } else mes "Hunted: ^0000F0"+.@monstercount+"^000000/"+$MD_MonsterCount[.@mission]; set .@line$,"[^008000"; set .@maxline, 20; // Actual length of that bar set .@linelen, ((.@maxline*.@monstercount) / $MD_MonsterCount[.@mission]); // Visualisation of progress for (set .@i, 1; .@i <= .@linelen; set .@i, .@i + 1) { set .@line$, .@line$+"="; } set .@line$, .@line$+"^F00000"; for (set .@i, 1; .@i <= .@maxline - .@linelen; set .@i, .@i+1) { set .@line$, .@line$+"+"; } set .@line$, .@line$+"^000000] "+((100*.@monstercount)/$MD_MonsterCount[.@mission])+"%"; mes .@line$; // Finally the line appears } //================== Item gathering progress ================== if ($MD_Item[.@mission])&&($MD_ItemCount[.@mission]) { set .@itemcount, countitem($MD_Item[.@mission]); if (.@itemcount > $MD_ItemCount[.@mission]) { set .@itemcount, $MD_ItemCount[.@mission]; } mes "Required item: "+getitemname($MD_Item[.@mission]); if (.@itemcount < $MD_ItemCount[.@mission]) { mes "Gathered: ^F00000"+.@itemcount+"^000000/"+$MD_ItemCount[.@mission]; } else mes "Gathered: ^0000F0"+.@itemcount+"^000000/"+$MD_ItemCount[.@mission]; set .@line$,"[^008000"; set .@maxline, 20; // Actual length of that second bar set .@linelen, ((.@maxline*.@itemcount) / $MD_ItemCount[.@mission]); // Visualisation of progress again for (set .@i, 1; .@i <= .@linelen; set .@i, .@i + 1) { set .@line$, .@line$+"="; } set .@line$, .@line$+"^F00000"; for (set .@i, 1; .@i <= .@maxline - .@linelen; set .@i, .@i+1) { set .@line$, .@line$+"+"; } set .@line$, .@line$+"^000000] "+((100*.@itemcount)/$MD_ItemCount[.@mission])+"%"; mes .@line$; // Finally the line appears again } //================== Reward info ================== if ($MD_bExp[.@mission])||($MD_jExp[.@mission]) { mes "Reward exp (^F00000base^000000/^008000job^000000):"; mes "^F00000"+$MD_bExp[.@mission]+"^000000/^008000"+$MD_jExp[.@mission]+"^000000"; } if ($MD_Reward[.@mission])&&($MD_RewardCount[.@mission]) { mes "Item reward: "+$MD_RewardCount[.@mission]+"x ^0000F0"+getitemname($MD_Reward[.@mission]); } return; } //============================== // F_DisplayMissionInfo [Mission ID] // Displays info on a mission by mission ID function script F_DisplayMissionInfo { set .@mission, getarg(0); mes "Mission name: "; mes "^0000F0"+$MD_Name$[.@mission]+"^000000"; mes "Description:"; if ($MD_Desc$[.@mission] != "") { mes "^F00000"+$MD_Desc$[.@mission]+"^000000"; } else { mes "^F00000[No description]^000000"; } mes "Level limitation: "+$MD_MinLevel[.@mission]+"-"+$MD_MaxLevel[.@mission]; if ($MD_Monster[.@mission])&&($MD_MonsterCount[.@mission]) { mes "Target monster: "+getmonsterinfo($MD_Monster[.@mission],0); mes "Monsters to hunt: "+$MD_MonsterCount[.@mission]; } if ($MD_Item[.@mission])&&($MD_ItemCount[.@mission]) { mes "Required item: "+getitemname($MD_Item[.@mission]); mes "Items to gather: "+$MD_ItemCount[.@mission]; } if ($MD_bExp[.@mission])||($MD_jExp[.@mission]) { mes "Reward exp (^F00000base^000000/^008000job^000000):"; mes "^F00000"+$MD_bExp[.@mission]+"^000000/^008000"+$MD_jExp[.@mission]+"^000000"; } if ($MD_Reward[.@mission])&&($MD_RewardCount[.@mission]) { mes "Item reward: "; mes $MD_RewardCount[.@mission]+"x ^0000F0"+getitemname($MD_Reward[.@mission])+"^000000"; } if ($MD_Enabled[.@mission]) { mes "The mission is now ^009000enabled^000000."; } else { mes "The mission is now ^F00000disabled^000000."; } return; } //============================================================ // F_ClearArrays // Deletes all missions function script F_ClearArrays { mes .@n$; deletearray $MD_Name$; deletearray $MD_Desc$; deletearray $MD_bExp; deletearray $MD_jExp; deletearray $MD_Monster; deletearray $MD_MonsterCount; deletearray $MD_Item; deletearray $MD_ItemCount; deletearray $MD_Reward; deletearray $MD_RewardCount; deletearray $MD_MaxLevel; deletearray $MD_MinLevel; deletearray $MD_Enabled; mes "Deleted."; next; mes .@n$; mes "Do you want to set them to defaults?"; next; if (select("No:Yes")==2) { set $MD_MissionsChanged, 0; donpcevent "MissionData::OnInit"; } return; } //============================================================ // F_DeleteMission [Mission ID] // Deletes a mission function script F_DeleteMission { set .@mission,getarg(0); set $MD_Name$[.@mission],""; set $MD_Desc$[.@mission],""; set $MD_bExp[.@mission],0; set $MD_jExp[.@mission],0; set $MD_Monster[.@mission],0; set $MD_MonsterCount[.@mission],0; set $MD_Item[.@mission],0; set $MD_ItemCount[.@mission],0; set $MD_Reward[.@mission],0; set $MD_RewardCount[.@mission],0; set $MD_MaxLevel[.@mission],1; set $MD_MinLevel[.@mission],0; set $MD_Enabled[.@mission],0; return; } //============================================================ // F_CompressArrays // Compresses mission arrays after deletion function script F_CompressArrays { set .@size, getarraysize($MD_Name$); for (set .@i, 0; .@i<.@size; set .@i, .@i+1) { set .@size, getarraysize($MD_Name$); if ($MD_Name$[.@i]=="") { for (set .@j,.@i; .@j < .@size-1; set .@j, .@j+1) { set $MD_Name$[.@j], $MD_Name$[.@j+1]; set $MD_Desc$[.@j], $MD_Desc$[.@j+1]; set $MD_bExp[.@j], $MD_bExp[.@j+1]; set $MD_jExp[.@j], $MD_jExp[.@j+1]; set $MD_Monster[.@j], $MD_Monster[.@j+1]; set $MD_MonsterCount[.@j], $MD_MonsterCount[.@j+1]; set $MD_Item[.@j], $MD_Item[.@j+1]; set $MD_ItemCount[.@j], $MD_ItemCount[.@j+1]; set $MD_Reward[.@j], $MD_Reward[.@j+1]; set $MD_RewardCount[.@j], $MD_RewardCount[.@j+1]; set $MD_MaxLevel[.@j], $MD_MaxLevel[.@j+1]; set $MD_MinLevel[.@j], $MD_MinLevel[.@j+1]; set $MD_Enabled[.@j], $MD_Enabled[.@j+1]; } set $MD_Name$[.@j], ""; set $MD_Desc$[.@j], ""; set $MD_bExp[.@j], 0; set $MD_jExp[.@j], 0; set $MD_Monster[.@j], 0; set $MD_MonsterCount[.@j], 0; set $MD_Item[.@j], 0; set $MD_ItemCount[.@j], 0; set $MD_Reward[.@j], 0; set $MD_RewardCount[.@j], 0; set $MD_MaxLevel[.@j], 0; set $MD_MinLevel[.@j], 0; set $MD_Enabled[.@j], 0; } } return; } //============================================================ - script MissionData -1,{ OnInit: if (!$MD_MissionsChanged) { setarray $MD_Name$[0], "Hunting Porings", // Mission 1 "Hunting Fabres", // Mission 2 "Collecting Jellopies", // Mission 3 "Porings Extermination"; // Mission 4 setarray $MD_Desc$[0], "You have to hunt down 10 Porings or world will crash!", // Mission 1 "You have to hunt down 10 Fabres! Hurry!", // Mission 2 "How can you live without jellopies? Get 10 of them, now!", // Mission 3 "Time has come to exterminate porings! Kill 10 of them and get 10 jellopies!"; // Mission 4 setarray $MD_bExp[0], 1000, 2000, 3000, 4000; setarray $MD_jExp[0], 1001, 2001, 3001, 4001; setarray $MD_Reward[0], 909, 909, 909, 909; setarray $MD_RewardCount[0], 11, 12, 13, 14; setarray $MD_MaxLevel[0], 150, 150, 150, 150; setarray $MD_MinLevel[0], 0, 0, 0, 0; setarray $MD_Monster[0],1002, 1007, 0, 1002; setarray $MD_MonsterCount[0], 10, 10, 0, 10; setarray $MD_Item[0], 0, 0, 909, 909; setarray $MD_ItemCount[0], 0, 0, 10, 10; setarray $MD_Enabled[0],1, 1, 1, 1; } set $MD_OnPage, 5; set $MD_Slots, 5; set $MD_GM, 60; set $MD_LevelLimit, 150; } //==================== Hunting trigger ==================== - script MD_HuntingTrigger -1,{ OnNPCKillEvent: for (set .@i, 0; .@i < $MD_Slots; set .@i, .@i + 1) { if (getd("MD_Mission_Slot"+.@i)) { set .@mission, getd("MD_ID_Slot"+.@i); if (killedrid == $MD_Monster[.@mission]) { set .@m, getd("MD_MonsterCount_Slot"+.@i); if (.@m < $MD_MonsterCount[.@mission]) { setd "MD_MonsterCount_Slot"+.@i,.@m+1; announce "["+$MD_Name$[.@mission]+"] "+getmonsterinfo($MD_Monster[.@mission],0)+" hunted: "+(.@m+1)+"/"+$MD_MonsterCount[.@mission],bc_self,0xF000A0; break; } } } } } //==================== Mission Board Function ==================== //MD_MissionBoard(NPC Name$, BoardType{, LevelMin, LevelMax, NPC count, NPC Number}) // //NPC Name$ Name displayed when talking //BoardType 0: AllMissions // 1: Level Limited [Type 1] // 2: Level Limited [Type 2] // 3: Level Limited [Type 3] // 4: Level Limited [Type 1] and divided between number of npc-s // 5: Level Limited [Type 2] and divided between number of npc-s // 6: Level Limited [Type 3] and divided between number of npc-s // 7: Equally Divided (same as type 4,5,6 with Level limit 1-150) // 8: Adjusted to player (displays missions player can take at his current level) // //LevelMin Minimal mission level to be displayed (boardtype 1,2,3,4,5,6) //LevelMax Maximal mission level to be displayed (boardtype 1,2,3,4,5,6) // //~~ Level Limited Type 1: Displays missions which have range fully in specified level range // [That missions can ONLY be taken by users within NPC level range] // //~~ Level Limited Type 2: Displays missions which have range intersecting with the specified // [That missions can possibly be taken by users within NPC level range] // //~~ Level Limited Type 3: Displays missions which contain specified level range in their level restrictions // [That missions can FOR SURE be taken by users within NPC level range] // // Example table, for NPC-s with "LevelMin = 50" and "LevelMax = 100" // // MissionLevelLimit Type1 Type2 Type3 // 10-55 [NO] [YES] [NO] // 55-100 [YES] [YES] [NO] // 40-120 [NO] [YES] [YES] // 10-20 [NO] [NO] [NO] // 50-100 [YES] [YES] [YES] // // //NPC count Number of NPCs to divide missions between (type 4,5,6,7) //NPC number Number of the mission portion that is to be displayed, out of NPC count portions (type 4,5,6,7) function script MD_MissionBoard { set .@n$, getarg(0); set .@size, getarraysize($MD_Name$); set .@type, getarg(1); //=============== Type parse =============== //=============== Level limited types if (.@type > 0)&&(.@type < 7) { set .@LevelLimitMin, getarg(2); set .@LevelLimitMax, getarg(3); //=============== Level limited divided types if (.@type > 3) { set .@NPCcount, getarg(4); set .@NPCnumber, getarg(5); if (!.@NPCcount) { // NPC count = 0 [dividing by zero] exception mes "Invalid number of arguments/data for Missionboard function. Report to Game Master with screenshots."; close; } } } //=============== Divided type if (.@type == 7) { set .@NPCcount, getarg(2); set .@NPCnumber, getarg(3); if (!.@NPCcount) { // NPC count = 0 [dividing by zero] exception mes "Invalid number of arguments/data for Missionboard function. Report to Game Master with screenshots."; close; } } //=============== Other checks if ((!.@size)||($MD_disabled))&&(getgmlevel()<$MD_GM) { mes .@n$; mes "I'm sorry, but I have no missions available for you today."; close; } if (!$MD_OnPage) { mes .@n$; mes "Missionboard page setting is corrupt. Report to Game Master with screenshots."; close; } L_MainMenu: mes .@n$; mes "What would you like to do?"; next; if (getgmlevel()<$MD_GM) { menu "Get mission",L_GetMission, "Submit mission",L_SubmitMission, "See my missions",L_SeeMissions, "Drop mission",L_DropMission, "Nothing",L_Quit; } else { set .@chmission, 0; menu "Get mission",L_GetMission, "Submit mission",L_SubmitMission, "See my missions",L_SeeMissions, "Drop mission",L_DropMission, "Disable/Enable npc",L_EnableTrigger, "Create mission",L_CreateMission, "Change mission",L_ChangeMission, "Delete mission",L_ChDelMission, "Remove all missions",L_ClearArrays, "Nothing",L_Quit; } L_GetMission: set .@slot, callfunc("F_FreeMissionSlot"); set .@size, getarraysize($MD_Name$); next; if (.@slot == -1) { mes .@n$; mes "I'm sorry but you don't have free slots to get another mission. Please free some by deleting or submitting missions in them."; close; } set .@j, 0; set .@skip, 0; deletearray .@MDreference; //Cleanup deletearray .@MDlist$; if (.@type > 3) && (.@type < 8) { // Count number of missions first for divided types for (set .@i, 0; .@i < .@size; set .@i, .@i+1) { if ($MD_Enabled[.@i]) { switch(.@type) { case 1: case 4: if ($MD_MaxLevel[.@i] > .@LevelLimitMax ) || ($MD_MinLevel[.@i] < .@LevelLimitMin) { continue; } break; case 2: case 5: if ($MD_MaxLevel[.@i] < .@LevelLimitMin) || ($MD_MinLevel[.@i] > .@LevelLimitMax) { continue; } break; case 3: case 6: if ($MD_MaxLevel[.@i] < .@LevelLimitMax) || ($MD_MinLevel[.@i] > .@LevelLimitMin) { continue; } break; case 8: if ($MD_MaxLevel[.@i] < BaseLevel) || ($MD_MinLevel[.@i] > BaseLevel) { continue; } break; } set .@j, .@j+1; } } set .@q, .@j; // Quantity of listed missions to be divided between npcs set .@j, 0; // For next loop } for (set .@i, 0; .@i < .@size; set .@i, .@i+1) { if ($MD_Enabled[.@i]) { switch(.@type) { case 1: case 4: if ($MD_MaxLevel[.@i] > .@LevelLimitMax ) || ($MD_MinLevel[.@i] < .@LevelLimitMin) { continue; } break; case 2: case 5: if ($MD_MaxLevel[.@i] < .@LevelLimitMin) || ($MD_MinLevel[.@i] > .@LevelLimitMax) { continue; } break; case 3: case 6: if ($MD_MaxLevel[.@i] < .@LevelLimitMax) || ($MD_MinLevel[.@i] > .@LevelLimitMin) { continue; } break; case 8: if ($MD_MaxLevel[.@i] < BaseLevel) || ($MD_MinLevel[.@i] > BaseLevel) { continue; } break; } set .@skip, .@skip + 1; if (.@type > 3)&&(.@type < 8) { if (.@skip < .@NPCnumber * (.@q/.@NPCcount)) { continue; } if (.@skip >= (.@NPCnumber+1) * (.@q/.@NPCcount)) { continue; } } // Added mission level to the listing name for easier use set .@MDlist$[.@j], $MD_Name$[.@i]+" ^0000C0["+$MD_MinLevel[.@i]+"-"+$MD_MaxLevel[.@i]+"]^000000"; set .@MDreference[.@j], .@i; set .@j, .@j+1; } } set .@page, 0; set .@menusize, getarraysize(.@MDlist$); if (!.@menusize) { mes .@n$; mes "I'm sorry, but I don't have any missions available."; close; } mes .@n$; mes "Please choose a mission:"; goto L_GetMissionMenu; L_GetMissionMenu: //=============== Generate menu list out of available missions =============== set .@menustr$, .@MDlist$[$MD_OnPage*.@page]; set .@menulength, 1; for (set .@i, 0; .@i < $MD_OnPage-1; set .@i, .@i+1) { if ($MD_OnPage*.@page+.@i+1 < .@menusize) { set .@menustr$, .@menustr$+":"+.@MDlist$[$MD_OnPage*.@page+.@i+1]; set .@menulength, .@menulength + 1; } } if (($MD_OnPage*(1+.@page)) < .@menusize) { set .@menustr$, .@menustr$ + ":[Next page]"; set .@menulength, .@menulength + 1; } if (.@page) { set .@menustr$, .@menustr$ + ":[Previous page]"; set .@menulength, .@menulength + 1; } set .@choice, select(.@menustr$); //=============== Next/Previous page references =============== if (($MD_OnPage*(1+.@page)) < .@menusize) && (.@page) { if (.@choice == .@menulength) { set .@page, .@page + 1; goto L_GetMissionMenu; } if (.@choice == .@menulength - 1) { set .@page, .@page - 1; goto L_GetMissionMenu; } } else if (.@page) { if (.@choice == .@menulength) { set .@page, .@page - 1; goto L_GetMissionMenu; } } else if (($MD_OnPage*(1+.@page)) < .@menusize) { if (.@choice == .@menulength) { set .@page, .@page + 1; goto L_GetMissionMenu; } } //=============== Mission was selected; Various checks =============== next; if (callfunc("F_MissionTaken",.@MDreference[.@page*$MD_OnPage+.@choice-1])) { mes .@n$; mes "You have already taken this mission. You should submit it first or choose another mission."; goto L_GetMissionMenu; } if (BaseLevel > $MD_MaxLevel[.@MDreference[.@page*$MD_OnPage+.@choice-1]]) { mes .@n$; mes "Your level is too high to accept this mission."; goto L_GetMissionMenu; } if (BaseLevel < $MD_MinLevel[.@MDreference[.@page*$MD_OnPage+.@choice-1]]) { mes .@n$; mes "Your level is too low to accept this mission."; goto L_GetMissionMenu; } //=============== Misson info display and prompt =============== mes .@n$; callfunc "F_DisplayMissionInfo", .@MDreference[.@page*$MD_OnPage+.@choice-1]; next; mes .@n$; mes "Do you want to accept this mission? ("+$MD_Name$[.@MDreference[.@page*$MD_OnPage+.@choice-1]]+")"; next; if (select("No:Yes") == 1) { mes .@n$; mes "Do you want to choose another mission then?"; if (select("Yes:No") == 1) goto L_GetMissionMenu; next; goto L_Quit; } mes .@n$; callfunc "F_GetMission",.@slot,.@MDreference[.@page*$MD_OnPage+.@choice-1]; mes "You have successfully received a mission. Good luck!"; close; L_SeeMissions: set .@j,0; for (set .@i, 0; .@i<$MD_Slots; set .@i, .@i+1) { set .@mission, getd("MD_Mission_Slot"+.@i); if(.@mission) { mes .@n$; mes "Slot: "+(.@i+1); callfunc "F_ShowMission",.@i; set .@j, .@j+1; next; } } if (!.@j) { mes .@n$; mes "You didn't accept any missions yet."; next; goto L_MainMenu; } goto L_MainMenu; L_DropMission: mes .@n$; set .@menustr$, ""; deletearray(.@MDreference); set .@j, 0; for (set .@i, 0; .@i<$MD_Slots; set .@i, .@i+1) { set .@mission, getd("MD_Mission_Slot"+.@i); if (.@mission) { mes "Slot "+(.@i+1)+": "+$MD_Name$[getd("MD_ID_Slot"+.@i)]; set .@menustr$, .@menustr$ + "Slot "+ (.@i+1)+":"; set .@MDreference[.@j], .@i; set .@j, .@j+1; } } if (!.@j) { mes "You didn't accept any missions yet."; next; goto L_MainMenu; } set .@menustr$, .@menustr$+"Cancel"; next; set .@choice, select(.@menustr$); if (.@choice == .@j+1) { goto L_MainMenu; } mes .@n$; callfunc "F_ShowMission",.@MDreference[.@choice-1]; next; mes .@n$; mes "Are you sure you want to delete this mission?"; next; if (select("No:Yes") == 1) { goto L_MainMenu; } callfunc "F_DropMission", .@MDreference[.@choice-1]; mes .@n$; mes "Mission successfully deleted."; next; goto L_MainMenu; L_SubmitMission: mes .@n$; set .@menustr$, ""; deletearray(.@MDreference); set .@j, 0; for (set .@i, 0; .@i<$MD_Slots; set .@i, .@i+1) { set .@mission, getd("MD_Mission_Slot"+.@i); if (.@mission) { mes "Slot "+(.@i+1)+":"+$MD_Name$[getd("MD_ID_Slot"+.@i)]; set .@menustr$, .@menustr$ + "Slot "+ (.@i+1)+":"; set .@MDreference[.@j], .@i; set .@j, .@j+1; } } if (!.@j) { mes "You didn't accept any missions yet."; next; goto L_MainMenu; } set .@menustr$, .@menustr$+"Cancel"; next; set .@choice, select(.@menustr$); if (.@choice == .@j+1) { goto L_MainMenu; } mes .@n$; callfunc "F_ShowMission",.@MDreference[.@choice-1]; next; mes .@n$; mes "Do you want to sumbit this mission?"; next; if (select("Yes:No") == 2) { goto L_MainMenu; } switch (callfunc("F_CompleteMission", .@MDreference[.@choice-1])) { case 1: mes .@n$; mes "You didn't complete this mission yet. You can delete it via according menu option."; next; goto L_MainMenu; case 2: mes .@n$; mes "You completed the mission but you can't carry your reward. Please come back after using Kafra Storage."; close; case 0: mes .@n$; mes "Congratulations on completing the mission."; next; goto L_MainMenu; } close; //=============== GM menu starts here =============== L_ClearArrays: mes .@n$; mes "Are you sure you want to remove ALL missions?"; next; if (select("No:Yes") == 1) {goto L_MainMenu;} mes .@n$; mes "Last chance to change your mind. Do you want to delete all missions?"; next; if (select("No, don't delete them:Yes, delete them all") == 1) {goto L_MainMenu;} callfunc "F_ClearArrays"; next; goto L_MainMenu; L_EnableTrigger: mes .@n$; mes "Npc is now "+($MD_disabled?"disabled":"enabled")+"."; next; if (select("Do nothing:"+($MD_disabled?"Enable it":"Disable it")) == 2) { set $MD_disabled, !$MD_disabled; } else {goto L_MainMenu;} mes .@n$; mes "Npc is now "+($MD_disabled?"disabled":"enabled")+"."; next; goto L_MainMenu; L_ChangeMission: set .@chmission, 1; goto L_ChDelMission; L_ChDelMission: mes .@n$; mes "Please choose a mission:"; set .@j, 0; set .@size, getarraysize($MD_Name$); deletearray(.@MDreference); //Cleanup deletearray(.@MDlist$); //=============================== TODO: OPTIMIZE [Change arrays to global ones, because no filtering is done] //P.S. (after 6 months) I honestly forgot what I meant by that ^ for (set .@i, 0; .@i < .@size; set .@i, .@i+1) { set .@MDlist$[.@j], $MD_Name$[.@i]+" ^0000C0["+$MD_MinLevel[.@i]+"-"+$MD_MaxLevel[.@i]+"]^000000"; set .@MDreference[.@j], .@i; set .@j, .@j+1; } set .@page, 0; set .@menusize, getarraysize(.@MDlist$); goto L_ChDelMenu; L_ChDelMenu: //=============== Generate menu list out of available missions =============== set .@menustr$, .@MDlist$[$MD_OnPage*.@page]; set .@menulength, 1; for (set .@i, 0; .@i < $MD_OnPage; set .@i, .@i+1) { if ($MD_OnPage*.@page+.@i+1 < .@menusize) { set .@menustr$, .@menustr$+":"+.@MDlist$[$MD_OnPage*.@page+.@i+1]; set .@menulength, .@menulength + 1; } } if (($MD_OnPage*(1+.@page)) < .@menusize) { set .@menustr$, .@menustr$ + ":[Next page]"; set .@menulength, .@menulength + 1; } if (.@page) { set .@menustr$, .@menustr$ + ":[Previous page]"; set .@menulength, .@menulength + 1; } set .@choice, select(.@menustr$); //=============== Next/Previous page references =============== if (($MD_OnPage*(1+.@page)) < .@menusize) && (.@page) { if (.@choice == .@menulength) { set .@page, .@page + 1; goto L_ChDelMenu; } if (.@choice == .@menulength - 1) { set .@page, .@page - 1; goto L_ChDelMenu; } } else if (.@page) { if (.@choice == .@menulength) { set .@page, .@page - 1; goto L_ChDelMenu; } } else if (($MD_OnPage*(1+.@page)) < .@menusize) { if (.@choice == .@menulength) { set .@page, .@page + 1; goto L_ChDelMenu; } } //=============== Misson info display and prompt =============== next; if (.@chmission) { set .@selected, .@MDreference[.@page*$MD_OnPage+.@choice-1]; goto L_ChangeSelected; } mes .@n$; callfunc "F_DisplayMissionInfo", .@MDreference[.@page*$MD_OnPage+.@choice-1]; next; mes .@n$; mes "Are you sure you want to delete this mission? ("+$MD_Name$[.@MDreference[.@page*$MD_OnPage+.@choice-1]]+")"; next; if (select("No:Yes") == 1) { mes .@n$; mes "Do you want to delete another mission then?"; if (select("Yes:No") == 1) goto L_ChDelMenu; next; goto L_Quit; } mes .@n$; callfunc "F_DeleteMission",.@MDreference[.@page*$MD_OnPage+.@choice-1]; callfunc "F_CompressArrays"; set $MD_MissionsChanged, 1; mes "Deleted."; next; goto L_MainMenu; //=============== Mission modification/adding =============== L_CreateMission: mes .@n$; mes "Please enter mission data, click \"Done\" after you're done."; callfunc "F_CompressArrays"; set .@selected, getarraysize($MD_Name$); callfunc "F_DeleteMission",.@selected; set $MD_Name$[.@selected], "Mission #"+(.@selected+1); set $MD_Enabled[.@selected], 1; set $MD_MissionsChanged, 1; next; goto L_ChangeSelected; L_ChangeSelected: mes .@n$; set $MD_MissionsChanged, 1; callfunc "F_DisplayMissionInfo", .@selected; mes "================="; mes "What would you like to change?"; next; menu "Mission name",L_ChName, "Mission description",L_ChDesc, "Mission bExp reward",L_ChBaseExp, "Mission jExp reward",L_ChJobExp, "Mission target monster",L_ChMonster, "Mission monster count",L_ChMonsterCount, "Mission target item",L_ChItem, "Mission item count",L_ChItemCount, "Mission reward item",L_ChReward, "Mission reward count",L_ChRewardCount, "Mission level",L_ChLevel, "Enable/Disable mission",L_ChEnable, "I'm done",L_MainMenu; close; L_ChName: mes .@n$; mes "Current name:"; mes $MD_Name$[.@selected]; mes "Enter new name:"; next; input .@newname$; if (.@newname$ == "") { mes .@n$; mes "You cannot make new name empty. Use \"Delete Mission\" if you want to remove it or \"Disable\" to disable it."; next; goto L_ChangeSelected; } set $MD_Name$[.@selected], .@newname$; goto L_ChangeSelected; L_ChDesc: mes .@n$; mes "Current description:"; if ($MD_Desc$[.@selected] != "") { mes $MD_Desc$[.@selected]; } else { mes "[No description]"; } mes "Enter new description:"; input .@newdesc$; set $MD_Desc$[.@selected], .@newdesc$; next; mes .@n$; mes $MD_Desc$[.@selected]; mes "Add another line?"; next; if (select("No:Yes") == 1) { goto L_ChangeSelected; } input .@newdesc$; set $MD_Desc$[.@selected], $MD_Desc$[.@selected] + .@newdesc$; next; mes .@n$; mes $MD_Desc$[.@selected]; mes "Add another line?"; next; if (select("No:Yes") == 1) { goto L_ChangeSelected; } input .@newdesc$; set $MD_Desc$[.@selected], $MD_Desc$[.@selected] + .@newdesc$; mes .@n$; mes $MD_Desc$[.@selected]; mes "Add another line?"; next; if (select("No:Yes") == 1) { goto L_ChangeSelected; } input .@newdesc$; set $MD_Desc$[.@selected], $MD_Desc$[.@selected] + .@newdesc$; goto L_ChangeSelected; L_ChBaseExp: mes .@n$; mes "Current base exp reward: "+$MD_bExp[.@selected]; mes "Change it to?"; next; input .@newvalue; // Avoid writing corrupt data in global value set $MD_bExp[.@selected], .@newvalue; goto L_ChangeSelected; L_ChJobExp: mes .@n$; mes "Current base exp reward: "+$MD_jExp[.@selected]; mes "Change it to?"; next; input .@newvalue; set $MD_jExp[.@selected], .@newvalue; goto L_ChangeSelected; L_ChMonster: mes .@n$; mes "Current monster: "; if ($MD_Monster[.@selected]) { mes getmonsterinfo($MD_Monster[.@selected],0)+" ["+$MD_Monster[.@selected]+"]"; } else { mes "[None]"; } mes "Input new monster ID or 0 to disable hunting:"; next; input .@newvalue; if (getmonsterinfo(.@newvalue,0) == "null") { mes .@n$; mes "Wrong monster ID."; next; goto L_ChangeSelected; } set $MD_Monster[.@selected], .@newvalue; goto L_ChangeSelected; L_ChMonsterCount: mes .@n$; mes "Current monster count: "+$MD_MonsterCount[.@selected]; mes "Input new value (or 0 to disable hunting):"; next; input .@newvalue; set $MD_MonsterCount[.@selected], .@newvalue; goto L_ChangeSelected; L_ChItem: mes .@n$; mes "Current item: "; if ($MD_Item[.@selected]) { mes getitemname($MD_Item[.@selected])+" ["+$MD_Item[.@selected]+"]"; } else { mes "[None]"; } mes "Input new Item ID or 0 to disable gathering:"; next; input .@newvalue; if (getitemname(.@newvalue) == "null") { mes .@n$; mes "Wrong item ID."; next; goto L_ChangeSelected; } set $MD_Item[.@selected], .@newvalue; goto L_ChangeSelected; L_ChItemCount: mes .@n$; mes "Current item count: "+$MD_ItemCount[.@selected]; mes "Input new value (or 0 to disable gathering):"; next; input .@newvalue; set $MD_ItemCount[.@selected], .@newvalue; goto L_ChangeSelected; L_ChReward: mes .@n$; mes "Current item reward: "; if ($MD_Reward[.@selected]) { mes getitemname($MD_Reward[.@selected])+" ["+$MD_Reward[.@selected]+"]"; } else { mes "[None]"; } mes "Input new Item ID or 0 to disable gathering:"; next; input .@newvalue; if (getitemname(.@newvalue) == "NULL") { mes .@n$; mes "Wrong item ID."; next; goto L_ChangeSelected; } set $MD_Reward[.@selected], .@newvalue; goto L_ChangeSelected; L_ChRewardCount: mes .@n$; mes "Current item count: "+$MD_ItemCount[.@selected]; mes "Input new value (or 0 to disable gathering):"; next; input .@newvalue; set $MD_RewardCount[.@selected], .@newvalue; goto L_ChangeSelected; L_ChLevel: mes .@n$; mes "What should be the ^F00000minimum^000000 Base Level for this mission?"; mes "(Currently: "+$MD_MinLevel[.@selected]+")"; if (input(.@lvlmin,0,$MD_LevelLimit)) { next; mes .@n$; mes "Number you specified is out of range (0-"+$MD_LevelLimit+")."; next; menu "Try again",L_ChLevel, "Cancel",-; goto L_ChangeSelected; } if (.@lvlmin == $MD_LevelLimit) { set .@lvlmax, $MD_LevelLimit; next; goto L_ChLevelFinish; } next; goto L_ChMaxLevel; L_ChMaxLevel: mes .@n$; mes "What should be the ^0000F0maximum^000000 Base Level for this mission?"; mes "(Currently: "+$MD_MaxLevel[.@selected]+")"; if (input(.@lvlmax,1,$MD_LevelLimit)) { next; mes .@n$; mes "Number you specified is out of range (1-"+$MD_LevelLimit+")."; next; menu "Input again",L_ChMaxlevel, "Input minimal level again",L_ChLevel, "Cancel",-; goto L_ChangeSelected; } if (.@lvlmax < .@lvlmin) { next; mes .@n$; mes "Maximal level cannot be less than minimal ("+.@lvlmin+")."; next; menu "Input again",L_ChMaxLevel, "Input minimal level again",L_ChLevel, "Cancel",-; goto L_ChangeSelected; } next; goto L_ChLevelFinish; L_ChLevelFinish: set $MD_MaxLevel[.@selected], .@lvlmax; set $MD_MinLevel[.@selected], .@lvlmin; mes .@n$; mes "Level successfully changed."; next; goto L_ChangeSelected; L_ChEnable: mes .@n$; mes "The mission \""+$MD_Name$[.@selected]+"\" is currently "+($MD_Enabled[.@selected]?"enabled":"disabled")+"."; next; if (select("Do nothing:"+($MD_Enabled[.@selected]?"Disable it":"Enable it")) == 2) { set $MD_Enabled[.@selected], !$MD_Enabled[.@selected]; } else {goto L_ChangeSelected;} mes .@n$; mes "The mission \""+$MD_Name$[.@selected]+"\" is now "+($MD_Enabled[.@selected]?"enabled":"disabled")+"."; next; goto L_ChangeSelected; L_Quit: mes .@n$; mes "See you then."; close; } //============================================================== //============== Mission Boards ================================ //callfunc "MD_MissionBoard",NPC Name$, BoardType{, LevelMin, LevelMax, NPC count, NPC Number}; // //NPC Name$ Name displayed when talking //BoardType 0: AllMissions // 1: Level Limited [Type 1] // 2: Level Limited [Type 2] // 3: Level Limited [Type 3] // 4: Level Limited [Type 1] and divided between number of npc-s // 5: Level Limited [Type 2] and divided between number of npc-s // 6: Level Limited [Type 3] and divided between number of npc-s // 7: Equally Divided (same as type 4,5,6 with Level limit 1-150) // 8: Adjusted to player (displays missions player can take at his current level) //~~ Level Limited Type 1: Displays missions which have range fully in specified level range // [That missions can ONLY be taken by users within NPC level range] // //~~ Level Limited Type 2: Displays missions which have range intersecting with the specified // [That missions can possibly be taken by users within NPC level range] // //~~ Level Limited Type 3: Displays missions which contain specified level range in their level restrictions // [That missions can FOR SURE be taken by users within NPC level range] // EXAMPLES louyang,212,56,4 script All missions#chicken 800,{ callfunc "MD_MissionBoard","[Chickenlolz]",0; end; } louyang,214,56,4 script Level lim 1#chicken 800,{ mes "Min level:"; input .@minlevel; mes "Max level:"; input .@maxlevel; next; callfunc "MD_MissionBoard","[Chickenlolz]",1,.@minlevel,.@maxlevel; end; } louyang,216,56,4 script Level lim 2#chicken 800,{ mes "Min level:"; input .@minlevel; mes "Max level:"; input .@maxlevel; next; callfunc "MD_MissionBoard","[Chickenlolz]",2,.@minlevel,.@maxlevel; end; } louyang,218,56,4 script Level lim 3#chicken 800,{ mes "Min level:"; input .@minlevel; mes "Max level:"; input .@maxlevel; next; callfunc "MD_MissionBoard","[Chickenlolz]",3,.@minlevel,.@maxlevel; end; } louyang,220,56,4 script Level lim 1 div#chicken 800,{ mes "Min level:"; input .@minlevel; mes "Max level:"; input .@maxlevel; mes "Npc count"; input .@npccount; mes "Npc number"; input .@npcnumber; next; callfunc "MD_MissionBoard","[Chickenlolz]",4,.@minlevel,.@maxlevel,.@npccount,.@npcnumber; end; } louyang,222,56,4 script Level lim 2 div#chicken 800,{ mes "Min level:"; input .@minlevel; mes "Max level:"; input .@maxlevel; mes "Npc count"; input .@npccount; mes "Npc number"; input .@npcnumber; callfunc "MD_MissionBoard","[Chickenlolz]",5,.@minlevel,.@maxlevel,.@npccount,.@npcnumber; end; } louyang,224,56,4 script Level lim 3 div#chicken 800,{ mes "Min level:"; input .@minlevel; mes "Max level:"; input .@maxlevel; mes "Npc count"; input .@npccount; mes "Npc number"; input .@npcnumber; next; callfunc "MD_MissionBoard","[Chickenlolz]",6,.@minlevel,.@maxlevel,.@npccount,.@npcnumber; end; } louyang,226,56,4 script Divided#chicken 800,{ mes "Npc count"; input .@npccount; mes "Npc number"; input .@npcnumber; next; callfunc "MD_MissionBoard","[Chickenlolz]",7,.@npccount,.@npcnumber; end; } louyang,228,56,4 script Adj to player#chicken 800,{ callfunc "MD_MissionBoard","[Chickenlolz]",8; end; }