Últimas atualizações:
16/12/2013:
- Adicionei uma configuração do número mínimo de players que o evento precisa para começar, se não atingir esse mínimo, o evento é fechado e já fica preparado para quando for acontecer novamente. Os jogadores que entraram são teleportados para o templo.
- Coloquei um tempo máximo de permanêcncia no evento, se o player ficar X minutos no evento, ele é teleportado para o templo.
- Retirei todos os bugs que podiam acontecer no evento:
- O monstros (Guarda do Portao e Arcanjo) não são criados novamente caso já estejam em suas devidas posições
- Caso alguém morra no evento, o evento entende que tem um participante a menos.
- Após o tempo máximo de duração do evento, o script faz uma checagem para garantir que esteja tudo certo. Se algo estiver errado, o script arruma.
- Caso o seu servidor caia durante o evento, quando o servidor for aberto novamente, todos os participantes do evento são teleportados para o templo e o script já prepara o evento para - -quando for acontecer de novo.
[ATUALIZADO 12/04/2014]
Introdução:
Eai gente, vcs conhecem o evento Blood Castle que tem no jogo MU? Então, eu resolvi criar esse evento para OpenTibia e ficou bem legal
- Informações:
Versões testadas: TFS 0.4, TFS 0.3.6 e Real Server 3.1
Como funciona: A cada X intervalo de tempo (ou manualmente) , o evento é anunciado e um teleporte é criado, os jogadores então ficam na sala de espera até o evento começar. Quando ele começa, os jogadores devem matar os monstros até chegarem no portão do castelo, no portão eles devem matar o Guarda para passar. Quando o guarda morre, eles entram no castelo, e vão matando os monstros até a estátua do Arcanjo aparecer. Depois que ela aparece, os jogadores tem que quebrar ela, aquele que causou mais dano na estátua é o vencedor e recebe um prêmio.
OBS: NÃO é obrigatório o uso do mapa que vou por aqui, ele serve somente para exemplo.
#Dica: Acho que fica legal o premio do evento ser um item que da double exp por um tempo.
Atualização:
Resolvi refazer o código, para facilitar a instalação e melhorar o funcionamento do evento.
O que mudou?
- Reduzi bastante o código
- Reduzi a quantidade de arquivos para facilitar a instalação
- Otimizei o código (refiz algumas funções e algumas partes do código)
- Passei o nome das funções para ingles, para ficar mais bonito rs
Instalando o evento:
Lib:
Na pasta data/lib crie um arquivo .lua chamado BloodCastle e cole esse código:
-- == Blood Castle Event por Killua - Xtibia.com == -- bloodconfig = { templo = {x = 160, y = 51, z = 7}, -- templo posGuarda = {x = 29, y = 263, z = 7}, -- Onde o guarda do portão vai nascer premios = {{6527, 10}, {2160, 20}}, -- Premios que o vencedor vai ganhar {id, quantidade} positionTP = {x = 157, y = 44, z = 7}, -- Onde o tp será criado positionEvento = {x = 30, y = 314, z = 7}, -- Para onde o tp vai levar tempoTP = 2, -- Depois de quanto tempo que avisou vai ser criado o tp? Em minutos tempoAberto = 5, -- Tempo que o tp fica aberto. Em minutos minPlayers = 3, -- Número mínimo de players que devem entrar para que o evento aconteça tempoMaximo = 40, -- Tempo máximo, em minutos, que alguem pode permanecer no evento playersStorage = 54910, -- Não mude posPedras = {{x = 27, y = 304, z = 7, stackpos=1}, {x = 28, y = 304, z = 7, stackpos=1}, {x = 29, y = 304, z = 7, stackpos=1}, {x = 30, y = 304, z = 7, stackpos=1}, {x = 31, y = 304, z = 7, stackpos=1}}, -- Posições das pedras que bloqueiam a entrada do evento idDasParedes = 9486, -- ID das paredes que vao ser removidas quando o Guarda morrer (todas devem ter o mesmo id) estatua = {x = 29, y = 242, z = 7}, -- Posicao onde o arcanjo vai ser criado tempoSaida = 70, -- Quando tempo o tp q é criado quando a estátua morre vai ficar? Em segundos posParedes = {{x = 28, y = 262, z = 7, stackpos=1}, {x = 29, y = 262, z = 7, stackpos=1}, {x = 30, y = 262, z = 7, stackpos=1}}, -- Posições das paredes que ficam atrás do guarda fromPos = {x = 12, y = 237, z = 7}, -- Canto superior esquerdo da área do seu evento ---- Deve ser uma área quadrada ou retangular, de forma que todo o evento fique dentro dela. toPos = {x = 44, y = 323, z = 7}, -- Canto inferior direito da área do seu evento } -- [[ NAO ALTERE MAIS NADA DAQUI PARA BAIXO! ]] -- function removeTpb() local t = getTileItemById(bloodconfig.positionTP, 1387) if t then doRemoveItem(t.uid, 1) doSendMagicEffect(bloodconfig.positionTP, CONST_ME_POFF) end end function removeStones() for i = 1, #bloodconfig.posPedras do local pedra = getTileItemById(bloodconfig.posPedras[i], 1304) if pedra then doRemoveItem(pedra.uid, 1) end end end function putStones() for i = 1, #bloodconfig.posPedras do local pedra = getTileItemById(bloodconfig.posPedras[i], 1304) if not pedra then doCreateItem(1304, 1, pedra) end end end function createTeleportb() local tip = doCreateTeleport(1387, bloodconfig.positionEvento, bloodconfig.positionTP) doItemSetAttribute(tip, "aid", 4726) end function removeTpa() local t = getTileItemById(bloodconfig.estatua, 1387) if t then doRemoveItem(t.uid, 1) doSendMagicEffect(bloodconfig.estatua, CONST_ME_POFF) end end function getPlayersInBlood() local playersInBlood = getGlobalStorageValue(bloodconfig.playersStorage) return playersInBlood < 0 and 0 or playersInBlood end function removePlayers() for _, pid in pairs(getPlayersOnline()) do if isInArea(getThingPos(pid), bloodconfig.fromPos, bloodconfig.toPos) then doTeleportThing(pid, bloodconfig.templo, false) doPlayerSendTextMessage(pid, MESSAGE_STATUS_CONSOLE_BLUE, "Voce foi removido do Blood Castle. Possiveis causas: o evento nao atingiu o numero minimo de players; Voce permaneceu no evento por mais de " .. bloodconfig.tempoMaximo .. " minutos.") end end end function checkBlood() if getPlayersInBlood() >= bloodconfig.minPlayers then removeStones() doBroadcastMessage("[Blood Castle] O Evento comecou e o teleporte para ele foi fechado. Boa sorte a todos!") if not isMonster(getTopCreature(bloodconfig.posGuarda).uid) then doCreateMonster("Guarda do Portao", bloodconfig.posGuarda) end addEvent(removePlayers, bloodconfig.tempoMaximo*60*1000) else removePlayers() setGlobalStorageValue(bloodconfig.playersStorage, 0) doBroadcastMessage("[Blood Castle] O evento nao atingiu o numero minimo de participantes e foi cancelado.") if isMonster(getTopCreature(bloodconfig.posGuarda).uid) then doRemoveCreature(getTopCreature(bloodconfig.posGuarda).uid) end if isMonster(getTopCreature(bloodconfig.estatua).uid) then doRemoveCreature(getTopCreature(bloodconfig.estatua).uid) end end end function putWalls() for i = 1, #bloodconfig.posParedes do doCreateItem(bloodconfig.idDasParedes, 1, bloodconfig.posParedes[i]) end end function removeWalls() for i = 1, #bloodconfig.posParedes do local wall = getTileItemById(bloodconfig.posParedes[i], bloodconfig.idDasParedes) if wall then doRemoveItem(wall.uid, 1) end end end function createAngel() if not isMonster(getTopCreature(bloodconfig.estatua).uid) then doCreateMonster("Arcanjo", bloodconfig.estatua) doBroadcastMessage("[Blood Castle] A estatua do arcanjo apareceu!") end end function Guarantee() if isMonster(getTopCreature(bloodconfig.posGuarda).uid) then putWalls() doRemoveCreature(getTopCreature(bloodconfig.posGuarda).uid) elseif isMonster(getTopCreature(bloodconfig.estatua).uid) then putStones() putWalls() doRemoveCreature(getTopCreature(bloodconfig.estatua).uid) end end
Movements:
Em data/movements/scripts crie um arquivo .lua chamado BloodMovement e coloque esse código:
-- == Blood Castle Event por Killua - Xtibia.com == -- function onStepIn(cid, item, position, lastPosition, fromPosition, toPosition, actor) if item.actionid == 4726 then setGlobalStorageValue(bloodconfig.playersStorage, getPlayersInBlood()+1) print(getPlayersInBlood().. " Jogadores no Blood Castle") elseif item.actionid == 9371 then setGlobalStorageValue(bloodconfig.playersStorage, getPlayersInBlood()-1) print(getPlayersInBlood().. " Jogadores no Blood Castle") end return true end
TAG do movements.xml:
<movevent type="StepIn" actionid="4726;9371" event="script" value="BloodMovement.lua"/>
Creaturescripts:
Em data/creaturescripts/scripts crie um arquivo .lua chamado BloodCreatureGuarda e coloque esse código:
-- == Blood Castle Event por Killua - Xtibia.com == -- function onDeath(cid, corpse, mostDamageKiller) local artigo = getPlayerSex(mostDamageKiller[1]) == 0 and "A jogadora" or "O jogador" if isMonster(cid) and string.lower(getCreatureName(cid)) == string.lower("Guarda do Portao") then removeWalls() addEvent(createAngel, 2*60*1000) doBroadcastMessage("[Blood Castle] " .. artigo .. " " .. getPlayerName(mostDamageKiller[1]) .. " derrotou o Guarda do Portao! Prossigam para proxima sala e aguardem ate o arcanjo nascer!") end return true end
Na mesma pasta, crie um arquivo .lua chamado BloodCreatureAnjo e coloque esse código:
-- == Blood Castle Event por Killua - Xtibia.com == -- function onDeath(cid, corpse, mostDamageKiller) local artigo = getPlayerSex(mostDamageKiller[1]) == 0 and "A jogadora" or "O jogador" if isMonster(cid) and string.lower(getCreatureName(cid)) == string.lower("Arcanjo") then doBroadcastMessage("[Blood Castle] " .. artigo .. " " .. getPlayerName(mostDamageKiller[1]) .. " destruiu a estatua do Arcanjo e foi o vencedor da rodada!") for _, premio in pairs(bloodconfig.premios) do doPlayerAddItem(mostDamageKiller[1], premio[1], premio[2]) end doPlayerSendTextMessage(mostDamageKiller[1], 25, "Parabens voce venceu o evento Blood Castle!") doSendMagicEffect(getCreaturePosition(mostDamageKiller[1]), 66) doCreateTeleport(1387, bloodconfig.templo, bloodconfig.estatua) addEvent(removeTpa, bloodconfig.tempoSaida*1000) setGlobalStorageValue(bloodconfig.playersStorage, 0) putWalls() putStones() end return true end
Ainda na mesma pasta crie um arquivo .lua chamado BloodCreature e coloque esse código:
-- == Blood Castle Event por Killua, antigo - Xtibia.com == -- function onDeath(cid, corpse, mostDamageKiller) if isPlayer(cid) and isInArea(getCreaturePosition(cid), bloodconfig.fromPos, bloodconfig.toPos) then setGlobalStorageValue(bloodconfig.playersStorage, getPlayersInBlood()-1) end return true end function onLogin(cid) if isInArea(getCreaturePosition(cid), bloodconfig.fromPos, bloodconfig.toPos) then doTeleportThing(cid, bloodconfig.templo, false) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, "Voce estava no meio do evento Blood Castle quando o servidor caiu. Voce foi teleportado para o templo.") end registerCreatureEvent(cid, "morrerblood") registerCreatureEvent(cid, "guardablood") registerCreatureEvent(cid, "arcanjoblood") return true end
TAGs no creaturescripts.xml
<event type="death" name="guardablood" event="script" value="BloodCreatureGuarda.lua"/> <event type="death" name="arcanjoblood" event="script" value="BloodCreatureAnjo.lua"/> <event type="death" name="morrerblood" event="script" value="BloodCreature.lua"/> <event type="death" name="loginblood" event="script" value="BloodCreature.lua"/>
Monsters:
Em data/monsters crie uma pasta chamada Blood Castle coloque esses dois códigos:
Guarda do Portao.xml:
<?xml version="1.0" encoding="UTF-8"?> <monster name="Guarda do Portao" nameDescription="the Guarda do Portao" race="undead" experience="500000" speed="0" manacost="0"> <health now="1000000" max="1000000"/> <look type="268" head="114" body="114" legs="114" feet="114" addons="3" corpse="6080"/> <targetchange interval="5000" chance="0"/> <strategy attack="0" defense="0"/> <script> <event name="guardablood"/> </script> <flags> <flag summonable="0"/> <flag attackable="1"/> <flag hostile="1"/> <flag illusionable="0"/> <flag convinceable="0"/> <flag pushable="0"/> <flag canpushitems="0"/> <flag canpushcreatures="1"/> <flag targetdistance="1"/> <flag staticattack="90"/> <flag runonhealth="100"/> </flags> <defenses armor="1" defense="1"/> <immunities> <immunity poison="1"/> <immunity lifedrain="1"/> <immunity paralyze="1"/> <immunity outfit="1"/> <immunity drunk="1"/> <immunity invisible="1"/> </immunities> </monster>
Arcanjo.xml:
<?xml version="1.0" encoding="UTF-8"?> <monster name="Arcanjo" nameDescription="the Arcanjo" race="undead" experience="500000" speed="0" manacost="0"> <health now="1000000" max="1000000"/> <look typeex="9751"/> <targetchange interval="5000" chance="0"/> <strategy attack="0" defense="0"/> <script> <event name="arcanjoblood"/> </script> <flags> <flag summonable="0"/> <flag attackable="1"/> <flag hostile="1"/> <flag illusionable="0"/> <flag convinceable="0"/> <flag pushable="0"/> <flag canpushitems="0"/> <flag canpushcreatures="1"/> <flag targetdistance="1"/> <flag staticattack="90"/> <flag runonhealth="100"/> </flags> <defenses armor="1" defense="1"/> <immunities> <immunity poison="1"/> <immunity lifedrain="1"/> <immunity paralyze="1"/> <immunity outfit="1"/> <immunity drunk="1"/> <immunity invisible="1"/> </immunities> </monster>
Em monsters.xml coloque essas TAGs:
<monster name="Guarda do Portao" file="Blood Castle/Guarda do Portao.xml"/> <monster name="Arcanjo" file="Blood Castle/Arcanjo.xml"/>
-- == Blood Castle Event por Killua - Xtibia.com == -- function onThink(cid, interval) local plural = bloodconfig.tempoTP == 1 and "minuto" or "minutos" local plurals = bloodconfig.tempoAberto == 1 and "minuto" or "minutos" doBroadcastMessage("[Blood Castle] O portal para o evento vai ser aberto em " .. bloodconfig.tempoTP .. " " .. plural .. ", nao percam!") addEvent(createTeleportb, bloodconfig.tempoTP*60*1000) addEvent(doBroadcastMessage, bloodconfig.tempoTP*60*1000, "[Blood Castle] O teleport para o evento foi aberto no templo e vai sumir em " .. bloodconfig.tempoAberto .. " " .. plurals .. ". Se apressem!") addEvent(removeTpb, bloodconfig.tempoTP+bloodconfig.tempoAberto*60*1000) addEvent(checkBlood, bloodconfig.tempoTP+bloodconfig.tempoAberto*60*1000+60*1000) addEvent(Guarantee, bloodconfig.tempoMaximo*60*1000+15000) return true end function onStartup() setGlobalStorageValue(bloodconfig.playersStorage, 0) print(getPlayersInBlood().. "Jogadores no Blood Castle") return true end
TAGS no globalevents.xml:
<globalevent name="bloodstart" type="start" event="script" value="BloodGlobalEvent.lua"/> <globalevent name="Blood Castle" interval="6000000" event="script" value="BloodGlobalEvent.lua"/>
Manual:
Talkactions:
Em data/talkactions/scripts crie BloodTalk.lua e coloque esse código:
-- == Blood Castle Event por Killua - Xtibia.com == -- function onSay(cid, words, param, channel) local plural = bloodconfig.tempoTP == 1 and "minuto" or "minutos" local plurals = bloodconfig.tempoAberto == 1 and "minuto" or "minutos" doBroadcastMessage("[Blood Castle] O portal para o evento vai ser aberto em " .. bloodconfig.tempoTP .. " " .. plural .. ", nao percam!") addEvent(createTeleportb, bloodconfig.tempoTP*60*1000) addEvent(doBroadcastMessage, bloodconfig.tempoTP*60*1000, "[Blood Castle] O teleport para o evento foi aberto no templo e vai sumir em " .. bloodconfig.tempoAberto .. " " .. plurals .. ". Se apressem!") addEvent(removeTpb, bloodconfig.tempoTP+bloodconfig.tempoAberto*60*1000) addEvent(checkBlood, bloodconfig.tempoTP+bloodconfig.tempoAberto*60*1000+60*1000) addEvent(Guarantee, bloodconfig.tempoMaximo*60*1000+15000) return true end
TAG talkactions.xml:
<talkaction log="yes" words="/blood-start" access="5" event="script" value="BloodTalk.lua"/>
Globalevents:
Em data/globalevents/scripts crie BloodGlobalStart.lua e coloque:
-- == Blood Castle Event por Killua - Xtibia.com == -- function onStartup() setGlobalStorageValue(bloodconfig.playersStorage, 0) print(getPlayersInBlood().. "Jogadores no Blood Castle") return true end
TAG globalevents.xml
<globalevent name="bloodstart" type="start" event="script" value="BloodGlobalStart.lua"/>
Como Configurar:
* Se você for colocar, dentro do evento, um teleporte para as pessoas que não quiserem mais participar, coloque o Action ID 9371 nele.
* Lembre-se de por NO-LOGOUT tool e NO-PVP tool em toda área do evento!!
Todas as demais explicações estão na lib, mas vou demonstrar como configurar os mais "confusos".
No modo automático, você configura de quanto em quanto o tempo o evento vai acontecer. Nessa tag:
<globalevent name="Blood Castle" interval="3600" event="script" value="BloodGlobalEvent.lua"/>
Aqui está 3600 segundos, ou seja, 1 hora.
* Se seu servidor for em milisegundos, multiplique o número por 1000, assim: 3600 segundos * 1000 = 3600000 milisegundos = 1 hora.
No modo manual, para iniciar o evento, basta usar a talkaction /blood-start com seu god.




