Belíssimo script, estou louco para testar :smile_positivo: :smile_positivo:
- Fórum
- OTServ
- Recursos
- Scripting
- Globalevents e Spells
- Luna Event + bonus spell (inspirado no sot#01)
SK
globalevent
Luna Event + bonus spell (inspirado no sot#01)
Por Skulls, 11 de jan. de 2016 em Globalevents e Spells
luna
evento
spell
frozen
luna event
sot
sot#1
sot#01
3
2.4k
info
Grupo: Administrador
Registrado: 08/07/05
Posts: 5.8k
Reputação: +1.4k
Gênero: Outro

11 de janeiro de 2016 às 19:10
info
Grupo: Herói
Registrado: 25/02/07
Posts: 859
Reputação: +331
Gênero: Masculino

11 de janeiro de 2016 às 19:35
Belíssimo script, estou louco para testar :smile_positivo: :smile_positivo:
Muito obrigado! Quando testar me diga o que achou, ![]()
Descobri hoje que em algumas versões do baiak existe um evento parecido, porém com fogo, chamado fire storm (ou algo assim). Mas eu achei a de gelo mais legal, rsrs


info
Grupo: Herói
Registrado: 25/02/07
Posts: 859
Reputação: +331
Gênero: Masculino
Fala galera, tudo bem?
Então, eu li o sot#01 alguns dias atrás e achei bem legal a história no qual ele gira em torno.
Tive algumas idéias e, mesmo o evento não tendo acontecido por falta de inscritos, resolvi fazer pra lembrar algumas coisas, afinal tinha uns 7 anos que não mexia com scripts para otserv.
O resultado, que vou mostrar abaixo, é um evento global (mas que pode muito bem ser adaptado para uma quest ou outra finalidade). Como parte da recompensa do evento, fiz de bonus uma spell baseada na frozenOrb do whitewolf.
Bom vamos lá.
O Evento
Basicamente é um evento estilo aquela brincadeira antiga de criança "dança das cadeiras".
Como assim?
Bom, na área do evento o número de espaços vazios vai ser sempre o número de players restantes no evento -1. Isso implica que, em cada turno, pelo menos um player deixará o evento.
Contexto
Luna é uma estrela endeusada pelos elfos e muito poderosa. De tempo em tempo ela se desperta todos os players onlines são convocados para tentarem domar a sua ira. Aquele que sobreviver à ira de Luna sem se congelar será capaz de controlar seu poder até o próximo despertar.
editado: Esqueci de avisar que coloquei para ele ignorar o tile central na contagem de tiles livres pois no tile central, do meu mapa, eu coloquei um frozen starlight representando a luna e, a cada round, há uma animação na luna só para ficar bonitinho.
Crie um arquivo chamado lunaevent.lua dentro de scripts e coloque o código abaixo nele:
--[[Variáveis de configuração]]-- local config = { hour = "5 Horas", -- Time to next event (only for broadcast message, real time you can set on globalevents.xml) reward_id = 2361, -- Reward ID frozen_humans = {7303, 7304, 7305, 7306, 7307, 7308, 7309, 7310, 7311, 7312, 7172}, -- Frozen human ids area = {center = {x = 102, y = 182, z = 7}, side = 4}, -- Area do evento centrada em center, a capacidade da área é effects = {luna = 28, alert = 72, init = 41, frozen = 43}, -- de (1+2*side)^2 menos os itens imóveis do mapa (ex frozen humans) storage = 5544 --storage que vai definir quem pode usar o poder de luna } --[[Gera um array de numeros aleatorios distintos]]-- function getRandomArray(n, max) rand = {} flag = {} for i = 0, n do rand[i] = math.random(0, max) while flag[rand[i]] ~= nil do rand[i] = math.random(0, max) end flag [rand[i]] = i end return rand end --[[Remove os frozen humman ao final do evento]]-- function clearEventArea() for i, tile in pairs(getArea(config.area.center, config.area.side, config.area.side)) do tile.stackpos = 1 tmp = getThingFromPos(tile) if tmp.uid ~= 0 then if isCreature(tmp.uid) == false then item_id = getItemIdByName(getItemDescriptions(tmp.uid).name) for k, v in pairs(config.frozen_humans) do if item_id == v then doRemoveItem(tmp.uid, math.min(math.max(1, tmp.type), 1)) end end end end end end --[[Conta quantos players ainda estão no evento]]-- function countPlayers() result = 0 for i, tile in pairs(getArea(config.area.center, config.area.side, config.area.side)) do tile.stackpos = STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE tmp = getThingFromPos(tile) if isPlayer(tmp.uid) then result = result + 1 end end return result end --[[Congela o Player que for pego]]-- function removePlayer(rand, tiles) for i = 0, #rand do tmp = getThingFromPos(tiles[rand[i]]) if isPlayer(tmp.uid) then random = config.frozen_humans[math.random(1, #config.frozen_humans)] doCreateItem(random, 1, tiles[rand[i]]) doTeleportThing(tmp.uid, getTownTemplePosition(getPlayerTown(tmp.uid))) end end end --[[Efeitos do evento]]-- function lunaFalls(pos) addEvent(doSendMagicEffect, 2000, pos, config.effects.init) addEvent(doSendMagicEffect, 3000, pos, config.effects.init) addEvent(doSendMagicEffect, 4000, pos, config.effects.init) addEvent(doSendMagicEffect, 6000, pos, config.effects.frozen) end --[[Execução do evento]]-- function lunaEvent(n, round) x = round or 0 if countPlayers() == 0 and x > 0 then doBroadcastMessage("[Luna Event] Ninguém conseguiu controlar o poder de luna. Em " .. config.hour .. " Luna ascenderá novamente.") setGlobalStorageValue(config.storage, -1) clearEventArea() elseif (countPlayers() == 1 and x > 0) or n == 0 then for i, tile in pairs(getArea(config.area.center, config.area.side, config.area.side)) do tile.stackpos = STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE tmp = getThingFromPos(tile) if isPlayer(tmp.uid) then winner = getCreatureName(tmp.uid) doBroadcastMessage("[Luna Event] " .. winner .. " provou-se corajoso e domou a ira de Luna.") doBroadcastMessage("[Luna Event] Nas próximas " .. config.hour .. " Luna ficará sobre o controle de " .. winner .. ".") setGlobalStorageValue(config.storage, winner) item = doPlayerAddItem(getPlayerByName(winner), config.reward_id, 1) doSetItemSpecialDescription(item, "It's a souvenir from Luna Event. Winner: " .. winner) doTeleportThing(getPlayerByName(winner), getTownTemplePosition(getPlayerTown(tmp.uid))) clearEventArea() end end else --[[Preenche um array com os tiles da área do evento que podem ser usados para o evento. São considerados tiles "cheios" somente aqueles que possuem detalhes de mapa que impossibilitam mover sobre e o tile central, onde fica a estrela luna ]]-- local j = 0 local emptyTiles = {} for i, tile in pairs(getArea(config.area.center, config.area.side, config.area.side)) do tile.stackpos = 1 tmp = getThingFromPos(tile) tile.stackpos = STACKPOS_TOP_MOVEABLE_ITEM_OR_CREATURE tmp2 = getThingFromPos(tile) if (tmp.uid == 0) or (tmp2.uid ~= 0 and (tile.x ~= config.area.center.x and tile.y ~= config.area.center.y)) or isCreature(tmp.uid) then emptyTiles[j] = tile j = j + 1 end end rand = getRandomArray(#emptyTiles - n, #emptyTiles) doSendMagicEffect(config.area.center, config.effects.luna) for i = 0, #emptyTiles do addEvent(doSendMagicEffect, 1000, emptyTiles[i], config.effects.alert) end for i = 0, #emptyTiles - n do lunaFalls(emptyTiles[rand[i]]) end addEvent(removePlayer, 6000, rand, emptyTiles) addEvent(lunaEvent, 12000, n-1, x + 1) end end function onThink(interval, lastExecution) doBroadcastMessage("[Luna Event] Luna despertou. Todos os players online foram convocados para tentar domar seu poder.") --[[Checa se há alguém online, se não houver o evento acaba]]-- if(getWorldCreatures(0) == 0)then doBroadcastMessage("[Luna Event] Ninguém participou do evento. Em " .. config.hour .. " Luna ascenderá novamente.") setGlobalStorageValue(config.storage, -1) clearEventArea() return true end --[[Traz todos os players online para o evento. Poderia ser um portal mas fiquei com preguiça de configurar, assim foi mais prático]]-- local n = #getPlayersOnline() for k, tid in pairs(getPlayersOnline()) do doTeleportThing(tid, {x = config.area.center.x, y = config.area.center.y + 2, z = config.area.center.z}) end lunaEvent(n-1) return true endEm globalevents.xml coloque a tag:
A recompensa do evento é uma souvenir, um frozen starlight com o nome do vencedor do evento e x horas (no caso 5) podendo utilizar o poder de luna.
Bom, eu criei uma spell para ilustrar o poder de luna e como utilizar o storage que foi preenchido para o vencedor do evento para controlar o uso de uma spell.
Luna Strike
Primeiramente adicione a tag abaixo em spells.xml:
<instant name="Luna Strike" words="exori luna" lvl="100" manapercent="5" prem="0" range="6" casterTargetOrDirection="1" blockwalls="1" exhaustion="10000" groups="1,4000" icon="156" needlearn="0" event="script" value="attack/luna strike.lua"> <vocation id="1"/> <vocation id="2"/> <vocation id="3"/> <vocation id="4"/> <vocation id="5"/> <vocation id="6"/> <vocation id="7"/> <vocation id="8"/> </instant>Crie um arquivo chamado luna strike.lua dentro de scripts/attacks e coloque o código abaixo nele:
local config = { speed = 400, hits = 15, frozen_humans = {7303, 7304, 7305, 7306, 7307, 7308, 7309, 7310, 7311, 7312, 7172}, effects = {hit = 43, spin = 36, big_spin = 28}, storages = {event = 5545, use = 5544}, cooldown = 10, msg = "Luna's Rage" } --local local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, 255) --setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) setCombatFormula(combat, COMBAT_FORMULA_LEVELMAGIC, -5, -11, -7, -24, 2, 2, 0, 0) function backToMovement(target) if isCreature(target) == true then doCreatureSetNoMove(target, false) end end function onTargetCreature(cid, target) local chance = math.random(1, 18) if getGlobalStorageValue(5545) == -1 and isPlayer(target) and chance == 1 then registerCreatureEvent(target, "NoAtt") registerCreatureEvent(target, "NoSpell") registerCreatureEvent(target, "NoTgt") setGlobalStorageValue(config.storages.event, 1) addEvent(setGlobalStorageValue, 3000, 5545, -1) end chance = math.random(1, 15) if chance == 1 then doSendMagicEffect(getCreaturePosition(target), config.effects.hit) doCreatureSetNoMove(target, true) doSetItemOutfit(target, config.frozen_humans[math.random(1, #config.frozen_humans)], 1500) addEvent(backToMovement, 1800, target) end end setCombatCallback(combat, 4, "onTargetCreature") local arr = { {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 3, 1, 1}, {1, 1, 1, 1, 1}, {1, 1, 1, 1, 1} } local area = createCombatArea(arr) setCombatArea(combat, area) function initEffect(position) for i = 0, 7 do local dir = {} local pos = {x = position.x, y = position.y, z = position.z} if (i > 3) then dir = getPosByDir(getPosByDir(pos, i), i) else dir = getPosByDir(pos, i) end doSendDistanceShoot(position, dir, config.effects.spin) end return true end function cornerEffect(position, count) n = count or 0 if n < 6 then for i = 4, 7 do local pos = {x = position.x, y = position.y, z = position.z} local dir = getPosByDir(getPosByDir(pos, i), i) doSendMagicEffect(dir, config.effects.hit) end addEvent(cornerEffect, 1000, position, n + 1) end end function spin(cid, var, position, hits, count) n = count or 0 if n%5 == 0 then doCreatureAddMana(cid, -115) end if isCreature(cid) and n < hits then for i = 0, 3 do local pos = {x = position.x, y = position.y, z = position.z} local pos2 = {x = position.x, y = position.y, z = position.z} local dir = getPosByDir(pos, i) local dir2 = getPosByDir(pos2, i + 1 <= 3 and i + 1 or 0) doSendDistanceShoot(dir, dir2, config.effects.spin) dir = getPosByDir(getPosByDir(pos, i), i) dir2 = getPosByDir(getPosByDir(pos2, i + 1 <= 3 and i + 1 or 0), pos2, i + 1 <= 3 and i + 1 or 0) doSendDistanceShoot(dir2, dir, config.effects.big_spin) end doCombat(cid, combat, var) addEvent(spin, config.speed, cid, var, position, hits, n + 1) end return true end function endEffect(position) for i = 0, 7 do local dir = {} local pos = {x = position.x, y = position.y, z = position.z} if (i > 3) then dir = getPosByDir(getPosByDir(pos, i), i) else dir = getPosByDir(pos, i) end doSendDistanceShoot(dir, position, config.effects.spin) end return true end function onCastSpell(cid, var) if getGlobalStorageValue(config.storages.use) == getCreatureName(cid) and getPlayerStorageValue(cid, config.storages.use) - os.time() <= 0 then setPlayerStorageValue(cid, config.storages.use, os.time() + config.cooldown) local pos = {} if getCreatureTarget(cid) ~= 0 then pos = getCreaturePosition(getCreatureTarget(cid)) else pos = getCreatureLookPosition(cid) end doCreatureSay(cid, config.msg, TALKTYPE_MONSTER_SAY) initEffect(pos) addEvent(spin, 1000, cid, var, pos, config.hits) addEvent(cornerEffect, 1000, pos) addEvent(endEffect, 7000, pos) elseif getGlobalStorageValue(config.storages.use) ~= getCreatureName(cid) then doPlayerSendCancel(cid, "You don't control Luna's power.") else doPlayerSendCancel(cid, "You're exhausted.") end return true endEssa magia tem duas peculiaridades:
1. Ela tem uma chance de 1/15 para cada hit que ela dá de congelar o alvo e tornalo imóvel por 1.8 segundos, o que já está implementado nesse script e já funciona.
2. Em pvp, isso é, ao atacar um player, ela tem uma chance de 1/18 de liberar a Benção de Luna e tornar o caster imune aos ataques daquele player por 3 segundos (atenção, não são de todos os players da área, somente do player que liberou a benção de luna ao receber um hit).
Para implementar essa segunda parte, precisamos ir em creature scripts.
Adicione as tags abaixo a creaturescripts.xml:
Crie um arquivo chamado luna.lua dentro de scripts e coloque o código abaixo nele:
function onCast(cid, target) if getGlobalStorageValue(5545) == -1 and isPlayer(target) then return true else return false end end function onAttack(cid, target) if getGlobalStorageValue(5545) == -1 and isPlayer(target) then return true else return false end end function onTarget(cid, target) if getGlobalStorageValue(5545) == -1 and isPlayer(target) then return true else doPlayerSendCancel(cid, "Unable to attack, Luna blessed your target.") return false end endPronto, o seu evento está configura e sua magia 'Luna Strike' poderá ser castada pelo último vencedor do mesmo.
Espero que gostem, os scripts estão comentados e são bem auto-explicativos, mas qualquer dúvida podem me perguntar.
Abraços,
Editado Janeiro 11 por Skulls