• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!
  • New resources must be posted under Resources tab. A discussion thread will be created automatically, you can't open threads manually anymore.

Action Working Demon Oak Quest

91659104.jpg


Code:
ITEM_DEADTREE = 2709
 
HALLOWEDAXE_PRICE = 1000
 
ERROR_NOERROR = 0
ERROR_TREEPOSITION = 1
ERROR_NOTENOUGHLEVEL = 2
ERROR_ALREADYDONE = 3
ERROR_ALREADYCUT = 4
ERROR_WAITFOR = 5
ERROR_UNKNOWN = 6
 
TYPE_PLAYER = 1
TYPE_MONSTER = 2
TYPE_NPC = 3
TYPE_CREATURE = 4
GET_COUNT = 1
GET_UID = 2
 
STORAGE_LIB = 11257
STORAGE_THINK = 11258
 
oneByQuest = true
killAllBeforeCut = true
enableOakThink = true
level = 120
positions =
{
	kick = {x = 32716, y = 32337, z = 7},
	summon =
	{
		{x = 32712, y = 32347, z = 7},
		{x = 32711, y = 32352, z = 7},
		{x = 32717, y = 32354, z = 7},
		{x = 32720, y = 32353, z = 7},
		{x = 32722, y = 32350, z = 7},
		{x = 32718, y = 32347, z = 7},
		{x = 32714, y = 32348, z = 7},
		{x = 32720, y = 32355, z = 7}
	},
	rewardRoom = {x = 32786, y = 32412, z = 8},
	demonOak = {x = 32716, y = 32349, z = 7}
}
 
summons =
{
	[1] = {"Demon", "Grim Reaper", "Elder Beholder", "Demon Skeleton"},
	[2] = {"Dark Torturer", "Banshee", "Betrayed Wraith", "Blightwalker"},
	[3] = {"Bonebeast", "Braindeath", "Diabolic Imp", "Giant Spider"},
	[4] = {"Hand of Cursed Fate", "Lich", "Undead Dragon", "Vampire"},
	[5] = {"Braindeath", "Demon", "Bonebeast", "Diabolic Imp"},
	[6] = {"Demon Skeleton", "Banshee", "Elder Beholder", "Bonebeast"},
	[7] = {"Dark Torturer", "Undead Dragon", "Demon", "Demon"},
	[8] = {"Elder Beholder", "Betrayed Wraith", "Demon Skeleton", "Giant Spider"},
	[9] = {"Demon", "Banshee", "Blightwalker", "Demon Skeleton"},
	[10] = {"Grim Reaper", "Demon", "Diabolic Imp", "Braindeath"},
	[11] = {"Banshee", "Grim Reaper", "Hand of Cursed Fate", "Demon"}
}
 
areaPosition =
{
	{x = 32707, y = 32344, z = 7, stackpos = 255},
	{x = 32727, y = 32357, z = 7, stackpos = 255}
}
 
demonOak = {8288, 8289, 8290, 8291}
 
storages =
{
	done = 35711,
	treeCut = 35719
}
 
blockingTree =
{
	[ITEM_DEADTREE] = {32193, 3614}
}
 
floorDamage =
{
	min = 270,
	max = 310,
	type = COMBAT_EARTHDAMAGE,
	effect = CONST_ME_BIGPLANTS
}
 
rewards =
{
	[12901] = {done = 12900, reward = 2495, count = 1},
	[12902] = {done = 12900, reward = 8905, count = 1},
	[12903] = {done = 12900, reward = 2495, count = 1},
	[12904] = {done = 12900, reward = 8905, count = 1}
}
 
sounds =
{
	[1] =
	{
		"Release me and you will be rewarded greatefully!",
		"What is this? Demon Legs lying here? Someone might have lost them.",
		"I'm trapped, come here and free me fast!!",
		"I can bring your beloved back from the dead, just release me!",
		"What a nice shiny golden armor. Come to me and you can have it!",
		"Find a way in here and release me! Pleeeease hurry!",
		"You can have my demon set, if you help me get out of here!"
	},
	[2] =
	{
		"MY ROOTS ARE SHARP AS A SCYTHE! FEEL IT?!?",
		"CURSE YOU!",
		"RISE, MINIONS, RISE FROM THE DEAD!!!!",
		"AHHHH! YOUR BLOOD MAKES ME STRONG!",
		"GET THE BONES, HELLHOUND! GET THEM!!",
		"GET THERE WHERE I CAN REACH YOU!!!",
		"ETERNAL PAIN AWAITS YOU! NICE REWARD, HUH?!?!",
		"YOU ARE GOING TO PAY FOR EACH HIT WITH DECADES OF TORTURE!!",
		"ARGG! TORTURE IT!! KILL IT SLOWLY MY MINION!!"
	}
}
 
