• 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!

Action Working Demon Oak Quest

Joined
Apr 17, 2008
Messages
1,922
Solutions
1
Reaction score
188
Location
Venezuela
Demon Oak Quest By Darkhaos [Tested in last The Forgotten Server Version = (Crying Damson) 0.3.6]

V0.7.0 Rev: 1.
Update Log:
Code:
[b]V0.7.0 Rev: 1:[/b]
	[b]Rev: 1 - [26 / 06 / 2012][/b]
		Added a new variable: DISTRO_VERSION. Here you must specify your distro version to make script works properly in any version.
		Edited function 'monsterExists'. It'll now check if monster exists no matter if its name is upper/lower case.
		Monsters names were changed to lower case.
		Added a short version of the script. You can locate it here: http://otland.net/f81/working-demon-oak-quest-40244/index49.html#post1556557
[B]V0.6.8 Rev: 6:[/B]
	[B]Rev: 1 - [16 / 07 / 2011][/B]
		Changed some variables name, they fit their roles better now.
		Some optimizations made to function 'getCreaturesInRange(type, fromPos, toPos, get[, countSummon])'.
		Changed name to function 'getCreaturesInRange', now is 'getCreaturesInQuestArea'.
		Some other changes.
	[B]Rev: 2 - [16 / 07 / 2011][/B]
		Updated function 'checkLib', now it checks if variables exists and are in the correct format.
	[B]Rev: 3 - [22 / 07 / 2011][/B]
		New variable on lib (waves), now you can declare hoy many waves for each oak-part.
	[B]Rev: 4 - [11 / 08 / 2011][/B]
		Updated 'demonOakDeath.lua', now creatures are removed when player dies.
	[B]Rev: 5 - [30 / 08 / 2011][/B]
		Updated the function 'monsterExists' to avoid errors on console. Lib updated.
	[B]Rev: 6 - [06 / 09 / 2011][/B]
		Now script will warn when one or more monsters is/are not summoned.

