Faaaala galeinha! Tudo tranquilo? Bom, tomara que sim. Este é um projeto que eu desenvolvi ao longo deste mês, eu refiz três quests importantes do tibia, sendo estas a Demon Oak, Annihilator e Demon Helmet. Lembrando que elas não são exatamente como no tibia, são mais pra versão Demonbholder. Outra coisa, eu vou estar fazendo as quests rl que me pedirem abaixo com exceção da Pits of Inferno, POI. Esta quest não foi incorporada pois demora algum tempo para ser feita, portanto, talvez eu farei algum dia. Quem quiser contribuir com a sua versão de uma quest também pode me mandar por mensagem privada e ela será colocada aqui no tópico com os seus créditos. Não será tolerado ripping de quests, tanto de OtServers quanto de outros fóruns.
Atenção: Sempre, sempre leia as informações para que não aconteça nenhum bug.
Demon Oak
Versão: Demonbholder
Sistema: Mod
Detalhes: Esta versão da Demon Oak eu fiz com que pudesse se encaixar em vários mapas, porém, é necessário seguir o padrão da imagem abaixo.
Funcionamento: Deve funcionar desta seguinte maneira: O jogador deve conseguir o Hallowed Axe, e depois entrar em um portal, este portal deverá ter a actionid 37804. Após entrar no portal, ele será teleportado para Demon Oak, e lá ele deve usar o Hallowed Axe na arvore para começar a quest. Após ter terminado, ele automaticamente será teleportado para a sala do trono da Demon Oak. Os baús do trono da Demon Oak, devem ter os seguintes actionid: 37800, 37801, 37802, 37803.
Mapa Padrão:
Script:
<?xml version="1.0" encoding="UTF-8"?> <mod name="DemonOak" enabled="yes" author="Demonbholder" forum="XTibia.com"> <config name="Function"><![CDATA[ function getOak() local OAK = { [1] = {name='skeleton', quant=7}, [2] = {name='beholder', quant=4}, [3] = {name='minotaur mage', quant=3}, [4] = {name='dwarf guard', quant=3}, [5] = {name='demon skeleton', quant=2}, [6] = {name='dragon', quant=1}, [7] = {name='tarantula', quant=3}, [8] = {name='pirate cutthroat', quant=3}, [9] = {name='orc leader', quant=3}, [10] = {name='dwarf geomancer', quant=1}, [11] = {name='fire elemental', quant=4}, [12] = {name='vampire', quant=2}, [13] = {name='avalanche', quant=1}, [14] = {name='blue djinn', quant=2}, [15] = {name='green djinn', quant=2}, [16] = {name='giant spider', quant=5}, [17] = {name='crystal spider', quant=3}, [18] = {name='dragon lord', quant=3}, [19] = {name='hydra', quant=2}, [20] = {name='frost dragon', quant=2}, [21] = {name='fury', quant=5}, [22] = {name='medusa', quant=2}, [23] = {name='destroyer', quant=3}, [24] = {name='diabolic imp', quant=2}, [25] = {name='minishabaal', quant=2}, [26] = {name='behemoth', quant=3}, [27] = {name='warlock', quant=2}, [28] = {name='undead dragon', quant=2}, [29] = {name='demon', quant=3}, } return OAK end function doOak(param) local pos = getCreaturePosition(param) for posx = pos.x - 20, pos.x + 20 do for posy = pos.y - 20, pos.y + 20 do local posi = getThingFromPos({x=posx, y=posy, z=pos.z, stackpos=253}).uid if isMonster(posi) then doRemoveCreature(posi) end end end return TRUE end ]]></config> <creaturescript type="login" name="DemonOakR" event="script"><![CDATA[ registerCreatureEvent(cid, "DemonOakD") registerCreatureEvent(cid, "DemonOakK") return TRUE ]]></creaturescript> <action itemid="8293" event="script"><![CDATA[ domodlib('Function') local espinhosid = {8289, 8290} if isInArray(espinhosid, itemEx.itemid) then if getPlayerStorageValue(cid, 37800) > -1 and getPlayerStorageValue(cid, 37800) <= #getOak() and getPlayerStorageValue(cid, 37801) == -1 then doPlayerSendTextMessage(cid, 22, "Mate-os!") for i = 1, getOak()[getPlayerStorageValue(cid, 37800)].quant do setPlayerStorageValue(cid, 37801, 0) oakx = itemEx.itemid == 8289 and i or 0 doCreateMonster(getOak()[getPlayerStorageValue(cid, 37800)].name, {x=getThingPos(item.uid).x +oakx, y=getThingPos(item.uid).y +4, z=getThingPos(item.uid).z}) end else doPlayerSendCancel(cid, "Voce ja fez esta quest.") end end ]]></action> <action actionid="37800;37801;37802;37803" event="script"><![CDATA[ domodlib('Function') local itens = { [37800] = {id = 2495, message = "Parabens, voce ganhou uma demon legs."}, [37801] = {id = 8905, message = "Parabens, voce ganhou um rainbow shield."}, [37802] = {id = 8851, message = "Parabens, voce ganhou um royal crossbow."}, [37803] = {id = 8918, message = "Parabens, voce ganhou um spellbook of dark mysteries."} } if getPlayerStorageValue(cid, 37800) == #getOak()+1 then doPlayerAddItem(cid, itens[item.actionid].id, 1) doPlayerSendTextMessage(cid, 25, itens[item.actionid].message) setPlayerStorageValue(cid, 37800, getPlayerStorageValue(cid, 37800)+1) end ]]></action> <creaturescript type="logout" name="DemonOakL" event="script"><![CDATA[ domodlib('Function') if getPlayerStorageValue(cid, 37800) > -1 and getPlayerStorageValue(cid, 37800) <= #getOak() then if getCreatureHealth(cid) ~= 0 then doPlayerSendCancel(cid, "Voce nao pode sair da demon OAK.") return FALSE end end return TRUE ]]></creaturescript> <creaturescript type="kill" name="DemonOakK" event="script"><![CDATA[ domodlib('Function') local salapos = {x=148, y=38, z=7} -- sala do trono if isMonster(target) and string.lower(getCreatureName(target)) == string.lower(getOak()[getPlayerStorageValue(cid, 37800)].name) and getCreatureMaster(target) ~= cid then if getPlayerStorageValue(cid, 37800) > -1 and getPlayerStorageValue(cid, 37800) <= #getOak() then setPlayerStorageValue(cid, 37801, getPlayerStorageValue(cid, 37801) + 1) end if getPlayerStorageValue(cid, 37801) == (getOak()[getPlayerStorageValue(cid, 37800)].quant) then setPlayerStorageValue(cid, 37800, getPlayerStorageValue(cid, 37800) + 1) setPlayerStorageValue(cid, 37801, -1) end if getPlayerStorageValue(cid, 37800) == #getOak()+1 then doTeleportThing(cid, salapos) end end return TRUE ]]></creaturescript> <creaturescript type="death" name="DemonOakD" event="script"><![CDATA[ domodlib('Function') if getPlayerStorageValue(cid, 37800) > -1 and getPlayerStorageValue(cid, 37800) <= #getOak() then setPlayerStorageValue(cid, 37800, -1) setPlayerStorageValue(cid, 37801, -1) doOak(cid) end return TRUE ]]></creaturescript> <movevent type="StepIn" actionid="37804" event="script"><![CDATA[ domodlib('Function') local ret = FALSE local pos = {x=63, y=129, z=7} -- demon oak for _, pid in pairs(getPlayersOnline()) do if getPlayerStorageValue(pid, 37800) > -1 and getPlayerStorageValue(pid, 37800) < #getOak() then ret = TRUE break end end if ret == TRUE or getPlayerStorageValue(cid, 37800) > -1 or getPlayerItemCount(cid, 8293) < 1 then doTeleportThing(cid, fromPosition) doPlayerSendCancel(cid, "Ha alguem fazendo esta quest no momento, ou voce ja a fez ou nao possui o hallowed axe.") else setPlayerStorageValue(cid, 37800, 1) doTeleportThing(cid, pos) doPlayerSendTextMessage(cid, 22, "Demon OAK!") end return TRUE ]]></movevent> </mod>
Crie um arquivo .xml em mods e cole este script nele, nada mais precisa ser feito.
Editando o script: Edite a posição da sala do trono, linha 126. Edite a posição da demon oak, linha 162. Por fim, você pode editar os monstros e a quantidade deles no inicio do script, porém não é recomendável adicionar mais níveis. Se for mudar os monstros e a quantidade, mude antes de colocar o script, caso contrário, poderá bugar. Os baús da quest devem ter os seguintes actionid: 32800, 32801, 32802, 32803.
Annihilator:
Versão: Demonbholder
Sistema: Actions
Funcionamento: Após entrar na annihilator, o time terá tanto tempo para matar os demons e pegar sua recompensa, caso isto não seja feito no tempo escolhido no script, os jogadores serão teleportados para algum lugar desejado e a quest reiniciará. Enquanto este tempo não acabar, outros times não poderão entrar na quest. O script irá teleportar os jogadores para um andar abaixo.
Mapa padrão:
Script - Alavanca:
function onUse(cid, item) local pos = {x=193, y=118, z=9, stackpos=253} -- posição do jogador mais proximo da alavanca local uid = nil local delay = 500 -- tempo para resetar a quest local t = {} for i = pos.x -3, pos.x do local player = getThingFromPos({x=i, y=pos.y, z=pos.z, stackpos=253}).uid if isCreature(player) then if getPlayerStorageValue(player, 32800) == -1 and getPlayerLevel(player) >= 100 then uid = uid == nil and 1 or uid + 1 t[uid] = player end else return doPlayerSendCancel(cid, "Você precisa de 4 membros para fazer a quest.") end end if #t == 4 then if getGlobalStorageValue(32800) - os.time() <= 0 then for i = pos.x -3, pos.x do doTeleportThing(getThingFromPos({x=i, y=pos.y, z=pos.z, stackpos=253}).uid, {x=i, y=pos.y, z=pos.z + 1}) doSendMagicEffect({x=i, y=pos.y, z=pos.z + 1}, 27) end doRespaw('demon') setGlobalStorageValue(32800, delay + os.time()) addEvent(doCheck, delay*1000, t) else doPlayerSendCancel(cid, "Espere "..getGlobalStorageValue(32800) - os.time().." segundos para fazer a quest.") end else doPlayerSendCancel(cid, "Alguém no seu grupo já fez a quest.") end return TRUE end function doRespaw(mon) mon1 = {x=190, y=116, z=10, stackpos=253} -- posição demon 1 mon2 = {x=191, y=120, z=10, stackpos=253} -- posição demon 2 mon3 = {x=194, y=118, z=10, stackpos=253} -- posição demon 3 doCreateMonster(mon, mon1) doCreateMonster(mon, {x=mon1.x +2, y=mon1.y, z=mon1.z}) doCreateMonster(mon, mon2) doCreateMonster(mon, {x=mon2.x +2, y=mon2.y, z=mon2.z}) doCreateMonster(mon, mon3) doCreateMonster(mon, {x=mon3.x +1, y=mon3.y, z=mon3.z}) end function doCheck(tab) local templepos = {x=151, y=50, z=7} for i = 1, 4 do if isCreature(tab[i]) then if getPlayerStorageValue(tab[i], 32800) == -1 then doTeleportThing(tab[i], templepos) end end end for posx = mon1.x, mon1.x + 2, 2 do local monster = {x=posx, y=mon1.y, z=mon1.z, stackpos=253} if isCreature(getThingFromPos(monster).uid) then if string.lower(getCreatureName(getThingFromPos(monster).uid)) == 'demon' and isMonster(getThingFromPos(monster).uid) then doRemoveCreature(getThingFromPos(monster).uid) end end end for posx = mon2.x, mon2.x + 2, 2 do local monster = {x=posx, y=mon2.y, z=mon2.z, stackpos=253} if isCreature(getThingFromPos(monster).uid) then if string.lower(getCreatureName(getThingFromPos(monster).uid)) == 'demon' and isMonster(getThingFromPos(monster).uid) then doRemoveCreature(getThingFromPos(monster).uid) end end end for posx = mon3.x, mon3.x + 1 do local monster = {x=posx, y=mon3.y, z=mon3.z, stackpos=253} if isCreature(getThingFromPos(monster).uid) then if string.lower(getCreatureName(getThingFromPos(monster).uid)) == 'demon' and isMonster(getThingFromPos(monster).uid) then doRemoveCreature(getThingFromPos(monster).uid) end end end end
Crie um arquivo .lua em data/actions/scripts e cole o script acima nele, feito isso, em data/actions.xml, cole isto:
<action actionid="AID" event="script" value="NomeDoArquivo.lua"/>
Escolhe o actionid e coloque na alavanca e na tag.
Editando o script: Edite a posição do jogador mais próximo da alavanca, linha 3. Edite o tempo citado no funcionamento da quest, linha 5. Edite as posições dos demons, nas linhas 41, 42, 43, onde a primeira posição é onde fica o primeiro demon em cima do jogador, a segunda posição é onde fica o primeiro demon em baixo do jogador e a ultima posição é onde fica o demon ao lado do jogador.
Script - Chest:
function onUse(cid, item) local itens = { [32800] = {id = 2494, message = "Parabéns, você ganhou uma demon armor."}, [32801] = {id = 2400, message = "Parabéns, você ganhou uma magic sword."}, [32802] = {id = 2431, message = "Parabéns, você ganhou um stonecutter axe."}, [32803] = {id = 2326, message = "Parabéns, você ganhou um annihilation bear."} } if getPlayerStorageValue(cid, 32800) ~= 1 then if itens[item.actionid].id ~= 2326 then doPlayerAddItem(cid, itens[item.actionid].id, 1) else local bag = doPlayerAddItem(cid, 1990, 1) doAddContainerItem(bag, itens[item.actionid].id, 1) end doPlayerSendTextMessage(cid, 22, itens[item.actionid].message) setPlayerStorageValue(cid, 32800, 1) end return TRUE end
Crie um arquivo .lua em data/actions/scripts e cole o script acima nele, feito isso, em data/actions.xml, cole isto:
<action actionid="32800;32801;32802;32803" event="script" value="NomeDoArquivo.lua"/>
Demon Helmet
Versão: Demonbholder
Sistema: Actions
Funcionamento: Clique na alavanca e a pedra sumirá, após alguns segundos ela voltará. Os baús deverão ter os seguintes actionid: 34800, 34801, 34802.
Script - Alavanca:
function onUse(cid, item) local pedrapos = {x=151, y=51, z=7} -- posição da pedra local pedraid = 1355 -- id da pedra local time = 30 local pos = getThingPos(item.uid) if item.itemid == 1945 then for i = 1, 255 do if getThingFromPos({x=pedrapos.x, y=pedrapos.y, z=pedrapos.z, stackpos=i}).itemid == pedraid then doRemoveItem(getThingFromPos({x=pedrapos.x, y=pedrapos.y, z=pedrapos.z, stackpos=i}).uid, 1) doTransformItem(item.uid, 1946) addEvent(doCreatePedra, 1000*time, pedraid, pedrapos, pos) break else return doPlayerSendCancel(cid, "A pedra ainda não voltou.") end end else return doPlayerSendCancel(cid, "A pedra ainda não voltou.") end return TRUE end function doCreatePedra(id, pos1, pos2) doCreateItem(id, pos1) for i = 1, 255 do local position = {x=pos2.x, y=pos2.y, z=pos2.z, stackpos=i} if getThingFromPos(position).itemid == 1946 then stack = i break end end local posa = {x=pos2.x, y=pos2.y, z=pos2.z, stackpos=stack} doTransformItem(getThingFromPos(posa).uid, 1945) end
Crie um arquivo .lua em data/actions/script e cole o script acima nele, feito isso, cole esta tag em data/actions/actions.xml:
<action actionid="AID" event="script" value="NomeDoArquivo.lua"/>
Escolha um actionid e coloque na alavanca e na tag.
Editando o script: Edite a posição da pedra, linha 3, o id da pedra, linha 4 e o tempo que a pedra ficará removida, linha 5.
Script - Chest:
function onUse(cid, item) local itens = { [34800] = {id = 2493, message = "Parabéns, você ganhou um demon helmet."}, [34801] = {id = 2520, message = "Parabéns, você ganhou um demon shield."}, [34002] = {id = 2645, message = "Parabéns, você ganhou uma steel boots."} } if getPlayerStorageValue(cid, 34800) < 2 then doPlayerSendTextMessage(cid, 22, itens[item.actionid].message) doPlayerAddItem(cid, itens[item.actionid].id, 1) setPlayerStorageValue(cid, 34800, getPlayerStorageValue(cid, 34800) + 1) else doPlayerSendCancel(cid, "Você já fez esta quest.") end return TRUE end
Crie um arquivo .lua em data/actions/script e cole o script acima nele e depois em data/actions/actions.xml, cole a seguinte tag:
<action actionid="34800;34801;34802" event="script" value="NomeDoArquivo.lua"/>
Arena Svargrond
Versão: Demonbholder
Sistema: Mod
Detalhes: Script semelhante a Arena Svargrond do Tibia, pelo qual se desafia 10 monstros. Disponível em apenas 1 dificuldade.
Funcionamento: O jogador deve ir em um piso que tenha o actionid 40001 e será teleportado para a arena. Feito isso, ele irá pisar no piso com actionid 40000 e um monstro será criado, ele deverá lutar contra esse monstro. Após matar 10 monstros, o jogador é teleportado para sala de recompensa.
Script:
<?xml version="1.0" encoding="UTF-8"?> <mod name="Arena Svargrond" enabled="yes" author="Demonbholder" forum="XTibia.com"> <config name="ArenaLib"><![CDATA[ dinheiro = 10000 storage = 47000 storage2 = 47001 playerpos = {x=151, y=48, z=7} -- posicao da arena trofypos = {x=151, y=48, z=7} -- posicao da area apos a arena monpos = {x=151, y=48, z=7} -- posicao onde o monstro sera criado monsters = { [0] = 'rat', [1] = 'dwarf', [2] = 'minotaur guard', [3] = 'demon skeleton', [4] = 'dragon', [5] = 'vampire', [6] = 'giant spider', [7] = 'dragon lord', [8] = 'warlock', [9] = 'demon' } function doRemoveCorpse(pos) for i = 1, 255 do corp = {x=pos.x, y=pos.y, z=pos.z, stackpos=i} if isCorpse(getThingFromPos(corp).uid) then break end end doRemoveItem(getThingFromPos(corp).uid, 1) end ]]></config> <creaturescript type="death" name="Arena" event="script"><![CDATA[ domodlib('ArenaLib') if isPlayer(deathList[1]) and isMonster(cid) then if getPlayerStorageValue(deathList[1], storage) > -1 and getPlayerStorageValue(deathList[1], storage) < 10 then setPlayerStorageValue(deathList[1], storage, getPlayerStorageValue(deathList[1], storage) + 1) addEvent(doRemoveCorpse, 500, getCreaturePosition(cid)) setPlayerStorageValue(deathList[1], storage2, -1) end if getPlayerStorageValue(deathList[1], storage) == 10 then doTeleportThing(deathList[1], trofypos) end end return TRUE ]]></creaturescript> <creaturescript type="kill" name="ArenaK" event="script"><![CDATA[ domodlib('ArenaLib') if isMonster(cid) and isPlayer(target) then if getPlayerStorageValue(target, storage) > -1 and getPlayerStorageValue(target, storage) < 10 then setPlayerStorageValue(target, storage, -1) setPlayerStorageValue(target, storage2, -1) doRemoveCreature(cid) addEvent(doRemoveCorpse, 500, getCreaturePosition(target)) end end return TRUE ]]></creaturescript> <creaturescript type="logout" name="ArenaL" event="script"><![CDATA[ domodlib('ArenaLib') if getPlayerStorageValue(cid, storage) > -1 and getPlayerStorageValue(cid, storage) < 10 then return FALSE, doPlayerSendCancel(cid, "You can't logout during arena!") end return TRUE ]]></creaturescript> <movevent type="StepIn" actionid="40000" event="script"><![CDATA[ domodlib('ArenaLib') if monsters[getPlayerStorageValue(cid, storage)] then if getPlayerStorageValue(cid, storage2) == -1 then local mon = doCreateMonster(monsters[getPlayerStorageValue(cid, storage)], monpos) setPlayerStorageValue(cid, storage2, 1) registerCreatureEvent(mon, "Arena") registerCreatureEvent(mon, "ArenaK") end end return TRUE ]]></movevent> <movevent type="StepIn" actionid="40001" event="script"><![CDATA[ domodlib('ArenaLib') for _, pid in pairs(getPlayersOnline()) do if (getPlayerStorageValue(pid, storage) > -1 and getPlayerStorageValue(pid, storage) < 10) or getPlayerStorageValue(cid, storage) == 10 then return TRUE, doTeleportThing(cid, fromPosition) end end if getPlayerMoney(cid) < dinheiro then return TRUE, doTeleportThing(cid, fromPosition), doPlayerSendCancel(cid, "Voce nao tem dinheiro.") end doPlayerRemoveMoney(cid, dinheiro) setPlayerStorageValue(cid, storage, 0) doPlayerSendTextMessage(cid, 4, "Arena Svargrond!") return TRUE, doTeleportThing(cid, playerpos) ]]></movevent> </mod>
Crie um arquivo .xml em mods e cole este script nele, nada mais precisa ser feito.
Editando o script: Logo no início do mod você deve mudar as posições da sala de recompensas, de onde os monstros vão ser criados e de onde fica a arena. É possível mudar os monstros também. Lembrando que o actionid dos pisos devem ser 40000 para o de entrada na arena e 40001 para criar os monstros.
Só irei avaliar pedidos de quests que tiverem explicações e forem do tibia. Favor avisar caso seja encontrado alguma falha.
Por enquanto é isso galera, com o tempo eu irei adicionando mais quests. Espero que aproveitem, até mais.