diff --git a/share/locale/english/quest/biolog_system.quest b/share/locale/english/quest/biolog_system.quest new file mode 100644 index 0000000..3a8b518 --- /dev/null +++ b/share/locale/english/quest/biolog_system.quest @@ -0,0 +1,419 @@ +quest biolog_system begin + state start begin + function get_duration() + return 60 * 60 * 24 * 365 * 60 + end + + function get_npc_vnum() + return 20084 + end + + function get_stage_count() + return 9 + end + + function get_stages() + local stages = {} + + stages[1] = { + level = 30, + item_vnum = 30006, + item_count = 10, + drop_pct = 20, + reward_apply = apply.MOV_SPEED, + reward_value = 10, + reward_text = "Movement speed +10", + mobs = { 601, }, + } + + stages[2] = { + level = 40, + item_vnum = 30047, + item_count = 15, + drop_pct = 15, + reward_apply = apply.CAST_SPEED, + reward_value = 10, + reward_text = "Casting speed +10", + mobs = { 731, 732, 733, 734, 735, 736, 737, 701, 702, 703, 704, 705, 706, 707, }, + } + + stages[3] = { + level = 50, + item_vnum = 30015, + item_count = 20, + drop_pct = 12, + reward_apply = apply.DEF_GRADE_BONUS, + reward_value = 60, + reward_text = "Defense +60", + mobs = { 901, 902, 903, 904, 905, 906, 907, }, + } + + stages[4] = { + level = 60, + item_vnum = 30050, + item_count = 20, + drop_pct = 10, + reward_apply = apply.INT, + reward_value = 10, + reward_text = "INT +10", + mobs = { 1101, 1102, 1103, 1104, 1105, 1106, 1107, }, + } + + stages[5] = { + level = 70, + item_vnum = 30165, + item_count = 25, + drop_pct = 10, + reward_apply = apply.STR, + reward_value = 10, + reward_text = "STR +10", + mobs = { 2301, 2302, 2303, 2304, 2305, 2311, 2312, 2313, 2314, 2315, }, + } + + stages[6] = { + level = 80, + item_vnum = 30166, + item_count = 30, + drop_pct = 8, + reward_apply = apply.CRITICAL_PCT, + reward_value = 10, + reward_text = "Critical chance +10%", + mobs = { 1401, 1402, 1403, 1601, 1602, 1603, }, + } + + stages[7] = { + level = 85, + item_vnum = 30167, + item_count = 30, + drop_pct = 6, + reward_apply = apply.PENETRATE_PCT, + reward_value = 10, + reward_text = "Piercing chance +10%", + mobs = { 2311, 2312, 2313, 2314, 2315, }, + } + + stages[8] = { + level = 92, + item_vnum = 30251, + item_count = 40, + drop_pct = 5, + reward_apply = apply.RESIST_MAGIC, + reward_value = 10, + reward_text = "Magic resistance +10%", + mobs = { 1135, 1137, }, + } + + stages[9] = { + level = 94, + item_vnum = 30252, + item_count = 40, + drop_pct = 4, + reward_apply = apply.DEF_GRADE_BONUS, + reward_value = 10, + reward_text = "Defense +10", + mobs = { 2412, 2414, }, + } + + return stages + end + + function get_stage(stage_index) + return biolog_system.get_stages()[stage_index] + end + + function get_completed_stage_count() + local stage = pc.getqf("biolog_stage") + if stage <= 1 then + return 0 + end + + if stage > biolog_system.get_stage_count() then + return biolog_system.get_stage_count() + end + + return stage - 1 + end + + function is_complete() + return pc.getqf("biolog_stage") > biolog_system.get_stage_count() + end + + function ensure_started() + if pc.getqf("biolog_stage") == 0 and pc.get_level() >= biolog_system.get_stage(1).level then + pc.setqf("biolog_stage", 1) + pc.setqf("biolog_submitted", 0) + pc.setqf("biolog_timer", 0) + end + end + + function remove_reward(stage) + affect.remove_collect(stage.reward_apply, stage.reward_value) + end + + function add_reward(stage) + affect.add_collect(stage.reward_apply, stage.reward_value, biolog_system.get_duration()) + end + + function sync_rewards() + local stages = biolog_system.get_stages() + for stage_index = 1, biolog_system.get_stage_count() do + biolog_system.remove_reward(stages[stage_index]) + end + + local completed = biolog_system.get_completed_stage_count() + for stage_index = 1, completed do + biolog_system.add_reward(stages[stage_index]) + end + end + + function get_status_text() + if pc.getqf("biolog_stage") == 0 then + return "Reach level 30 to unlock the first biolog stage." + end + + if biolog_system.is_complete() then + return "All biolog stages are complete." + end + + local stage_index = pc.getqf("biolog_stage") + local stage = biolog_system.get_stage(stage_index) + local submitted = pc.getqf("biolog_submitted") + local remaining = stage.item_count - submitted + local cooldown = pc.getqf("biolog_timer") - get_time() + + if cooldown < 0 then + cooldown = 0 + end + + local text = string.format( + "Stage %d requires %d more x %s. Reward: %s.", + stage_index, + remaining, + item_name(stage.item_vnum), + stage.reward_text + ) + + if cooldown > 0 then + text = text .. string.format(" Cooldown remaining: %d:%02d:%02d.", math.floor(cooldown / 3600), math.floor(cooldown / 60) % 60, cooldown % 60) + end + + return text + end + + function refresh_tracker() + if pc.getqf("biolog_stage") == 0 or biolog_system.is_complete() then + clear_letter() + q.done() + return + end + + local stage_index = pc.getqf("biolog_stage") + local stage = biolog_system.get_stage(stage_index) + local submitted = pc.getqf("biolog_submitted") + local remaining = stage.item_count - submitted + local cooldown = pc.getqf("biolog_timer") - get_time() + + send_letter("Biolog Research") + q.set_title(string.format("Biolog Stage %d", stage_index)) + q.set_counter_name(item_name(stage.item_vnum)) + q.set_counter_value(remaining) + + if cooldown > 0 then + q.set_clock("Cooldown", cooldown) + else + q.set_clock_name("") + end + + q.start() + end + + function can_submit() + if pc.getqf("biolog_stage") == 0 then + return false, "The biolog quest has not unlocked yet." + end + + if biolog_system.is_complete() then + return false, "You already completed all biolog stages." + end + + local stage = biolog_system.get_stage(pc.getqf("biolog_stage")) + if pc.get_level() < stage.level then + return false, string.format("Stage %d unlocks at level %d.", pc.getqf("biolog_stage"), stage.level) + end + + if pc.getqf("biolog_timer") > get_time() then + return false, "The biolog is still analyzing your previous sample." + end + + if pc.count_item(stage.item_vnum) <= 0 then + return false, string.format("You need %s before you can submit.", item_name(stage.item_vnum)) + end + + return true, "" + end + + function complete_stage(stage_index) + local stage = biolog_system.get_stage(stage_index) + + biolog_system.add_reward(stage) + + local next_stage = stage_index + 1 + pc.setqf("biolog_stage", next_stage) + pc.setqf("biolog_submitted", 0) + pc.setqf("biolog_timer", 0) + + say_title("Biolog Research") + say(string.format("Stage %d is complete.", stage_index)) + say_reward(stage.reward_text) + + if next_stage > biolog_system.get_stage_count() then + say("") + say("You completed every biolog stage.") + else + local next_data = biolog_system.get_stage(next_stage) + say("") + say(string.format("Stage %d unlocks at level %d and needs %d x %s.", + next_stage, + next_data.level, + next_data.item_count, + item_name(next_data.item_vnum))) + end + end + + function submit_sample() + local can_submit, reason = biolog_system.can_submit() + if not can_submit then + say_title("Biolog Research") + say(reason) + return false + end + + local stage_index = pc.getqf("biolog_stage") + local stage = biolog_system.get_stage(stage_index) + + pc.remove_item(stage.item_vnum, 1) + pc.setqf("biolog_submitted", pc.getqf("biolog_submitted") + 1) + + if not is_test_server() then + pc.setqf("biolog_timer", get_time() + 60 * 60 * 22) + else + pc.setqf("biolog_timer", 0) + end + + local submitted = pc.getqf("biolog_submitted") + if submitted >= stage.item_count then + biolog_system.complete_stage(stage_index) + else + say_title("Biolog Research") + say(string.format( + "Sample accepted. Progress: %d / %d.", + submitted, + stage.item_count + )) + + if pc.getqf("biolog_timer") > get_time() then + local cooldown = pc.getqf("biolog_timer") - get_time() + say(string.format("Next sample in %d:%02d:%02d.", math.floor(cooldown / 3600), math.floor(cooldown / 60) % 60, cooldown % 60)) + end + end + + biolog_system.refresh_tracker() + return true + end + + function is_target_mob(stage_index, race) + local stage = biolog_system.get_stage(stage_index) + if not stage then + return false + end + + for _, mob_vnum in ipairs(stage.mobs) do + if mob_vnum == race then + return true + end + end + + return false + end + + function give_drop() + if pc.getqf("biolog_stage") == 0 or biolog_system.is_complete() then + return + end + + local stage_index = pc.getqf("biolog_stage") + local stage = biolog_system.get_stage(stage_index) + + if pc.get_level() < stage.level then + return + end + + local progress = pc.getqf("biolog_submitted") + pc.count_item(stage.item_vnum) + if progress >= stage.item_count then + return + end + + if is_test_server() or number(1, 100) <= stage.drop_pct then + pc.give_item2(stage.item_vnum, 1) + end + end + + when login or enter or levelup begin + biolog_system.ensure_started() + biolog_system.sync_rewards() + biolog_system.refresh_tracker() + end + + when letter begin + biolog_system.refresh_tracker() + end + + when button or info begin + say_title("Biolog Research") + say(biolog_system.get_status_text()) + say("") + + if not biolog_system.is_complete() then + local stage = biolog_system.get_stage(pc.getqf("biolog_stage")) + say_item_vnum(stage.item_vnum) + say_reward(string.format("Submitted: %d / %d", pc.getqf("biolog_submitted"), stage.item_count)) + end + end + + when 20084.chat."Biolog Research" begin + say_title("Biolog Research") + say(biolog_system.get_status_text()) + say("") + + if not biolog_system.is_complete() and pc.getqf("biolog_stage") > 0 then + local stage = biolog_system.get_stage(pc.getqf("biolog_stage")) + say_item_vnum(stage.item_vnum) + say_reward(string.format("Submitted: %d / %d", pc.getqf("biolog_submitted"), stage.item_count)) + say_reward(string.format("Inventory: %d x %s", pc.count_item(stage.item_vnum), item_name(stage.item_vnum))) + say("") + + local submit = select("Submit sample", "Close") + if submit == 1 then + biolog_system.submit_sample() + end + end + end + + when 20084.chat."GM: Skip biolog cooldown" with pc.is_gm() begin + pc.setqf("biolog_timer", 0) + say_title("Biolog Research") + say("Cooldown cleared.") + biolog_system.refresh_tracker() + end + + when kill begin + if pc.getqf("biolog_stage") == 0 or biolog_system.is_complete() then + return + end + + if biolog_system.is_target_mob(pc.getqf("biolog_stage"), npc.get_race()) then + biolog_system.give_drop() + end + end + end +end diff --git a/share/locale/english/quest/locale_list b/share/locale/english/quest/locale_list index 2707846..71a8c86 100644 --- a/share/locale/english/quest/locale_list +++ b/share/locale/english/quest/locale_list @@ -37,7 +37,6 @@ dragon_lair.quest ride_mount_change.quest ride.quest heavens_cave_escape.quest -check_collect_reward.quest heavens_cave_keyquest.quest arena_manager.quest blacksmith.quest @@ -53,16 +52,7 @@ collect_herb_lv20.quest collect_herb_lv25.quest collect_herb_lv4.quest collect_herb_lv7.quest -collect_quest_lv30.quest -collect_quest_lv40.quest -collect_quest_lv50.quest -collect_quest_lv60.quest -collect_quest_lv70.quest -collect_quest_lv80.quest -collect_quest_lv85.quest -collect_quest_lv90.quest -collect_quest_lv92.quest -collect_quest_lv94.quest +biolog_system.quest couple_ring.quest cube.quest deviltower_zone.quest