function canEnter(cid, tree)
 
	if isInRange(tree, areaPosition[1], areaPosition[2]) then
		return ERROR_TREEPOSITION
	elseif getPlayerLevel(cid) < level then
		return ERROR_NOTENOUGHLEVEL
	elseif getCreatureStorage(cid, storages.done) > 0 then
		return ERROR_ALREADYDONE
	elseif getCreatureStorage(cid, storages.treeCut) > 0 then
		return ERROR_ALREADYCUT
	elseif oneByQuest then
		local players = getPlayersOnline()
		if getCreaturesInRange(TYPE_PLAYER, areaPosition[1], areaPosition[2], GET_COUNT, false) > 0 then
			return ERROR_WAITFOR
		end
	else
		return ERROR_UNKNOWN
	end
	return ERROR_NOERROR
end
 
 
function getError(data, tree)
	if data == ERROR_TREEPOSITION then
		return print("[Warning - Action::Demon Oak Script] Dead tree position is inside the quest area positions.\nDead tree position: (x: " .. tree.x .. ", y: " .. tree.y .. ", z: " .. tree.z .. ")\nNorth-West area position (x: " .. areaPosition[1].x .. ", y: " .. areaPosition[1].y .. ", z: " .. areaPosition[1].z .. ")\nSouth-West area position (x: " .. areaPosition[2].x .. ", y: " .. areaPosition[2].y .. ", z: " .. areaPosition[2].z .. ")\nScript will not work correctly, please fix it.") and "Something is wrong, please contact a staff member."
	elseif data == ERROR_NOTENOUGHLEVEL then
		return "You need level " .. level .. " or higher to enter to the quest area."
	elseif data == ERROR_ALREADYDONE then
		return "You already done this quest."
	elseif data == ERROR_ALREADYCUT then
		return "You can not leave the quest area by here."
	elseif data == ERROR_WAITFOR then
		return "Wait until the player inside the quest area finish the quest."
	elseif data == ERROR_UNKNOWN then
		return "Sorry, not possible."
	end
	return ""
end
 
function getCreaturesInRange(type, fromPos, toPos, get, countSummon)
 
	local types = 
	{
		[TYPE_PLAYER] = isPlayer,
		[TYPE_MONSTER] = isMonster,
		[TYPE_NPC] = isNpc,
		[TYPE_CREATURE] = isCreature
	}
	local tmp = {}
 
	local t = types[type]
	if(not t) then return print("[Warning - Function::getCreaturesInRange] Unknow type " .. (type or "(nil value)")) end
 
	local thing
	local pos
	for x = fromPos.x, toPos.x do
		for y = fromPos.y, toPos.y do
			for z = fromPos.z, toPos.z do
				pos = {x = x, y = y, z = z}
				thing = getTopCreature(pos)
				if t(thing.uid) then
					if countSummon then
						if isSummon(thing.uid) then
							table.insert(tmp, thing.uid)
						end
					else
						if not isSummon(thing.uid) then
							table.insert(tmp, thing.uid)
						end
					end
				end
			end
		end
	end
	if(get == GET_COUNT) then
		return table.maxn(tmp)
	elseif(get == GET_UID) then
		return tmp
	else
		print("[Warning - Function::getCreaturesInRange] Unknow type to get " .. (get or "(nil value)"))
	end
end
 
function monsterExists(name)
 
	local file = "data/monster/monsters.xml"
	local m_name, getName, getFile, m_file = 0, 0, 0, 0
	local monsterExists, fileExists = false, false
	if io.open(file, "r") ~= nil then
		for line in io.lines(file) do
			if line:find('name=".*".*') and line:find('file=".*".*') then
				getName = string.match(line, 'name=".*".*')
				getFile = string.match(line, 'file=".*".*')
				m_name = string.sub(getName, string.find(getName, '="') + 2, string.find(getName, '" ') - 1)
				m_file = string.sub(getFile, string.find(getFile, '="') + 2, string.find(getFile, '"/') - 1)
				if m_name == name then
					monsterExists = true
					if io.open("data/monster/" .. m_file, "r") ~= nil then
						fileExists = true
					end
				end
			end
		end
	end
	return monsterExists and fileExists or false
