--[[
Quest: 40-piętrowa Wieża Demonów (Szablon)
Autor: Tomasz
Opis: Szkielet questu dla wielopiętrowego dungeonu.
--]]
quest demon_tower_40 begin
state start begin
-- VNUM NPC rozpoczynającego dungeon (np. Strażnik Wieży)
when 20090.chat."Wejdź do 40-piętrowej Wieży" begin
-- Podstawowe warunki wejścia
if pc.is_gm() then -- Pozwól GMom testować bez ograniczeń
say_npc("Tryb GM: Omijam sprawdzanie warunków.")
else
-- Sprawdzenie, czy gracz jest liderem grupy
if not party.is_leader() then
say_npc("Tylko lider grupy może rozpocząć wejście.")
return
end
-- Sprawdzenie minimalnego poziomu (np. 75)
if pc.get_level() < 75 then
say_npc("Potrzebujesz co najmniej 75 poziomu, by tu wejść.")
say_npc(string.format("Minimalny poziom dla grupy: %d.", 75)) -- Informacja dla lidera
local members = party.get_near_members()
for i, member_vid in ipairs(members) do
local member = pc.select(member_vid)
if member and member.get_level() < 75 then
say_npc(string.format("Gracz %s ma zbyt niski poziom.", member.get_name()))
end
end
return
end
-- Sprawdzenie, czy wszyscy członkowie są w pobliżu
if party.get_near_count() < party.get_member_count() then
say_npc("Nie wszyscy członkowie grupy są w pobliżu.")
return
end
-- Można dodać inne warunki (np. posiadanie przepustki, cooldown)
-- if pc.count_item(30190) < 1 then -- Przykład: Wymagana przepustka
-- say_npc("Potrzebujesz Przepustki do Wieży.")
-- return
-- end
-- pc.remove_item(30190, 1)
end
say_npc("Dobrze, przygotujcie się na wyzwanie!")
say("Czy na pewno chcesz wejść z grupą do Wieży?")
local s = select("Tak, wchodzimy!", "Nie teraz.")
if s == 2 then
return
end
-- !! WAŻNE: Zmień 210 na indeks mapy Twojego dungeonu !!
local MAP_INDEX = 210
-- Koordynaty wejściowe wewnątrz dungeonu
local start_x = 50 * 100
local start_y = 50 * 100
-- Ustawienie miejsca powrotu po wyjściu/śmierci w dungeonie
-- Użyj d.set_warp_location dla instancji dungeonu
d.set_warp_location(MAP_INDEX, pc.get_map_index(), pc.get_x(), pc.get_y())
-- Przeniesienie całej grupy do dungeonu
party.warp(MAP_INDEX, start_x, start_y)
-- Ustawienie początkowego piętra dla całej grupy (flaga questu)
-- Używamy party.setqf, aby ustawić flagę dla wszystkich członków
party.setqf("pietro", 1)
party.setqf("punkty_za_potwory", 0) -- Można dodać licznik punktów/zabić
-- Można ustawić ogólny timer na cały dungeon
-- party.setqf("limit_czasu", get_time() + 3600) -- Np. 1 godzina
-- Rozpoczęcie logiki dungeonu
-- Przełączenie questu w stan obsługi wnętrza dungeonu
-- UWAGA: set_state działa tylko na graczu klikającym,
-- dlatego logikę startową piętra lepiej umieścić w when MAP_INDEX.enter
say_reward("Przeniesiono grupę do Wieży!")
-- Można wywołać funkcję inicjującą pierwsze piętro dla lidera,
-- ale 'enter' jest pewniejsze dla wszystkich
end
end -- Koniec state start
state inside begin
-- Wyzwalane dla każdego gracza wchodzącego na mapę dungeonu
when 210.enter begin -- !! Użyj indeksu swojej mapy !!
local current_floor = pc.getqf("pietro")
if current_floor == 0 then
-- Gracz nie powinien tu być bez aktywnego questu/piętra
say("Zostałeś wyrzucony z Wieży.")
pc.warp_to_village() -- Lub pc.warp(mapa_wyjscia, x, y)
return
end
-- Informacja o piętrze
notice_multiline(string.format("Witaj na piętrze %d!", current_floor), "", "Przygotuj się na walkę!")
-- Inicjalizacja logiki dla aktualnego piętra
-- Tylko lider grupy powinien inicjować spawny itp., aby uniknąć duplikacji
if party.is_leader() then
-- Sprawdzenie, czy to pierwsze wejście lidera na to piętro (aby uniknąć respawnu po relogu)
if pc.getqf("pietro_zainicjowane") ~= current_floor then -- Użyj ~= dla nierówności
InitializeFloor(current_floor)
pc.setqf("pietro_zainicjowane", current_floor) -- Zaznacz, że lider zainicjował
end
end
end
-- Wyzwalane przy opuszczaniu mapy dungeonu
when 210.leave begin -- !! Użyj indeksu swojej mapy !!
-- Można tu dodać logikę czyszczenia timerów specyficznych dla gracza
-- Flagi qf) są zazwyczaj zapisywane automatycznie
end
-- Wyzwalane przy zabiciu potwora PRZEZ GRUPĘ
-- To jest kluczowe dla dungeonów grupowych
when party_kill begin
local current_floor = pc.getqf("pietro")
local mob_vnum = npc.get_race() -- Pobierz VNUM zabitego potwora
-- --- Logika dla Piętra 1: Zabij wszystkie potwory ---
if current_floor == 1 then
-- Sprawdź, czy na mapie nie ma już potworów z VNUMów dla piętra 1
-- UWAGA: d.count_monster może być niedokładne jeśli są inne potwory
-- Lepszym podejściem jest użycie d.get_mob_count() jeśli na piętrze są TYLKO potwory do zabicia
-- Lub śledzenie zabitych potworów za pomocą flagi/licznika
local monsters_left = d.get_mob_count() -- Sprawdza wszystkie potwory na mapie instancji!
if monsters_left == 0 then
-- Tylko lider powinien wywołać przejście na następne piętro
if party.is_leader() then
CompleteFloor(1)
AdvanceToFloor(2)
end
end
end
-- --- Logika dla Piętra 2: Zabij Bossa ---
-- !! Zmień 2591 na VNUM Bossa Piętra 2 !!
if current_floor == 2 and mob_vnum == 2591 then -- Użyj == do porównania
if party.is_leader() then
CompleteFloor(2)
AdvanceToFloor(3)
end
end
-- --- Logika dla Piętra 3: Zniszcz Kamień Metin ---
-- !! Zmień 8025 na VNUM Metina Piętra 3 !!
if current_floor == 3 and mob_vnum == 8025 then -- Użyj == do porównania
if party.is_leader() then
CompleteFloor(3)
AdvanceToFloor(4)
end
end
-- --- Logika dla Piętra 4: Zbierz Klucze i użyj na Pieczęci ---
-- !! Zmień 1001 na VNUM potwora dającego klucz !!
-- !! Zmień 50001 na VNUM klucza !!
if current_floor == 4 and mob_vnum == 1001 then -- Użyj == do porównania
-- Szansa na drop klucza (np. 50%)
if number(1, 100) <= 50 then
-- Daj klucz członkom grupy w pobliżu potwora
party.give_item_near_vid(npc.get_vid(), 50001, 1)
d.notice_all("Znaleziono Klucz Demona!")
end
end
-- ... Dodaj logikę dla pięter 5-39 ...
-- --- Logika dla Piętra 40: Finałowy Boss ---
-- !! Zmień 2598 na VNUM Finałowego Bossa !!
if current_floor == 40 and mob_vnum == 2598 then -- Użyj == do porównania
if party.is_leader() then
CompleteFloor(40) -- Ukończono ostatnie piętro
-- Nagrody, wiadomość, teleportacja na zewnątrz
d.notice_all("Gratulacje! Pokonaliście Władcę Demonów i oczyściliście Wieżę!")
-- Przykładowe nagrody dla całej grupy
party.give_item2(70057, 4) -- np. 4x Skrzynia Wieży
party.give_exp(5000000) -- np. 10kk EXP
-- Teleportacja grupy na zewnątrz po 15 sekundach
timer("koniec_wiezy_warp", 15)
end
end
end -- Koniec when party_kill
-- --- Logika dla Piętra 4: Użycie Klucza na Pieczęci ---
-- !! Zmień 20091 na VNUM obiektu/NPC Pieczęci !!
-- !! Zmień 50001 na VNUM Klucza !!
when 20091.click begin
local current_floor = pc.getqf("pietro")
if current_floor == 4 then
if pc.count_item(50001) >= 1 then
pc.remove_item(50001, 1)
d.notice_all(string.format("%s użył Klucza Demona i złamał pieczęć!", pc.get_name()))
-- Tylko lider powinien zainicjować przejście
if party.is_leader() then
CompleteFloor(4)
AdvanceToFloor(5)
end
else
say("Potrzebujesz Klucza Demona, aby złamać tę pieczęć.")
end
end
end
-- --- Timer do teleportacji po ukończeniu ---
when timer."koniec_wiezy_warp" begin
-- Resetowanie flag dla grupy przed wyjściem
party.setqf("pietro", 0)
party.setqf("pietro_zainicjowane", 0)
party.setqf("punkty_za_potwory", 0)
-- Wyrzucenie wszystkich z instancji dungeonu
d.exit_all()
-- Quest wraca do stanu 'start' dla graczy
set_state(start)
end
-- --- Funkcje pomocnicze (definiowane wewnątrz questu) ---
-- Funkcja inicjująca dane piętro (wywoływana przez lidera)
function InitializeFloor(floor_num)
d.notice_all(string.format("Rozpoczyna się Piętro %d!", floor_num))
-- Czyszczenie poprzednich potworów/obiektów (opcjonalne, zależy od projektu mapy)
d.purge() -- Usuwa wszystkie NPC/Potwory z mapy instancji
-- Ładowanie spawnu potworów z pliku dla danego piętra
-- Musisz stworzyć pliki regen np. w /usr/game/share/locale/country/quest/object/regen/demon_tower_40/
local regen_file = string.format("regen/demon_tower_40/floor_%d.txt", floor_num)
d.regen_file(regen_file)
-- Alternatywnie, można spawnmobować ręcznie: d.spawn_mob(vnum, x, y, count)
-- Tutaj dodaj logikę specyficzną dla startu piętra:
if floor_num == 1 then
d.notice_all("Cel: Wyeliminuj wszystkie demony na tym piętrze!")
elseif floor_num == 2 then
d.notice_all("Cel: Znajdź i pokonaj Władcę Demonów tego poziomu!")
-- Można dodać specjalne spawny bossa itp.
elseif floor_num == 3 then
d.notice_all("Cel: Zniszcz Kamień Metin Piekieł!")
-- Spawn Metina: d.spawn_mob(8025, 100, 100) -- Przykładowe koordynaty
elseif floor_num == 4 then
d.notice_all("Cel: Zdobądź Klucz Demona pokonując strażników i użyj go na pieczęci!")
-- Spawn pieczęci: d.spawn_mob(20091, 150, 150) -- Przykładowe koordynaty
elseif floor_num == 40 then
d.notice_all("OSTATECZNE WYZWANIE! Pokonaj Władcę Wieży!")
-- Spawn finalnego bossa
end
-- Można uruchomić timer specyficzny dla piętra
-- timer("timer_pietra_"..floor_num, 600) -- Np. 10 minut na piętro
end
-- Funkcja wywoływana po ukończeniu celu piętra (przez lidera)
function CompleteFloor(floor_num)
d.notice_all(string.format("Piętro %d ukończone!", floor_num))
-- Można przyznać małe nagrody za ukończenie piętra
-- party.give_item2(item_vnum, count)
-- party.give_exp(exp_amount)
-- Zatrzymanie timera piętra, jeśli był ustawiony
-- cleartimer("timer_pietra_"..floor_num)
-- Usunięcie pozostałych potworów/obiektów z ukończonego piętra (opcjonalnie)
d.purge()
end
-- Funkcja przechodząca na następne piętro (wywoływana przez lidera)
function AdvanceToFloor(next_floor_num)
d.notice_all(string.format("Przechodzicie na Piętro %d...", next_floor_num))
-- Ustawienie flagi nowego piętra dla całej grupy
party.setqf("pietro", next_floor_num)
-- Można dodać teleportację grupy w inne miejsce mapy, jeśli piętra są w różnych jej częściach
-- local next_x, next_y = GetCoordinatesForFloor(next_floor_num)
-- party.warp(210, next_x, next_y) -- Użyj indeksu swojej mapy
-- Krótka pauza przed inicjalizacją nowego piętra
-- wait(5) -- Czeka 5 sekund (funkcja wait może wymagać specjalnej implementacji lub być niedostępna)
-- Alternatywnie: użyj timera
timer("inicjalizacja_pietra_"..next_floor_num, 5)
end
-- Timery do inicjalizacji pięter (opóźnienie po AdvanceToFloor)
for i = 2, 40 do
when timer."inicjalizacja_pietra_"..i begin
if party.is_leader() and pc.getqf("pietro") == i then
InitializeFloor(i)
pc.setqf("pietro_zainicjowane", i) -- Zaznacz, że lider zainicjował
end
end
end
end -- Koniec state inside
end -- Koniec quest