[B]V0.6.7 Rev: 45:[/B]
	[B]Rev: 25 -  [14 / 02 / 2011][/B]
		Now script will check if monsters can be summoned, if all monster can't be summoned, player won't get the storage.
	[B]Rev: 26 -  [14 / 02 / 2011][/B]
		Fixed a bug.
	[B]Rev: 27 -  [16 / 02 / 2011][/B]
		Updated function 'checkLib()' to prevent errors on console
	[B]Rev: 28 -  [16 / 02 / 2011][/B]
		Some changes to lib and actions/demonOak.lua
	[B]Rev: 29 -  [17 / 02 / 2011][/B]
		Fixed a bug on fucntion 'demonOakThink()'
	[B]Rev: 30 -  [17 / 02 / 2011][/B]
		Fixed a bug on function 'demonOakThink()'
	[B]Rev: 31 -  [17 / 02 / 2011][/B]
		Fixed a bug on function 'canEnter(cid, tree)'
		Fixed a text bug on actions/demonOak.lua
	[B]Rev: 32 -  [17 / 02 / 2011][/B]
		Fixed a bug on function 'getCreaturesInRange(type, fromPos, toPos, toget, countSummon)'
	[B]Rev: 33 -  [23 / 02 / 2011][/B]
		Now demonOakThink will work only when gamestate is normal and not starting
	[B]Rev: 34 -  [24 / 02 / 2011][/B]
		Added function 'onThink' to oldrak.lua
	[B]Rev: 35 -  [25 / 02 / 2011][/B]
		Some changes.
	[B]Rev: 36 -  [26 / 02 / 2011][/B]
		Some optimitations to lib file.
	[B]Rev: 37 -  [26 / 02 / 2011][/B]
		More optimitations to lib file.
	[B]Rev: 38 -  [26 / 02 / 2011][/B]
		Added a new feature, now you can enable/disable if the errors founded in the lib will be saved on a text file (data/logs/demonOak.txt)
	[B]Rev: 39 -  [27 / 02 / 2011][/B]
		Now only errors will be saved in the .txt file
	[B]Rev: 40 -  [27 / 02 / 2011][/B]
		Now script will check for updates (Optional)
	[B]Rev: 41 -  [27 / 02 / 2011][/B]
		Fixed bug on lib.
	[B]Rev: 42 -  [27 / 02 / 2011][/B]
		Some changes to auto update-checker.
	[B]Rev: 43 -  [27 / 02 / 2011][/B]
		Now you can enable/disable if you want the script downloads a file with all new scripts on a specified dir by the user (Only players that are using auto-update checker.
	[B]Rev: 44 -  [03 / 03 / 2011][/B]
		Some updates to auto updater and fixed item ids in rewards.
	[B]Rev: 45 -  [08 / 07 / 2011][/B]
		Removed auto-updater, not in use anymore.

[B]V0.6.6 Rev: 24: [13 / 02 / 2011][/B]
- Updated lib file --[[
	Updated function 'checkLib()' to prevent errors on console
	Updated function 'demonOakThink()' to prevent errors on console
]]
[B]V0.6.5 Rev: 23: [13 / 02 / 2011][/B]
- Updated lib file --[[
	Removed messageUids, was useless.
	Updated function 'checkLib()', now function will check if variables exists (To prevent errors on console)
	Updated function 'demonOakThink()'
]]
[B]V0.6.4: [12 / 02 / 2011][/B]
- Updated lib file --[[
	Added a variable to declare the dead tree id
	Added a new variable to declare demon oak think storage.
	Added a think function for the demon oak (demon oak will yell sounds like monster, added in lib to prevent a new file (globalevent file))
	Added a variable to enable/disable demon oak think
]]

55jvo0.png


Go to data/lib and create a new file called 102-demonOak.lua and paste this:
Lua:
--PLEASE SPECIFY HERE WHAT DISTRO VERSION YOU ARE USING. IF YOU ARE USING (0.40/0.4.0)DEV SPECIFY IT AS 040
--IF YOU ARE USING 0.3.7/0.3.7PL1/0.3.6/0.3.5.... OR ANY OTHER VERSION OF 0.3, SPECIFY IT AS 037/036/035, ETC...
--THE IDEA IS TO SPECIFY IT WITHOUT ANY STRING CHARACTER, JUST NUMBERS
--MUST SPECIFY THIS PROPERLY TO MAKE SCRIPT WORKS CORRECTLY
DISTRO_VERSION = 036
--END

_INFO =
{
	UPDATED = "June 26 2012",
	VERSION = "0.70",
	REV = 1,
	AUTHOR = "Darkhaos",
	CONTACT = "http://otland.net/members/darkhaos/"
}
 
if getStorage(0x65535) < 1 then
	doSetStorage(0x65536, os.clock())
	print("\n>> Loading Demon Oak Lib V" .. (_INFO.VERSION or "?") .. " REV: " .. (_INFO.REV or "?") .. " (" .. (_INFO.UPDATED or "?") .. ") By " .. (_INFO.AUTHOR or "?") .. " (Contact: " .. (_INFO.CONTACT or "?") .. ")")
	doSetStorage(0x65535, 1)
end
 
ITEM_DEADTREE = 2709
 
HALLOWEDAXE_PRICE = 1000
 
ERROR_NOERROR = 0
ERROR_TREEPOSITION = 1
ERROR_NOTENOUGHLEVEL = 2
ERROR_ALREADYDONE = 3
ERROR_ALREADYCUT = 4
ERROR_PLAYERINAREA = 5
ERROR_MISSINGINFO = 6
 
TYPE_PLAYER = 1
TYPE_MONSTER = 2
TYPE_NPC = 3
TYPE_ALL = 4
 
GET_COUNT = 1
GET_UID = 2
 
STORAGE_LIB = 11257
STORAGE_OAKTHINK = 11258
 
OAKTHINK_TIME = 10000
OAKTHINK_CHANCE = 30
 
oneInArea = true
killAllBeforeCut = true
oakThink = true
 
logEnabled = true
 
level = 120
waves = 11
positions =
{
	kick = {x = 110, y = 75, z = 7},
	summon =
	{
		{x = 104, y = 83, z = 7},
		{x = 101, y = 82, z = 7},
		{x = 105, y = 81, z = 7},
		{x = 102, y = 78, z = 7},
		{x = 103, y = 80, z = 7},
		{x = 102, y = 82, z = 7},
		{x = 103, y = 79, z = 7},
		{x = 100, y = 78, z = 7}
	},
	rewardRoom = {x = 586, y = 630, z = 8},
	demonOak = {x = 105, y = 82, 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"}
}
 
questAreaPosition =
{
	{x = 94, y = 75, z = 7, stackpos = 255},
	{x = 112, y = 86, z = 7, stackpos = 255}
}
 
demonOak = {8288, 8289, 8290, 8291}
 
storages =
{
	done = 35712,
	treeCut = 38551
}
 
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 = 8918, count = 1},
	[12904] = {done = 12900, reward = 8851, count = 1}
}
 