end
 
function isSummon(cid)
	return getCreatureMaster(cid) ~= cid or false
end
 
function isLastCut(cid)
	local k, s = 0, 0
	for i = demonOak[1], demonOak[table.maxn(demonOak)] do
		if getCreatureStorage(cid, i) == table.maxn(summons) + 1 then
			k = k + 1
		end
		if getCreatureStorage(cid, i) == table.maxn(summons) then
			s = s + 1
		end
	end
	return (k == 3 and s == 1 and true or false)
end
function checkLib()
	print("\nChecking demon oak lib...")
	local r = 0
	if summons and type(summons) == "table" then
		for k, v in pairs(summons) do
			if v and type(v) == "table" then
				for _, s in ipairs(v) do
					if not monsterExists(s) then
						print("[Warning - Lib::DemonOak] Table: summons, Id: " .. k .. ", Monster " .. s .. " does not exists.")
						r = r + 1
					end
				end
			else
				print("[Warning - Lib::DemonOak] Table: summons, Id: " .. k .. ", cannot load summons (table expected, got " .. (type(v) or "nil") .. ")")
				r = r + 1
			end
		end
	else
		print("[Warning - Lib::DemonOak] Cannot load summons (table expected, got " .. (type(summons) or "nil") .. ")")
		r = r + 1
	end
	if positions and type(positions) == "table" then
		if not positions.kick or type(positions.kick) ~= "table" then
			print("[Warning - Lib::DemonOak] Invalid position for kick (table expected, got " .. (type(positions.kick) or "nil") .. ")")
			r = r + 1
		end
		if positions.summon and type(positions.summon) == "table" then
			for i = 1, table.maxn(positions.summon) do
				if type(positions.summon[i]) ~= "table" then
					print("[Warning - Lib::DemonOak] Invalid summon position on index " .. i .. " (table expected, got " .. (type(positions.summon[i]) or "nil") .. ")")
					r = r + 1
				end
			end
		else
			print("[Warning - Lib::DemonOak] Cannot load summons position (table expected, got " .. (type(positions.summon) or "nil") .. ")")
			r = r + 1
		end
		if not positions.rewardRoom or type(positions.rewardRoom) ~= "table" then
			print("[Warning - Lib::DemonOak] Invalid position for reward room (table expected, got " .. (type(positions.rewardRoom) or "nil") .. ")")
			r = r + 1
		end
		if not positions.demonOak or type(positions.demonOak) ~= "table" then
			print("[Warning - Lib::DemonOak] Cannot load demonOak position, scripts will use player position.")
			r = r + 1
		end
	else
		print("[Warning - Lib::DemonOak] Cannot load positions (table expected, got " .. (positions and type(positions) or "nil") .. ")")
		r = r + 1
	end
	if not areaPosition or not areaPosition[1] or type(areaPosition[1]) ~= "table" or not areaPosition[2] or type(areaPosition[2]) ~= "table" then
		print("[Warning - Lib::DemonOak] Invalid area positions!")
		r = r + 1
	end
	if not demonOak or type(demonOak) ~= "table" then
		print("[Warning - Lib::DemonOak] Cannot load 'demonOak' ids (table expected, got " .. (type(demonOak) or "nil") .. ")")
		demonOak = {8288, 8289, 8290, 8291}
		r = r + 1
	end
	if storages and storages.done == storages.treeCut then 
		print("[Warning - Lib::Demon Oak] Storage for dead tree (" .. storages.cutTree .. ") and storage to check if demonOak is finished (" .. storages.done .. ") are the same, change it or script will not work correctly.")
		r = r + 1
	end
	if blockingTree and type(blockingTree) == "table" then
		for k, v in pairs(blockingTree) do
			if type(v) ~= "table" then
				print("[Warning - Lib::DemonOak] Cannot load info about dead tree id: " .. k .. " (table expected, got " .. (type(v) or "nil") .. ")")
				r = r + 1
			end
		end
	else
		print("[Warning - Lib::DemonOak] Cannot load info about dead tree (table expected, got " .. (type(blockingTree) or "nil") .. ")")
		r = r + 1
	end
	if rewards and type(rewards) == "table" then
		for k, v in pairs(rewards) do
			if type(v) ~= "table" or not v.done or not v.reward or not v.count then
				print("[Warning - Lib::DemonOak] Cannot load reward id " .. k .. "!")
				r = r + 1
			end
		end
	else
		print("[Warning - Lib::DemonOak] Cannot load rewards (table expected, got " .. (type(rewards) or "nil") .. ")")
		r = r + 1
	end
	if sounds and type(sounds) == "table" then
		for k, v in pairs(sounds) do
			if type(v) ~= "table" then
				print("[Warning - Lib::DemonOak] Cannot load sounds on index " .. k .. " (table expected, got " .. (type(v) or "nil") .. ")")
				r = r + 1
			end
		end
	else
		print("[Warning - Lib::DemonOak] Cannot load sounds (table expected, got " .. (type(sounds) or "nil") .. ")")
		r = r + 1
	end
	print("...done, " .. r .. " problems loaded.\n")
