Jump to content

Help write simple Doungeon quest (UNIVERSAL)


Go to solution Solved by caanmasu,

Recommended Posts

If someone have nothing to do and want to help me:

I need a dungeon quest ( universal ) to use for multiple dungeons (Beran / Nemere / Razador / Alastor ...)

# I want dungeon to work for single player and party group

# I want to use regen files ( mob.txt / metin.txt / boss.txt )

# Need 30 minutes to complete dungeon, after this time warp all in town.

# Need 3 levels: - 1) Kill all mobs (ex: 5 mobs )

                            - 2) Kill all metin stones (ex: 3mobs )

                            - 3) Kill boss

# After dungeon is done i need a cooldown (ex: 10 minutes)

 

I maked something similar with a dungeon quest + chatgpt and some help from camillo but im not sure is good enought:

I have this error ( 

Save: quest::PC::Save : cannot find . in FlagMap

) with this quest and d.notice is not showing...:

quest DragonLair_dungeon begin
	state start begin
        when 20090.chat."Dungeon RUN 3 -0" with pc.get_map_index() == 73 begin
            if pc.get_level() < 75 then
                say_title("DR:")
                say("[ENTER]Nivelul tau este prea scazut")
            elseif pc.get_level() > 127 then
                say_title("DR:")
                say("[ENTER]Nivelul tau este prea mare")
