forked from metin-server/m2dev-server
issue-3: add unified biolog quest system
This commit is contained in:
419
share/locale/english/quest/biolog_system.quest
Normal file
419
share/locale/english/quest/biolog_system.quest
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user