sounds =
{
	[1] = --Messages shown when you wlak on special tiles
	{
		"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] = --Messages shown when you use axe on Demon Oak
	{
		"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 type(questAreaPosition) == "table" and type(questAreaPosition[1]) == "table" and type(questAreaPosition[2]) == "table" and level and type(storages) == "table" then
		if isInRange(tree, questAreaPosition[1], questAreaPosition[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 oneInArea then
			if getCreaturesInQuestArea(TYPE_PLAYER, questAreaPosition[1], questAreaPosition[2], GET_COUNT) > 0 then
				return ERROR_PLAYERINAREA
			end
		end
	else
		return ERROR_MISSINGINFO
	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: " .. questAreaPosition[1].x .. ", y: " .. questAreaPosition[1].y .. ", z: " .. questAreaPosition[1].z .. ")\nSouth-West area position (x: " .. questAreaPosition[2].x .. ", y: " .. questAreaPosition[2].y .. ", z: " .. questAreaPosition[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_PLAYERINAREA then
		return "Wait until the player inside the quest area finishes the quest."
	elseif data == ERROR_MISSINGINFO then
		return "Sorry, not possible."
	end
	return ""
end
 
function getCreaturesInQuestArea(type, fromPos, toPos, get, countSummon)
 
	local types = 
	{
		[TYPE_PLAYER] = isPlayer,
		[TYPE_MONSTER] = isMonster,
		[TYPE_NPC] = isNpc,
		[TYPE_ALL] = isCreature
	}
 
	local tmp = {}
	local t = types[type]
	if not t then
		return print("[!] --> [Warning - Function::getCreaturesInQuestArea] 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
					table.insert(tmp, thing.uid)
					if not countSummon and isSummon(thing.uid) then
						for i = 1, #tmp do
							if tmp[i] == thing.uid then
								table.remove(tmp, i)
								break
							end
						end
					end
				end
			end
		end
	end
	return (get == GET_COUNT and #tmp or get == GET_UID and tmp or print("[Warning - Function::getCreaturesInQuestArea] Unknow type to get " .. (get or "(nil value)")))
end
 
function monsterExists(name)
 
	local file = "data/monster/monsters.xml"
	local openFile = io.open(file, "r")
	local m_name, getName, getFile, m_file = 0, 0, 0, 0
	local monsterExists, fileExists = false, false
	if openFile ~= 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=".*".*')
				if getName and getFile then
					m_name = string.sub(getName, string.find(getName, '="') + 2, (string.find(getName, '" ') or string.find(getName, '"f') or 1) - 1)
					m_file = string.sub(getFile, string.find(getFile, '="') + 2, (string.find(getFile, '"/') or string.find(getFile, '" ') or 1) - 1)
					if m_name:lower() == name:lower() then
						monsterExists = true
						mfile = io.open("data/monster/" .. m_file, "r")
						if mfile ~= nil then
							fileExists = true
							mfile:close()
						end
					end
				end
			end
		end
		openFile:close()
	end
	return monsterExists and fileExists or false
end
 
function isSummon(cid)
	if DISTRO_VERSION < 040 then
		return getCreatureMaster(cid) ~= cid or false
	else
		return getCreatureMaster(cid) ~= nil or false
	end
end
 
function isLastCut(cid)
	local k, s = 0, 0
	if not demonOak or type(demonOak) ~= "table" then
		return false
	end
	for i = demonOak[1], demonOak[#demonOak] do
		if getCreatureStorage(cid, i) == #summons + 1 then
			k = k + 1
		end
		if getCreatureStorage(cid, i) == #summons then
			s = s + 1
		end
	end
	return (k == 3 and s == 1 and true or false)
end
function checkLib()
 
	local final = "[" .. os.date() .. "]\n"
	print("\n[!] -> Checking demon oak lib...")
	local start = os.clock()
	local r = 0
	if not ITEM_DEADTREE or type(ITEM_DEADTREE) ~= "number" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load dead tree id (number expected, got " .. (type(ITEM_DEADTREE) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load dead tree id (number expected, got " .. (type(ITEM_DEADTREE) or "nil") .. ")\n"
		r = r + 1
	end
	if not HALLOWEDAXE_PRICE or type(HALLOWEDAXE_PRICE) ~= "number" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load hallowed axe price (number expected, got " .. (type(HALLOWEDAXE_PRICE) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load hallowed axe price (number expected, got " .. (type(HALLOWEDAXE_PRICE) or "nil") .. ")\n"
		r = r + 1
	end
	if not ERROR_NOERROR or type(ERROR_NOERROR) ~= "number" or not ERROR_TREEPOSITION or type(ERROR_TREEPOSITION) ~= "number"
	or not ERROR_NOTENOUGHLEVEL or type(ERROR_NOTENOUGHLEVEL) ~= "number" or not ERROR_ALREADYDONE or type(ERROR_ALREADYDONE) ~= "number"
	or not ERROR_ALREADYCUT or type(ERROR_ALREADYCUT) ~= "number" or not ERROR_PLAYERINAREA or type(ERROR_PLAYERINAREA) ~= "number"
	or not ERROR_MISSINGINFO or type(ERROR_MISSINGINFO) ~= "number" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load variables for function 'getError'")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load variables for function 'getError'\n"
		r = r + 1
	end
	if not TYPE_PLAYER or type(TYPE_PLAYER) ~= "number" or not TYPE_MONSTER or type(TYPE_MONSTER) ~= "number"
	or not TYPE_NPC or type(TYPE_NPC) ~= "number" or not TYPE_ALL or type(TYPE_ALL) ~= "number" 
	or not GET_COUNT or type(GET_COUNT) ~= "number" or not GET_UID or type(GET_UID) ~= "number" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load variables for function 'getCreaturesInQuestArea'")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load variables for function 'getCreaturesInQuestArea'\n"
		r = r + 1
	end
	if not STORAGE_LIB or not isInArray({"number", "string"}, type(STORAGE_LIB)) then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load storage lib, lib will be checked more than once.")
		final = final .. "	[Warning - Lib::DemonOak] Cannot storage lib, lib will be checked more than once.\n"
		r = r + 1
	end
	if not STORAGE_OAKTHINK or not isInArray({"number", "string"}, type(STORAGE_OAKTHINK)) then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load storage oakthink, 'demon oak think' will be started more than once.")
		final = final .. "	[Warning - Lib::DemonOak] Cannot storage oakthink, 'demon oak think' will be started more than once.\n"
		r = r + 1
	end
	if not OAKTHINK_TIME or type(OAKTHINK_TIME) ~= "number" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load oakthink time, 'demon oak think' cannot be started.")
		final = final .. "	[Warning - Lib::DemonOak] Cannot oakthink time, 'demon oak think' cannot be started.\n"
		r = r + 1
	end
	if not OAKTHINK_CHANCE or type(OAKTHINK_CHANCE) ~= "number" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load oakthink chance, 'demon oak think' cannot be started.")
		final = final .. "	[Warning - Lib::DemonOak] Cannot oakthink chance, 'demon oak think' cannot be started.\n"
		r = r + 1
	end
	if 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. Check if it is well writen in monsters.xml and also check if the file really exists.")
						final = final .. "	[Warning - Lib::DemonOak] Table: summons, Id: " .. k .. ", Monster " .. s .. " does not exists. Check if it is well writen in monsters.xml and also check if the file really exists.\n"
						r = r + 1
					end
				end
			else
				print("[!] --> [Warning - Lib::DemonOak] Table: summons, Id: " .. k .. ", cannot load summons (table expected, got " .. (type(v) or "nil") .. ")")
				final = final .. "	[Warning - Lib::DemonOak] Table: summons, Id: " .. k .. ", cannot load summons (table expected, got " .. (type(v) or "nil") .. ")\n"
				r = r + 1
			end
		end
	else
		print("[!] --> [Warning - Lib::DemonOak] Cannot load summons (table expected, got " .. (type(summons) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load summons (table expected, got " .. (type(summons) or "nil") .. ")\n"
		r = r + 1
	end
	if type(positions) == "table" then
		if type(positions.kick) ~= "table" then
			print("[!] --> [Warning - Lib::DemonOak] Invalid position for kick (table expected, got " .. (type(positions.kick) or "nil") .. ")")
			final = final .. "	[Warning - Lib::DemonOak] Invalid position for kick (table expected, got " .. (type(positions.kick) or "nil") .. ")\n"
			r = r + 1
		elseif type(positions.rewardRoom) ~= "table" then
			print("[!] --> [Warning - Lib::DemonOak] Invalid position for reward room (table expected, got " .. (type(positions.rewardRoom) or "nil") .. ")")
			final = final .. "	[Warning - Lib::DemonOak] Invalid position for reward room (table expected, got " .. (type(positions.rewardRoom) or "nil") .. ")\n"
			r = r + 1
		elseif type(positions.demonOak) ~= "table" then
			print("[!] --> [Warning - Lib::DemonOak] Cannot load demonOak position, scripts will use player position.")
			final = final .. "	[Warning - Lib::DemonOak] Cannot load demonOak position, scripts will use player position.\n"
			r = r + 1
		end
		if type(positions.summon) == "table" then
			for i = 1, #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") .. ")")
					final = final .. "	[Warning - Lib::DemonOak] Invalid summon position on index " .. i .. " (table expected, got " .. (type(positions.summon[i]) or "nil") .. ")\n"
					r = r + 1
				end
			end
		else
			print("[!] --> [Warning - Lib::DemonOak] Cannot load summons position (table expected, got " .. (type(positions.summon) or "nil") .. ")")
			final = final .. "	[Warning - Lib::DemonOak] Cannot load summons position (table expected, got " .. (type(positions.summon) or "nil") .. ")\n"
			r = r + 1
		end
	else
		print("[!] --> [Warning - Lib::DemonOak] Cannot load positions (table expected, got " .. (type(positions) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load positions (table expected, got " .. (type(positions) or "nil") .. ")\n"
		r = r + 1
	end
	if not questAreaPosition or type(questAreaPosition[1]) ~= "table" or type(questAreaPosition[2]) ~= "table" then
		print("[!] --> [Warning - Lib::DemonOak] Invalid area positions!")
		final = final .. "	[Warning - Lib::DemonOak] Invalid area positions!\n"
		r = r + 1
	end
	if type(demonOak) ~= "table" then
		print("[!] --> [Warning - Lib::DemonOak] Cannot load 'demonOak' ids (table expected, got " .. (type(demonOak) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load 'demonOak' ids (table expected, got " .. (type(demonOak) or "nil") .. ")\n"
		demonOak = {8288, 8289, 8290, 8291}
		r = r + 1
	end
	if storages and storages.done and storages.treeCut then
		if storages.done == storages.treeCut then 
			print("[!] --> [Warning - Lib::DemonOak] 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.")
			final = final .. "	[Warning - Lib::DemonOak] 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.\n"
			r = r + 1
		end
	else
		print("[!] --> [Warning - Lib::Demon Oak] Cannot load storages (table expected, got " .. (type(storages) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load storages (table expected, got " .. (type(storages) or "nil") .. ")\n"
		r = r + 1
	end
	if 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") .. ")")
				final = final .. "	[Warning - Lib::DemonOak] Cannot load info about dead tree id: " .. k .. " (table expected, got " .. (type(v) or "nil") .. ")\n"
				r = r + 1
			end
		end
	else
		print("[!] --> [Warning - Lib::DemonOak] Cannot load info about dead tree (table expected, got " .. (type(blockingTree) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load info about dead tree (table expected, got " .. (type(blockingTree) or "nil") .. ")\n"
		r = r + 1
	end
	if 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 .. "!")
				final = final .. "	[Warning - Lib::DemonOak] Cannot load reward id " .. k .. "!\n"
				r = r + 1
			end
		end
	else
		print("[!] --> [Warning - Lib::DemonOak] Cannot load rewards (table expected, got " .. (type(rewards) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load rewards (table expected, got " .. (type(rewards) or "nil") .. ")\n"
		r = r + 1
	end
	if 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") .. ")")
				final = final .. "	[Warning - Lib::DemonOak] Cannot load sounds on index " .. k .. " (table expected, got " .. (type(v) or "nil") .. ")\n"
				r = r + 1
			end
		end
	else
		print("[!] --> [Warning - Lib::DemonOak] Cannot load sounds (table expected, got " .. (type(sounds) or "nil") .. ")")
		final = final .. "	[Warning - Lib::DemonOak] Cannot load sounds (table expected, got " .. (type(sounds) or "nil") .. ")\n"
		r = r + 1
	end
 
	print("[!] ->  " .. r .. " problems loaded in " .. os.clock() - start .. " seconds.\n")
	local logFile = "data/logs/demonOak.txt"
	local f = io.open(logFile, "a+")
	if logEnabled then
		if f ~= nil then
			f:write((r > 0 and final .. "\n\n" or ""))
			f:close()
		end
	end
end
 
function demonOakThink()
 
	if getGameState() == GAMESTATE_NORMAL then
		if math.random(100) <= OAKTHINK_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 list and #list > 0 then
					for _, uid in ipairs(list) do
						if isPlayer(uid) and not isInArea(getCreaturePosition(uid), questAreaPosition[1], questAreaPosition[2]) and getCreaturesInQuestArea(TYPE_PLAYER, questAreaPosition[1], questAreaPosition[2], GET_COUNT) == 0 then
							doCreatureSay(uid, sounds[1][math.random(#sounds[1])], TALKTYPE_MONSTER_YELL, false, uid, positions.demonOak)
						end
					end
				end
			end
		end
	end
 
	addEvent(demonOakThink, OAKTHINK_TIME)
end
 
if getStorage(STORAGE_LIB) < 1 then
	checkLib()
	doSetStorage(STORAGE_LIB, 1)
end
 
if getStorage(STORAGE_OAKTHINK) < 1 and oakThink then
	demonOakThink()
	doSetStorage(STORAGE_OAKTHINK, 1)
end
 
if getStorage(0x65537) < 1 then
	print("[!] ->  Demon Oak Lib loaded in " .. os.clock() - getStorage(0x65536) .. " seconds.\n")
	doSetStorage(0x65537, 1)
end

Create a file in data/actions called demonOak.lua and paste:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)
 
	if blockingTree[itemEx.itemid] and itemEx.uid == blockingTree[itemEx.itemid][1] then
 
		local tree = toPosition
		if canEnter(cid, tree) ~= ERROR_NOERROR then
			return doPlayerSendCancel(cid, getError(canEnter(cid, tree), tree)) and doSendMagicEffect(tree, CONST_ME_POFF)
		end
 
		doTransformItem(itemEx.uid, blockingTree[itemEx.itemid][2])
		doSendMagicEffect(tree, CONST_ME_POFF)
		doMoveCreature(cid, getDirectionTo(getCreaturePosition(cid), toPosition))
		doCreatureSetStorage(cid, storages.treeCut, 1)
		doCreatureSay(cid, "I AWAITED YOU! COME HERE AND GET YOUR REWARD!", TALKTYPE_MONSTER_YELL, false, cid, (positions.demonOak or getCreaturePosition(cid)))
		return true
 
	elseif isInArray(demonOak, itemEx.itemid) then
 
		local get = getCreatureStorage(cid, itemEx.itemid)
		if get == -1 then doCreatureSetStorage(cid, itemEx.itemid, 1) end
 
		local k = 0
		for i = demonOak[1], demonOak[#demonOak] do
			if(getCreatureStorage(cid, i) == (waves and waves > 0 and waves or #summons) + 1) then
				k = k + 1
			end
		end
 
		if killAllBeforeCut or k == #demonOak then
			if getCreaturesInQuestArea(TYPE_MONSTER, questAreaPosition[1], questAreaPosition[2], GET_COUNT) > 0 then
				doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You need to kill all monsters first.")
				doSendMagicEffect(toPosition, CONST_ME_POFF)
				return true
			end
		end
 
		if(k == #demonOak) then 
			doTeleportThing(cid, positions.kick)
			doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "Tell Oldrak about your great victory against the demon oak.")
			doCreatureSetStorage(cid, storages.done, 1)
			return true
		end
 
		if getCreatureStorage(cid, itemEx.itemid) >= (waves and waves > 0 and waves or #summons) + 1 then
			return doSendMagicEffect(toPosition, CONST_ME_POFF)
		end
 
		if math.random(10) > 3 then
			doSendMagicEffect(toPosition, CONST_ME_DRAWBLOOD)
			doCreatureSay(cid, "-krrrrak-", TALKTYPE_MONSTER_YELL, false, cid, getThingPos(itemEx.uid))
			doTargetCombatHealth(0, cid, floorDamage.type, -floorDamage.min, -floorDamage.max, floorDamage.effect)
			return true
		end
 
		local deny = false
		local cbs = 0
		if summons[get] then
			for i = 1, #summons[get] do
				if monsterExists(summons[get][i]) then
					local sPos = positions.summon[math.random(#positions.summon)]
					local thing = getTopCreature(sPos)
					local area
					if isMonster(thing.uid) then
						area = getArea(sPos, 2, 2)
						for _, pos in ipairs(area) do
							if isCreature(getTopCreature(pos).uid) or not isInRange(pos, questAreaPosition[1], questAreaPosition[2]) then
								deny = true
								break
							else
								ret = doCreateMonster(summons[get][i], pos)
								if tonumber(ret) == nil then
									cbs = cbs + 1
								end
								break
							end
						end
					else
						ret = doCreateMonster(summons[get][i], sPos)
						if tonumber(ret) == nil then
							cbs = cbs + 1
						end
					end
				end
			end

			if cbs > 0 then
				return doPlayerSendCancel(cid, "There are " .. cbs .. " monster that could not be summoned. Wave has not been counted.")
			end

			if not deny then
				doCreatureSetStorage(cid, itemEx.itemid, get + 1)
			end
			if isLastCut(cid) then
				doCreatureSay(cid, "HOW IS THAT POSSIBLE?!? MY MASTER WILL CRUSH YOU!! AHRRGGG!", TALKTYPE_MONSTER_YELL, false, cid, (positions.demonOak or getCreaturePosition(cid)))
			else
				doCreatureSay(cid, sounds[2][math.random(1, #sounds[2])], TALKTYPE_MONSTER_YELL, false, cid, (positions.demonOak or getCreaturePosition(cid)))
			end
			doSendMagicEffect(toPosition, CONST_ME_DRAWBLOOD)
			if math.random(100) >= 50 then
				doTargetCombatHealth(0, cid, floorDamage.type, -floorDamage.min, -floorDamage.max, floorDamage.effect)
			end
		end
	return false
	end
end

Create a file on data/actions called demonOakGravestone.lua and paste:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)

	if getCreatureStorage(cid, storages.done) > 1 then
		return doTeleportThing(cid, positions.rewardRoom)
	end
	return false
end

Create a file on data/actions called demonOakChests.lua and paste:
Lua:
function onUse(cid, item, fromPosition, itemEx, toPosition)

	if rewards[item.uid] then
		local t = rewards[item.uid]
                if(getCreatureStorage(cid, t.done) < 1) then
                        doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "You have found " .. getItemArticleById(t.reward) .. " " .. getItemNameById(t.reward) .. ".")
                        doPlayerAddItem(cid, t.reward, t.count)
                        doCreatureSetStorage(cid, t.done, 1)
			return true
                end

		return doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, "It's empty.")
        end
        return false
end

Now add this to actions.xml:
XML:
	<action itemid="8293" event="script" value="demonOak.lua"/>
	<action fromuid="12901" touid="12904" event="script" value="demonOakChests.lua"/>
	<action uniqueid="55100" event="script" value="demonOakGravestone.lua" />

Create a file on data/movements called demonOakTree.lua and paste:
Lua:
function onStepOut(cid, item, position, fromPosition)

	return doTransformItem(item.uid, ITEM_DEADTREE)
end

Create a file on data/movements called demonOakArea.lua and paste:
Lua:
function onStepIn(cid, item, position, fromPosition)

	if isPlayer(cid) and math.random(1, 24) == 1 then
		doTargetCombatHealth(0, cid, floorDamage.type, -floorDamage.min, -floorDamage.max, floorDamage.effect)
	end
	return true
end

Create a file on data/movements called demonOakSquares.lua and paste:
Lua:
function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor)

	return doCreatureSay(cid, sounds[1][math.random(1, #sounds[1])], TALKTYPE_MONSTER_YELL, false, cid, (positions.demonOak or getCreaturePosition(cid)))
end

Now add this to movements.xml:
XML:
	<movevent type="StepOut" uniqueid="32193" event="script" value="demonOakTree.lua" />
	<movevent type="StepIn" itemid="8292" event="script" value="demonOakArea.lua" />
	<movevent type="StepIn" uniqueid="13901-13905" event="script" value="demonOakSquares.lua" />

Create a file on data/creaturescripts called demonOakLogout.lua and paste:
Lua:
function onLogout(cid)

	if getCreatureStorage(cid, storages.treeCut) > 0 and getCreatureStorage(cid, storages.done) < 1 then
		doCreatureSetStorage(cid, storages.treeCut, 0)
	end
	return true
end

Create a file on data/creaturescripts called demonOakDeath.lua and paste:
Lua:
function onDeath(cid, corpse)
 
	if getCreatureStorage(cid, storages.treeCut) > 0 and getCreatureStorage(cid, storages.done) < 1 then
		local creatures = getCreaturesInQuestArea(TYPE_MONSTER, questAreaPosition[1], questAreaPosition[2], GET_UID)
		if creatures and #creatures > 0 then
			for _, it in ipairs(creatures) do
				doRemoveCreature(it)
			end
		end
		doCreatureSetStorage(cid, storages.treeCut, 0)
	end
	return true
end

Create a file on data/creaturescripts called demonOakAttack.lua and paste:
Lua:
function onAttack(cid, target)

	if not isPlayer(cid) or not isMonster(target) then return true end
	if not isInRange(getCreaturePosition(cid), questAreaPosition[1], questAreaPosition[2]) and isInRange(getCreaturePosition(target), questAreaPosition[1], questAreaPosition[2]) then
		return false
	end
	return true
end

Add this to login.lua:
Lua:
registerCreatureEvent(cid, "demonOakDeath")
registerCreatureEvent(cid, "demonOakAttack")
registerCreatureEvent(cid, "demonOakLogout")

And this to creaturescripts.xml:
XML:
<event type="logout" name="demonOakLogout" event="script" value="demonOakLogout.lua"/>
<event type="death" name="demonOakDeath" event="script" value="demonOakDeath.lua"/>
<event type="attack" name="demonOakAttack" event="script" value="demonOakAttack.lua"/>

Create a file on data/npc called Oldrak.xml and paste:
XML:
<npc name="Oldrak" script="data/npc/scripts/oldrak.lua" walkinterval="2000" floorchange="0" access="3">
    <health now="150" max="150"/>
    <look type="57" head="115" body="113" legs="31" feet="38" addons="3"/>
    <parameters>
        <parameter key="message_greet" value="Hello, |PLAYERNAME|!" />
        <parameter key="message_needmoremoney" value="Try again when you have more money."/>
        <parameter key="message_decline" value="Why would you tease me like that?"/>
    </parameters>
</npc>

Go to data/npc/scripts and create a file called oldrak.lua and paste:
Lua:
local keywordHandler = KeywordHandler:new()
local npcHandler = NpcHandler:new(keywordHandler)
NpcSystem.parseParameters(npcHandler)
local talkState = {}

function onCreatureAppear(cid)                          npcHandler:onCreatureAppear(cid) end
function onCreatureDisappear(cid)                       npcHandler:onCreatureDisappear(cid) end
function onCreatureSay(cid, type, msg)                  npcHandler:onCreatureSay(cid, type, msg) end
function onThink()                                      npcHandler:onThink() end

function creatureSayCallback(cid, type, msg)

	if(not npcHandler:isFocused(cid)) then
		return false
	end

	local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid
	if msgcontains(msg, "hallowed axe") then
		selfSay("Do you want to buy a Hallowed Axe for " .. HALLOWEDAXE_PRICE .. " gold coins?", cid)
		talkState[talkUser] = 1
	elseif msgcontains(msg, "yes") and talkState[talkUser] == 1 then
		if getPlayerItemCount(cid, 2386) >= 1 and getPlayerMoney(cid) >= HALLOWEDAXE_PRICE then
			if doPlayerRemoveMoney(cid, HALLOWEDAXE_PRICE) then
				selfSay("Here you are. You can now defeat the demon oak with this axe.", cid)
				doPlayerRemoveItem(cid, 2386, 1)
				doPlayerAddItem(cid, 8293, 1)
				talkState[talkUser] = 0
			end
		else
			selfSay("I need an axe and " .. HALLOWEDAXE_PRICE.. " gold coins to make you a {hallowed axe}.", cid)
			talkState[talkUser] = 0
		end
	elseif msgcontains(msg, "demon oak") then
		selfSay("Did you defeat the demon oak?", cid)
		talkState[talkUser] = 2
	elseif msgcontains(msg, "yes") and talkState[talkUser] == 2 then
		if getCreatureStorage(cid, storages.done) == 1 then
			selfSay("Good job!", cid)
			doCreatureSetStorage(cid, storages.done, 2)
			talkState[talkUser] = 0
		else
			selfSay("Go defeat the demon oak first.", cid)
			talkState[talkUser] = 0
		end
	elseif msgcontains(msg, "no") and (talkState[talkUser] >= 1 and talkState[talkUser] <= 3) then
		selfSay("Ok thanks.", cid)
		talkState[talkUser] = 0
	end
	return true
end

npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, creatureSayCallback)
npcHandler:addModule(FocusModule:new())

Enjoy!
 

Attachments

Last edited:
Sorry :)
All script working! good job!
rep!
 
Last edited:
Ehhh very buged...
1. Dead tree no remove or i heaven't idea to remove.
2. I use hallowed axe on tree with action id 8288, 8289, 8290, 8291 and shit :)

i tested and is working, dead tree should be itemid 2709 and uniqueid 32193,

8288 to 8291 are the itemids of the demon oak parts (Bird, left-right hand and face), these aren't action ids.

PD: to remove the dead tree you need to use the hallowed axe on it
 
So... 2 or more people can do quest at once?
 
Yes all working.
Sorry my english is bad ;/ I must learn
 
local areaPosition =
{
{x=923, y=1138, z=7, stackpos = 255},
{x=923, y=1139, z=7, stackpos = 255}



where devotees put this? is not
that there be done with that, please help me
: D
 
local areaPosition =
{
{x=923, y=1138, z=7, stackpos = 255},
{x=923, y=1139, z=7, stackpos = 255}



where devotees put this? is not
that there be done with that, please help me
: D

Lua:
local areaPosition =
{
    {x=923, y=1138, z=7, stackpos = 255}, --nort-west of the demon oak area
    {x=923, y=1139, z=7, stackpos = 255} --south-east of the demon oak area
}

Example:
(Image by Mazen, edited by me [ignore the red circles and the text])
33fde0w.jpg


The area inside the square is the area checked. If the script found a player in that area, then other player can't enter to the quest.
 
Dead Tree not working for me :/
When I use hallowed axe on dead tree (id 2709 uid 32193) obtain message: Wait until "my har name" finish the quest.
edroi.jpg

Only it not working :/
Do You help me? :p
Sorry for my english ;/
 
Dead Tree not working for me :/
When I use hallowed axe on dead tree (id 2709 uid 32193) obtain message: Wait until "my har name" finish the quest.
edroi.jpg

Only it not working :/
Do You help me? :p
Sorry for my english ;/

The death-tree position is inside the checked area.
 
Back
Top