-- DEVILTOWER_ENTER_2FLOOR_DIRECTLY
define DIRECT_ENTER_NEEDED_YANG 20000000 -- If players want to enter 2nd Floor directly, must be pay this much Yang for enter. - [MT2Dev Note]
define DIRECT_ENTER_PARTY_NEEDED_YANG 35000000 -- If players want to enter 2nd Floor directly with party, must be pay this much Yang for enter. - [MT2Dev Note]
-- END_OF_DEVILTOWER_ENTER_2FLOOR_DIRECTLY
define MINIMUM_ENTER_LEVEL 40 -- Minimum level for enter the Devil Tower. - [MT2Dev Note]
define TIMER_WAIT_SECONDS 3 -- How much seconds for wait go to the next floor after current floor is completed successfully? - [MT2Dev Note]
define FINAL_WAIT_SECONDS 30 -- How much seconds for wait go out after current 9nd floor is completed successfully? - [MT2Dev Note]
define KILL_COUNT_FOR_DROP_KEY 45 -- In 5th Floor, you need to kill this much mob (1062) for take a drop for item (50084). - [MT2Dev Note]
quest deviltower_zone begin
state start begin
when login begin
-- DEVILTOWER_ENTER_2FLOOR_DIRECTLY
-- Extra level check needed for partys 2nd floor enter. - [MT2Dev Note] - 11/09/2025
if pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 and pc.get_level() < MINIMUM_ENTER_LEVEL then
pc.warp(590500, 110900)
end
-- END_OF_DEVILTOWER_ENTER_2FLOOR_DIRECTLY
if pc.get_map_index() == 66 then
if pc.get_x() < 2136 or pc.get_y() < 7233 or pc.get_x() > 2284 or pc.get_y() > 7393 then
pc.warp(590800, 111200, 65)
else
pc.set_warp_location(65, 5908, 1112)
end
elseif pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 then
pc.set_warp_location(65, 5908, 1112)
end
end
when logout begin
if pc.count_item(30300) >= 1 then
pc.remove_item(30300, pc.count_item(30300))
end
if pc.count_item(30302) >= 1 then
pc.remove_item(30302, pc.count_item(30302))
end
end
-- DEVILTOWER_ENTER_2FLOOR_DIRECTLY
-- INFO: With this new select, players can start Devil Tower with 2.Floor directly, if they have 20M Yang ofc. - [MT2Dev Note] - 10/08/2025
when deviltower_man.chat.mt2dev.deviltower_zone._10_npcChat begin
if pc.get_level() < MINIMUM_ENTER_LEVEL then
say_title(mt2dev.deviltower_zone._20_sayTitle)
say(mt2dev.deviltower_zone._30_say)
else
say_title(mt2dev.deviltower_zone._20_sayTitle)
say(mt2dev.deviltower_zone._40_say)
local s = select(mt2dev.locale.monkey_dungeon.enter, mt2dev.locale.monkey_dungeon.enter_new, mt2dev.locale.monkey_dungeon.enter_new10, mt2dev.locale.monkey_dungeon.no_enter)
if s == 1 then -- Normal Enter. - [MT2Dev Note]
if false == pc.can_warp() then
say(mt2dev.check_trans_ticket._160_say)
else
pc.warp(216500, 727000)
end
elseif s == 2 then -- Enter 2nd Floor Directly (Only Player). - [MT2Dev Note]
if pc.get_money() < DIRECT_ENTER_NEEDED_YANG then
say(mt2dev.locale.monkey_dungeon.say_new)
elseif party.is_party() then
say(mt2dev.locale.monkey_dungeon.say_new10)
elseif false == pc.can_warp() then
say(mt2dev.check_trans_ticket._160_say)
else
pc.change_money(-DIRECT_ENTER_NEEDED_YANG)
d.new_jump(66, special.devil_tower[1][1], special.devil_tower[1][2])
d.regen_file("data/dungeon/deviltower2_regen.txt")
d.set_warp_at_eliminate(4, d.get_map_index(), special.devil_tower[2][1], special.devil_tower[2][2], "data/dungeon/deviltower3_regen.txt")
end--if
elseif s == 3 then -- Enter 2nd Floor Directly (With Party). - [MT2Dev Note]
if pc.get_money() < DIRECT_ENTER_PARTY_NEEDED_YANG then
say(mt2dev.locale.monkey_dungeon.say_new40)
elseif not party.is_party() then
say(mt2dev.locale.monkey_dungeon.say_new20)
elseif not party.is_leader() then
say(mt2dev.locale.monkey_dungeon.say_new30)
elseif false == pc.can_warp() then
say(mt2dev.check_trans_ticket._160_say)
else
pc.change_money(-DIRECT_ENTER_PARTY_NEEDED_YANG)
d.new_jump_party(66, special.devil_tower[1][1], special.devil_tower[1][2])
d.regen_file("data/dungeon/deviltower2_regen.txt")
d.set_warp_at_eliminate(4, d.get_map_index(), special.devil_tower[2][1], special.devil_tower[2][2], "data/dungeon/deviltower3_regen.txt")
end--if
elseif s == 4 then -- Cancel. - [MT2Dev Note]
return
end--s
end--if
end--when
-- END_OF_DEVILTOWER_ENTER_2FLOOR_DIRECTLY
when devil_stone1.kill with pc.get_map_index() == 66 begin -- Set timer only if player kill the metin stone in Devil Tower. - [MT2Dev Note] - 11/09/2025
timer("devil_stone1_1", TIMER_WAIT_SECONDS)
end
when devil_stone1_1.timer begin
d.new_jump_all(66, special.devil_tower[1][1], special.devil_tower[1][2])
d.regen_file("data/dungeon/deviltower2_regen.txt")
d.set_warp_at_eliminate(4, d.get_map_index(), special.devil_tower[2][1], special.devil_tower[2][2], "data/dungeon/deviltower3_regen.txt")
end
when devil_stone3.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
d.set_warp_at_eliminate(4, d.get_map_index(), special.devil_tower[3][1], special.devil_tower[3][2], "data/dungeon/deviltower4_regen.txt")
d.check_eliminated()
end
function get_4floor_stone_pos()
local positions = {
{368, 629},
{419, 630},
{428, 653},
{422, 679},
{395, 689},
{369, 679},
{361, 658},
}
for i = 1, 6 do
local j = number(i, 7)
if i != j then
local t = positions[i]
positions[i] = positions[j]
positions[j] = t
end
end
return positions
end
when 8016.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
d.setf("level", 4)
local positions = deviltower_zone.get_4floor_stone_pos()
for i = 1, 6 do
test_chat(positions[i][1], positions[i][2])
d.set_unique("fake" .. i , d.spawn_mob(8017, positions[i][1], positions[i][2]))
end
test_chat(positions[7][1], positions[7][2])
local vid = d.spawn_mob(8017, positions[7][1], positions[7][2])
test_chat(vid)
d.set_unique("real", vid)
server_loop_timer('devil_stone4_update', 10, pc.get_map_index())
server_timer('devil_stone4_fail1', 5 * 60, pc.get_map_index())
notice_multiline(mt2dev.deviltower_zone._50_dNotice,d.notice)
end
when devil_stone4_fail1.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._60_dNotice,d.notice)
server_timer('devil_stone4_fail2', 5 * 60, get_server_timer_arg())
end
end
when devil_stone4_fail2.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._70_dNotice, d.notice)
server_timer('devil_stone4_fail', 5 * 60, get_server_timer_arg())
end
end
when devil_stone4_fail.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._80_dNotice,d.notice)
d.clear_regen()
d.exit_all()
clear_server_timer('devil_stone4_update', get_server_timer_arg())
end
end
when devil_stone4_update.server_timer begin
if d.select(get_server_timer_arg()) then
if not d.is_unique_dead("real") then
for i = 1, 6 do
if d.getf("fakedead" .. i) == 0 then
if not d.is_unique_dead("fake" .. i) and d.unique_get_hp_perc("fake" .. i) < 50 then -- Fixed. - [MT2Dev Note]
d.purge_unique("fake" .. i)
d.setf("fakedead" .. i, 1)
notice_multiline(mt2dev.deviltower_zone._90_dNotice,d.notice)
end
end
end
else
server_timer("devil_stone4_end", 5, get_server_timer_arg())
--d.kill_all()
d.purge()
notice_multiline(mt2dev.deviltower_zone._100_dNotice,d.notice)
clear_server_timer('devil_stone4_fail1', get_server_timer_arg())
clear_server_timer('devil_stone4_fail2', get_server_timer_arg())
clear_server_timer('devil_stone4_fail', get_server_timer_arg())
end
else
server_timer('devil_stone4_stop_timer', 1, get_server_timer_arg())
end
end
when devil_stone4_stop_timer.server_timer begin
clear_server_timer('devil_stone4_update', get_server_timer_arg())
end
when devil_stone4_end.server_timer begin
if d.select(get_server_timer_arg()) then
clear_server_timer('devil_stone4_update', get_server_timer_arg())
clear_server_timer('devil_stone4_fail1', get_server_timer_arg())
clear_server_timer('devil_stone4_fail2', get_server_timer_arg())
clear_server_timer('devil_stone4_fail', get_server_timer_arg())
-- Clear regen from memory when exit. - [GF Dev Note]
d.clear_regen()
d.setf("level", 5)
d.setf("stone_count", 5)
notice_multiline(mt2dev.deviltower_zone._110_dNotice, d.notice)
d.jump_all(special.devil_tower[4][1], special.devil_tower[4][2])
server_timer('devil_stone5_fail1', 5 * 60, get_server_timer_arg())
clear_server_timer('devil_stone4_update', get_server_timer_arg())
d.set_regen_file("data/dungeon/deviltower5_regen.txt")
d.spawn_mob(20073, 421, 452)
d.spawn_mob(20073, 380, 460)
d.spawn_mob(20073, 428, 414)
d.spawn_mob(20073, 398, 392)
d.spawn_mob(20073, 359, 426)
end
end
when devil_stone5_fail1.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._120_dNotice,d.notice)
server_timer('devil_stone5_fail2', 5 * 60, get_server_timer_arg())
end
end
when devil_stone5_fail2.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._60_dNotice,d.notice)
server_timer('devil_stone5_fail3', 5 * 60, get_server_timer_arg())
end
end
when devil_stone5_fail3.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._70_dNotice,d.notice)
server_timer('devil_stone5_fail', 5 * 60, get_server_timer_arg())
end
end
when devil_stone5_fail.server_timer begin
if d.select(get_server_timer_arg()) then
notice_multiline(mt2dev.deviltower_zone._80_dNotice,d.notice)
d.exit_all()
end
end
when 1062.kill with pc.in_dungeon() and d.getf("level") == 5 begin
local n = d.getf("count") + 1
d.setf("count", n)
if n == KILL_COUNT_FOR_DROP_KEY then
game.drop_item(50084, 1)
d.setf("count", 0)
end
end
when devil_stone5.take with item.vnum == 50084 begin
npc.purge()
item.remove()
d.setf("stone_count", d.getf("stone_count") - 1)
if d.getf("stone_count") <= 0 then
d.setf("level", 6)
d.clear_regen()
d.regen_file("data/dungeon/deviltower6_regen.txt")
notice_multiline(mt2dev.deviltower_zone._130_dNotice,d.notice)
d.jump_all(special.devil_tower[5][1], special.devil_tower[5][2])
local server_arg = d.get_map_index()
clear_server_timer('devil_stone5_fail1', server_arg)
clear_server_timer('devil_stone5_fail2', server_arg)
clear_server_timer('devil_stone5_fail3', server_arg)
clear_server_timer('devil_stone5_fail', server_arg)
else
d.notice(string.format(mt2dev.deviltower_zone._140_dNotice, d.getf("stone_count")))
end
end
when devil_stone6.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 and d.getf("level") == 6 begin
d.kill_all()
notice_multiline(mt2dev.deviltower_zone._150_dNotice, d.notice)
d.check_eliminated()
notice_multiline(mt2dev.deviltower_zone._160_dNotice, d.notice)
local reward_alchemist = {20074, 20075, 20076}
d.spawn_mob(reward_alchemist[number(1, 3)], 425, 216)
d.setqf2("deviltower_zone", "can_refine", 1)
end
when 20074.chat.mt2dev.deviltower_zone._170_npcChat with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 and npc.lock() begin
say_title(mob_name(20074))
say(mt2dev.deviltower_zone._190_say)
wait()
if pc.level >= 75 then
say_title(mob_name(20074))
say(mt2dev.deviltower_zone._200_say)
local s = select(mt2dev.deviltower_zone._210_select, mt2dev.deviltower_zone._220_select, mt2dev.locale.cancel)
if s == 1 then -- Go to the next floor. - [MT2Dev Note]
timer("devil_jump_7", TIMER_WAIT_SECONDS)
npc.unlock()
d.purge()
return
elseif s == 2 then -- Give up and go out. - [MT2Dev Note]
pc.warp(590500, 110900)
return
elseif s == 3 then -- Cancel. - [MT2Dev Note]
return
end
end
say_title(mob_name(20074))
say(mt2dev.deviltower_zone._230_say)
wait()
pc.warp(590500, 110500)
return
end
when 20075.chat.mt2dev.deviltower_zone._170_npcChat with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 and npc.lock() begin
say_title(mob_name(20075))
say(mt2dev.deviltower_zone._190_say)
wait()
if pc.level >= 75 then
say_title(mob_name(20075))
say(mt2dev.deviltower_zone._200_say)
local s = select(mt2dev.deviltower_zone._210_select, mt2dev.deviltower_zone._220_select, mt2dev.locale.cancel)
if s == 1 then -- Go to the next floor. - [MT2Dev Note]
timer("devil_jump_7", TIMER_WAIT_SECONDS)
npc.unlock()
d.purge()
return
elseif s == 2 then -- Give up and go out. - [MT2Dev Note]
pc.warp(590500, 110900)
return
elseif s == 3 then -- Cancel. - [MT2Dev Note]
return
end
end
say_title(mob_name(20075))
say(mt2dev.deviltower_zone._230_say)
wait()
pc.warp(590500, 110500)
return
end
when 20076.chat.mt2dev.deviltower_zone._170_npcChat with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 and npc.lock() begin
say_title(mob_name(20076))
say(mt2dev.deviltower_zone._190_say)
wait()
if pc.level >= 75 then
say_title(mob_name(20076))
say(mt2dev.deviltower_zone._200_say)
local s = select(mt2dev.deviltower_zone._210_select, mt2dev.deviltower_zone._220_select, mt2dev.locale.cancel)
if s == 1 then -- Go to the next floor. - [MT2Dev Note]
timer("devil_jump_7", TIMER_WAIT_SECONDS)
npc.unlock()
d.purge()
return
elseif s == 2 then -- Give up and go out. - [MT2Dev Note]
pc.warp(590500, 110900)
return
elseif s == 3 then -- Cancel. - [MT2Dev Note]
return
end
end
say_title(mob_name(20076))
say(mt2dev.deviltower_zone._230_say)
wait()
pc.warp(590500, 110500)
return
end
when devil_jump_7.timer begin
d.clear_regen()
d.spawn_mob(8018, 639, 658)
d.spawn_mob(8018, 611, 637)
d.spawn_mob(8018, 596, 674)
d.spawn_mob(8018, 629, 670)
d.setf("level", 7)
notice_multiline(mt2dev.deviltower_zone._240_dNotice, d.notice)
d.jump_all(2638, 7294)
end
when 8018.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
local cont = d.getf("7_stone_kill") + 1
d.setf("7_stone_kill", cont)
if cont >= 4 then
d.setf("7_stone_kill", 0)
d.set_regen_file("data/dungeon/deviltower7_regen.txt")
end
end
when 8019.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
-- 7_FLOOR_METIN_LIMITATION
local metin_count = d.getf("7_metin_kill") + 1
d.setf("7_metin_kill", metin_count)
if metin_count >= 150 then
d.setf("7_metin_kill", 0)
d.clear_regen()
d.exit_all()
else
syschat(string.format("%d Metin Left - After that you will be kicked out..", 150 - metin_count))
game.drop_item(30300, 1)
end
-- END_OF_7_FLOOR_METIN_LIMITATION
end
when 30300.use with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
if d.getf("level") != 7 then
pc.remove_item(30300, 1)
return
end
pc.remove_item(30300, 1)
local pct = number(1, 10)
if pct <= 2 then -- %20 Chance. - [MT2Dev Note]
game.drop_item(30302, 1)
d.clear_regen()
else
say(mt2dev.subquest_49._340_say) -- Little "try again" message added instead of nothing.. - [MT2Dev Note] - 11/09/2025
end
end
when 30302.use with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
if d.getf("level") != 7 then
pc.remove_item(30302, 1)
return
end
pc.remove_item(30302, 1)
say_title(mt2dev.blacksmith._40_sayTitle)
say(mt2dev.deviltower_zone._250_say)
-- 7_FLOOR_METIN_LIMITATION
d.setf("7_metin_kill", 0)
-- END_OF_7_FLOOR_METIN_LIMITATION
d.clear_regen()
timer("devil_jump_8", TIMER_WAIT_SECONDS)
end
when devil_jump_8.timer begin
d.setf("level", 8)
notice_multiline(mt2dev.deviltower_zone._260_dNotice,d.notice)
local _count = pc.count_item(30302)
pc.remove_item(30302, _count)
d.jump_all(2638, 7059)
d.set_regen_file("data/dungeon/deviltower8_regen.txt")
d.spawn_mob(20366, 640, 460)
end
when 1040.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
local pct1 = number(1, 3)
if pct1 == 1 then -- %33.3 Chance. - [MT2Dev Note]
local pct2 = number(1, 10)
if pct2 <= 2 then -- %20 Chance. - [MT2Dev Note]
game.drop_item(30304, 1)
else
game.drop_item(30303, 1)
end
else
return
end
end
when 20366.take with item.vnum == 30304 begin
npc.purge()
item.remove()
timer("devil_jump_9", TIMER_WAIT_SECONDS)
end
when devil_jump_9.timer begin
d.setf("level", 9)
notice_multiline(mt2dev.deviltower_zone._270_dNotice, d.notice)
d.jump_all(2638, 6811)
d.regen_file("data/dungeon/deviltower9_regen.txt")
end
when 1093.kill with pc.in_dungeon() and pc.get_map_index() >= 660000 and pc.get_map_index() < 670000 begin
d.kill_all()
d.setqf2("deviltower_zone", "9_done", 1)
notice_multiline(mt2dev.deviltower_zone._280_dNotice, d.notice)
notice_multiline(mt2dev.deviltower_zone._290_dNotice, d.notice)
server_timer("devil_end_jump", FINAL_WAIT_SECONDS, d.get_map_index())
end
when devil_end_jump.server_timer begin
if d.select (get_server_timer_arg()) then
d.clear_regen()
d.exit_all()
end
end
end
end
-- MT2DevCore Project | Modern Base SF by MT2Dev | 2025