end
 
if getStorage(STORAGE_LIB) < 1 then
	checkLib()
	doSetStorage(STORAGE_LIB, 1)
end
 
function demonOakThink()
 
	local thinkTime = 10000
	if math.random(10) <= 3 then
		if positions and positions.demonOak and type(positions.demonOak) == "table" and areaPosition[1] and type(areaPosition[1]) == "table" and areaPosition[2] and type(areaPosition[2]) == "table" then
			local rangeX, rangeY = getDistanceBetween(positions.demonOak, areaPosition[1]) + 3, getDistanceBetween(positions.demonOak, areaPosition[2]) + 3
			local list = getSpectators(positions.demonOak, rangeX, rangeY)
			for _, uid in ipairs(list) do
				if isPlayer(uid) and not isInArea(getCreaturePosition(uid), areaPosition[1], areaPosition[2]) and getCreaturesInRange(TYPE_PLAYER, areaPosition[1], areaPosition[2], GET_COUNT, false) == 0 then
					doCreatureSay(uid, sounds[1][math.random(table.maxn(sounds[1]))], TALKTYPE_MONSTER_YELL, false, uid, positions.demonOak)
				end
			end
		end
	end
 
	addEvent(demonOakThink, thinkTime)
end
 
if getStorage(STORAGE_THINK) < 1 and enableOakThink then
	demonOakThink()
	doSetStorage(STORAGE_THINK, 1)
end

or