--[Camilo's code]
			elseif pc.getqf("last_exit_time") > get_time() then 
				say_title("DR:")
				local wait_time = pc.getqf("last_exit_time")-get_time()
				say(string.format("Wait time:%s", get_time_format(wait_time)))
			elseif party.is_in_dungeon() then
				say_title("DR:")
				say("Party is in dungeon now")
			elseif not party.is_map_member_flag_lt("last_exit_time" , get_time()) then
				say_title("DR:")
				say("Someone has to wait cooltime")
			else
				if party.is_party() then
					if party.is_leader() then
						d.new_jump_party(150, 8435, 10668) --no 00
						DragonLair_dungeon.createDungeon() --new line
					else
						say("You are not leader group")
					end
					else
						d.new_jump(150, 843500, 1066800)-- Teleport pe harta ( Dungeon Map )
						DragonLair_dungeon.createDungeon() --new line
					end
--[Camilo's code]
				server_timer("timelimit_dungeon_exit", 300, d.get_map_index()) -- Seteaza un timer de 1 minut pentru a termina temnita    
			end
		end	

--[STAGE 1] Inceput


		when login or enter with DragonLair_dungeon.isInDungeon(150) begin-- Când jucatorul se conecteaza ?i se afla pe indexul har?ii temni?ei
			d.set_warp_location(73, 2418, 12750)--Se seteaza locatia
		end

		when 8031.kill or 8032.kill or 8033.kill or 8034.kill with d.getf("DragonLair_stage01") == 1 begin-- Declan?atorul de ucidere a fost interogat cu semnalizarea misiunii
			local count = d.getf("kill_counter01") -1-- Variabila setata sa numere ?i scazând -1 din a treia
			d.setf("kill_counter01", count)-- Questflag pentru numarare pe misiune
			if count >= 1 then-- Întreba?i daca valoarea numarului este mai mare decât 1
				d.notice("Ramas: "..count.."")-- Ie?ire text calculata cu valoarea curenta -1
			elseif count == 0 then-- este contorul 0
				d.notice("Sarcina 1 finalizata.")-- Ie?ire ca a?i finalizat nivelul
				d.setf("DragonLair_stage02", 1)--Indicatorul de cautare nivelul 2 setat pentru interogare
				d.setf("kill_counter02", 1)--Contor setat cu valoarea 100
				d.regen_file("data/dungeon/dragon_lair/boss.txt")--Regenfile [STAGE 2]
			end
		end
--[STAGE 1] Sfarsit

-- [STAGE 2] Inceput
		when 2493.kill with d.getf("DragonLair_stage02") == 1 begin
			local count = d.getf("DragonLair_stage02") -1
			d.setf("kill_counter02", count)
			if count >= 1 then
				d.notice("Ramas: "..count.."")
			elseif count == 0 then
				d.notice("Sarcina 2 finalizata.")
				server_timer("end_dungeon_exit", 20 , d.get_map_index())--Cateva secunde pentru iesire
			end
			
			d.setqf("last_exit_time" , get_time()+60*10) --[Camilo's code] 10 minutes
			
		end
--[STAGE 2] Sfarsit



-- Functie terminare limita de timp dungeon
		when timelimit_dungeon_exit.server_timer begin
			if d.select(get_server_timer_arg()) then
				DragonLair_dungeon.clearDungeon()
				d.exit_all()
			end
		end

-- Functie iesire terminare dungeon
		when end_dungeon_exit.server_timer begin
			if d.select(get_server_timer_arg()) then
				DragonLair_dungeon.clearDungeon()
				d.exit_all()
			end
		end

-- Verificare de securitate la deconectare
		when logout begin
			d.set_warp_location(73, 2418, 12750)
			if DragonLair_dungeon.isInDungeon() then
				DragonLair_dungeon.clearDungeon()
			end
			
		end

	end

-- FUNCTIONS BEGIN
	state __FUNCTIONS__ begin
		function isInDungeon()
			return pc.get_map_index() >= (150 * 10000) and pc.get_map_index() < ((150+1) * 10000)-- Calculul indexului har?ii pentru interogarea de securitate
		end
		
		function clearDungeon()
			d.setf("DragonLair_stage01", 0)
			d.setf("DragonLair_stage02", 0)
			d.kill_all()
			d.clear_regen()
			d.clear_regen()
			clear_server_timer("end_dungeon_exit", get_server_timer_arg())
		end
		
		

		function createDungeon()
			d.regen_file("data/dungeon/dragon_lair/metins.txt")--Regenfile [STAGE 1]
			d.notice("Distruge toate pietrele de metin.")-- Text
			d.setf("DragonLair_stage01", 1)--Setul de nivel 1 pentru interogare
			d.setf("kill_counter01", 4)--Contor setat cu valoarea 3
		end
		
		
		
	end
-- FUNCTIONS END

end--Quest

 

Link to comment
Share on other sites

  • Replies 1
  • Created
  • Last Reply

Top Posters In This Topic

Popular Days

Top Posters In This Topic

  • Solution

Check UniversalDung_LIB.data and configure it
Make a file data/dungeon/universaldung/regen.txt, etc.

It is the first time that I use this way of programming, I hope it is understood.

UniversalDung_LIB.lua

UniversalDung_LIB = {}

UniversalDung_LIB.data = {
	map_index_in = 43, --map dungeon index
	map_index_out = {41, {9696, 2784}}, --index and cords (global) from where you enter the dung
	base_cord = {8192, 2048}, --dung map base global coordinates (Setting.txt)
	need_level = {100, 120}, --minimum and maximum level to enter
	need_item = {27001, 1}, --object and count to enter. Comment: deactivate
	wait_time_exit = 60, --time for me to get you out of the dung when I finish it
	wait_duration = 60*10, --waiting time to re-enter
	maxlife_dungeon = 60*30, --max duration dung
	
	floors = {
		[1] = {
			jump_cord = {872, 166},
			regen_path = {
				{"data/dungeon/universaldung/regen.txt", false}, --2° param is set_regen_file = true, regen_file = false
			}
		},
		[2] = {
			jump_cord = {370, 833},
			regen_path = {
				{"data/dungeon/universaldung/stone.txt", false},
			}
		},
		[3] = {
			jump_cord = {507, 859},
			regen_path = {
				{"data/dungeon/universaldung/boss.txt", false},
				{"data/dungeon/universaldung/regen.txt", true},
			},
			boss_vnum = 591,
		},
	}
}

UniversalDung_LIB.checkEnter = function()
	local data = UniversalDung_LIB.data
	if party.is_party() then
		local t_need_level, b_need_level = {}, true
		local t_need_item, b_need_item = {}, true
		
		for _, pid in ipairs({party.get_member_pids()}) do
			q.begin_other_pc_block(pid)
				if pc.level < data.need_level[1] or pc.level > data.need_level[2] then
					table.insert(t_need_level, pc.get_name())
					b_need_level = false
				end
				if data.need_item then
					if pc.count_item(data.need_item[1]) < data.need_item[2] then
						table.insert(t_need_item, pc.get_name())
						b_need_item = false
					end
				end
			q.end_other_pc_block()
		end

		if not party.is_leader() then
			say("You must be the leader of the group.")
			return false
		elseif party.is_in_dungeon() then
			say("Your party has already entered the dungeon. ")
			return false
		elseif not party.is_map_member_flag_lt("last_exit_time", get_time()-data.wait_duration) then
			say_reward("There are some members of the group[ENTER] who still have to wait.")
			return false
		elseif party.get_near_count() != table.getn({party.get_member_pids()}) then
			say_reward("All group members must be meet.")
			party.chat("All group members must be meet..")
			return false
		end
		
		if not b_need_level then
			say(string.format("These players do not meet the[ENTER]level (%s-%s)", data.need_level[1], data.need_level[2]))
			for _, name in next, t_need_level, nil do
				say(string.format("-> %s", name))
			end
			return false
		end
		if data.need_item then
			if not b_need_item then
				say(string.format("These players haven't item[ENTER]x%s %s", item_name(data.need_item[1]), data.need_item[2]))
				for _, name in next, t_need_item, nil do
					say(string.format("-> %s", name))
				end
				return false
			end
		end
	else
		if pc.level > data.need_level[2] or pc.level < data.need_level[1] then
			say(string.format("You do not meet the level (%s-%s)", data.need_level[1], data.need_level[2]))
			return false
		end
		if data.need_item then
			if pc.count_item(data.need_item[1]) < data.need_item[2] then
				say(string.format("You don't have x%s %s", data.need_item[2], item_name(data.need_item[1])))
				return false
			end
		end
	end
	return true
end

UniversalDung_LIB.isInDungeon = function()
	local my_map_index, inside_index = pc.get_map_index(), UniversalDung_LIB.data.map_index_in
	return pc.in_dungeon() and my_map_index >= inside_index*10000 and my_map_index < (inside_index+1)*10000
end

UniversalDung_LIB.isInMapOut = function()
	return pc.get_map_index() == UniversalDung_LIB.data.map_index_out[1]
end

UniversalDung_LIB.createDungeon = function()
	local data = UniversalDung_LIB.data

	local dung_floor = 1

	if party.is_party() then
		if data.need_item then
			local pids = {party.get_member_pids()}
			for i, pid in next, pids, nil do
				q.begin_other_pc_block(pid)
				pc.remove_item(data.need_item[1], data.need_item[2])
				q.end_other_pc_block()
			end
		end
		d.new_jump_party(data.map_index_in, 
			data.base_cord[1]+data.floors[dung_floor].jump_cord[1],
			data.base_cord[2]+data.floors[dung_floor].jump_cord[2]
		)
	else
		d.new_jump(data.map_index_in, 
			(data.base_cord[1]+data.floors[dung_floor].jump_cord[1])*100,
			(data.base_cord[2]+data.floors[dung_floor].jump_cord[2])*100
		)
		if data.need_item then
			pc.remove_item(data.need_item[1], data.need_item[2])
		end
	end

	server_timer("universaldung_exit_time", data.maxlife_dungeon, d.get_map_index())
	server_loop_timer("universaldung_main_timer", 5, d.get_map_index())
	d.set_warp_location(data.map_index_out[1], data.map_index_out[2][1], data.map_index_out[2][2])
	d.setf("floor", dung_floor)
	
	UniversalDung_LIB.makeFloor(true) --1° param: first floor (no jump)
	
end

UniversalDung_LIB.makeFloor = function(first_jump)
	d.clear_regen()
	local data = UniversalDung_LIB.data
	local data_floor = data.floors[d.getf("floor")]
	if data_floor then
		if data_floor.regen_path then
			for _, data_regen in ipairs(data_floor.regen_path) do
				if data_regen[2] then
					d.set_regen_file(data_regen[1])
				else
					d.regen_file(data_regen[1])
				end
			end
		end
	else
		d.notice(string.format("You will be teleported in %s seconds.", data.wait_time_exit))
		server_timer("universaldung_exit_time", data.wait_time_exit, d.get_map_index())
	end
	if not first_jump then
		server_timer("universaldung_next_jump", 3, d.get_map_index())
	end
end

UniversalDung_LIB.nextJump = function() --server_timer
	local data = UniversalDung_LIB.data
	local data_floor = data.floors[d.getf("floor")]
	d.jump_all(data.base_cord[1]+data_floor.jump_cord[1], data.base_cord[2]+data_floor.jump_cord[2])
end

UniversalDung_LIB.killProcess = function() --server_timer
	local data = UniversalDung_LIB.data
	local _floor = d.getf("floor")
	local data_floor = data.floors[_floor]
	if _floor == 3 then
		if data_floor.boss_vnum then
			d.clear_regen()
			d.setf("floor", _floor+1)
			UniversalDung_LIB.makeFloor()
		end
	end
end

UniversalDung_LIB.mainProcess = function() --server_loop_timer
	local data = UniversalDung_LIB.data
	local _floor = d.getf("floor")
	local data_floor = data.floors[_floor]
	if d.count_monster() == 0 then
		if _floor == 1 then
			d.setf("floor", _floor+1)
			UniversalDung_LIB.makeFloor()
		elseif _floor == 2 then --same logic than above
			d.setf("floor", _floor+1)
			UniversalDung_LIB.makeFloor()
		end
	end
end

UniversalDung_LIB.checkWaitTime = function()
	local data = UniversalDung_LIB.data
	if get_time()-pc.getf("UniversalDung_zone", "last_exit_time") < data.wait_duration then
		say("You still have to wait to enter.")
		local left_time = pc.getf("UniversalDung_zone","last_exit_time")-get_time()+data.wait_duration
		say_reward(string.format("Time remaining: %s", get_time_remaining(left_time)))
		return false
	end
	return true
end

UniversalDung_LIB.exitDungeon = function()
	local data = UniversalDung_LIB.data
	d.set_warp_location(data.map_index_out[1], data.map_index_out[2][1], data.map_index_out[2][2])
	d.exit_all()
end

UniversalDung_LIB.saveExitTime = function()
	if not pc.is_gm() then
		pc.setqf("last_exit_time", get_time())
	end
end

UniversalDung_LIB.sayDuration = function()
	local data = UniversalDung_LIB.data
	say(string.format("Dungeon duration:[ENTER]%s.", get_time_remaining(data.maxlife_dungeon)))
end


UniversalDung_zone.quest
 

define ENTRY_MAN 20354

quest UniversalDung_zone begin
	state start begin
		when ENTRY_MAN.chat."Universal dung" with UniversalDung_LIB.isInMapOut() begin
			say_title(mob_name(npc.get_race()))

			if not UniversalDung_LIB.checkWaitTime() then
				return
			end
			
			UniversalDung_LIB.sayDuration()

			say("Do you want to enter?")
			if select("Yes", "No") == 2 then
				return
			end
			
			if UniversalDung_LIB.checkEnter() then
				timer("universaldung_make_dungeon", 2)
			end
		end
		
		when universaldung_make_dungeon.timer begin
			UniversalDung_LIB.createDungeon()
		end
		
		when universaldung_exit_time.server_timer begin
			if d.select(get_server_timer_arg()) then
				UniversalDung_LIB.exitDungeon()
			end
		end
		
		when universaldung_main_timer.server_timer begin
			if d.select(get_server_timer_arg()) then
				UniversalDung_LIB.mainProcess()
			end
		end
		
		when universaldung_next_jump.server_timer begin
			if d.select(get_server_timer_arg()) then
				UniversalDung_LIB.nextJump()
			end
		end
		
		when logout with UniversalDung_LIB.isInDungeon() begin
			UniversalDung_LIB.saveExitTime()
		end

		when kill with UniversalDung_LIB.isInDungeon() begin
			UniversalDung_LIB.killProcess()
		end
	end
end

 

Link to comment
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

Announcements



×
×
  • Create New...

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.