sorry Dark for my problem but i realy don't know why don't work ;(
 
Last edited:
That happens every time you start the server? are you sure that my script are what are closing your server?
 
[17/02/2011 04:13:02] [Warning - Action::Demon Oak Script] Dead tree position is inside the quest area positions.
[17/02/2011 04:13:02] Dead tree position: (x: 770, y: 992, z: 7)
[17/02/2011 04:13:02] North-West area position (x: 757, y: 987, z: 7)
[17/02/2011 04:13:02] South-West area position (x: 784, y: 1008, z: 7)
 
[17/02/2011 04:13:02] [Warning - Action::Demon Oak Script] Dead tree position is inside the quest area positions.
[17/02/2011 04:13:02] Dead tree position: (x: 770, y: 992, z: 7)
[17/02/2011 04:13:02] North-West area position (x: 757, y: 987, z: 7)
[17/02/2011 04:13:02] South-West area position (x: 784, y: 1008, z: 7)

read
 
Code:
[11:17:48.651] [Error - Manager Interface] 
[11:17:48.651] In a timer event called from: 
[11:17:48.651] data/lib/102-demonOak.lua
[11:17:48.651] Description: 
[11:17:48.651] data/lib/102-demonOak.lua:366: bad argument #1 to 'ipairs' (table expected, got nil)
[11:17:48.652] stack traceback:
[11:17:48.652]     [C]: in function 'ipairs'
[11:17:48.652]     data/lib/102-demonOak.lua:366: in function <data/lib/102-demonOak.lua:358>

How fix?
 
Code:
[11:17:48.651] [Error - Manager Interface] 
[11:17:48.651] In a timer event called from: 
[11:17:48.651] data/lib/102-demonOak.lua
[11:17:48.651] Description: 
[11:17:48.651] data/lib/102-demonOak.lua:366: bad argument #1 to 'ipairs' (table expected, got nil)
[11:17:48.652] stack traceback:
[11:17:48.652]     [C]: in function 'ipairs'
[11:17:48.652]     data/lib/102-demonOak.lua:366: in function <data/lib/102-demonOak.lua:358>

How fix?

Lib was updated, check main post, should be working fine
 
Code:
[16:2:29.402] [Error - Manager Interface] 
[16:2:29.402] In a timer event called from: 
[16:2:29.403] data/lib/102-demonOak.lua
[16:2:29.403] Description: 
[16:2:29.403] data/lib/102-demonOak.lua:366: attempt to get length of local 'list' (a nil value)
[16:2:29.403] stack traceback:
[16:2:29.403]     data/lib/102-demonOak.lua:366: in function <data/lib/102-demonOak.lua:358>

Not :(
 
Code:
function demonOakThink()

	local thinkTime = 10000
	local chance = 30
	if math.random(100) <= chance then
		if positions and positions.demonOak and type(positions.demonOak) == "table" and questAreaPosition and questAreaPosition[1] and type(questAreaPosition[1]) == "table" and questAreaPosition[2] and type(questAreaPosition[2]) == "table" then
			local rangeX, rangeY = getDistanceBetween(positions.demonOak, questAreaPosition[1]) + 3, getDistanceBetween(positions.demonOak, questAreaPosition[2]) + 3
			local list = getSpectators(positions.demonOak, rangeX, rangeY)
			if [B][COLOR="red"]list and [/COLOR][/B]#list > 0 then
				for _, uid in ipairs(list) do
					if isPlayer(uid) and not isInArea(getCreaturePosition(uid), questAreaPosition[1], questAreaPosition[2]) and getCreaturesInRange(TYPE_PLAYER, questAreaPosition[1], questAreaPosition[2], GET_COUNT, false) == 0 then
						doCreatureSay(uid, sounds[1][math.random(table.maxn(sounds[1]))], TALKTYPE_MONSTER_YELL, false, uid, positions.demonOak)
					end
				end
			end
		end
	end

	addEvent(demonOakThink, thinkTime)
end
 
Works now, so so.

Estrange but 2 players can enter same time, what i configure wrong? where is the check for it?
 
already have

oneByQuest = true

:eek:

Maybe, in the quest area, there is a square outside the area positions, so the script won't check that sqm.. if the player steps on that sqm, another player will enter to the quest area.
 
Check my pos in the image, something wrong?

questAreaPosition =
{
{x = 32706, y = 32344, z = 7, stackpos = 255}, --It's first sand pillar, north, west
{x = 32725, y = 32357, z = 7, stackpos = 255} --It's second sand pillar, south, east

}

The ice pillar, is pos where my player stay, when i enter in quest using other player.

printzu.jpg


I think all pos is correct!
 
Check my pos in the image, something wrong?

questAreaPosition =
{
{x = 32706, y = 32344, z = 7, stackpos = 255}, --It's first sand pillar, north, west
{x = 32725, y = 32357, z = 7, stackpos = 255} --It's second sand pillar, south, east

}

The ice pillar, is pos where my player stay, when i enter in quest using other player.

printzu.jpg


I think all pos is correct!

I don't see anything bad on your pic, but i tested it and got ir working :S

EDIT: Some other people posted here that they are getting the same bug as you (Donator people, so i think that you and they are using 0.4 DEV).. so... go to data/lib/032-position.lua

Copy the function "isInRange" and post here to see if there is a difference between "isInRange" on 0.3.6 and "isInRange" on 0.4
 
Last edited:
0.4

function isInRange(position, fromPosition, toPosition)
return (position.x >= fromPosition.x and position.y >= fromPosition.y and position.z >= fromPosition.z
and position.x <= toPosition.x and position.y <= toPosition.y and position.z <= toPosition.z)
end


0.3.6

function isInRange(position, fromPosition, toPosition)
return (position.x >= fromPosition.x and position.y >= fromPosition.y and position.z >= fromPosition.z and position.x <= toPosition.x and position.y <= toPosition.y and position.z <= toPosition.z)
end

Here is!
 
Last edited:
I think i got the error, check main post, lib was updated.

EDIT:

Now is really fixed
 
Last edited:
Back
Top