Jump to content

Bird Hunt - Atire no pássaro.


Night Wolf

Recommended Posts

Fala galera, vim compartilhar com vcs um dos sistemas que eu fiz baseado no jogo Bird Hunt e que foi imbutido em alguns servidores famosos, sendo o Korelin um deles.
Obs: Testado em TFS 0.3.6 mas deve funcionar em TFS 0.4 sem problema

aqui tem uma pequena imagem demonstrando o sistema sendo utilizado:


6ehwxH5.png



Bom, antes de tudo eu vou ensinar vocês a criar um mapa apropriado pois isso é 90% das dificuldades que os players enfrentam quando tentam adicionar o sistema.

Inicialmente vc vai precisar criar uma area no seu mapa editor +- parecida com a que eu fiz na imagem abaixo:


sDgV2Qp.jpg



Feito isso vc deverá colocar uniqueid 16480 na porta e actionid 14874 em todos os lugares que o player pode percorrer (da placa pra \/ todos os quadrados verdes deverão conter esse actionid)

Colocado os ids, vc deverá fazer a sala à prova de bugs, para isso você terá que seguir essas especificações:


wa4VqRB.jpg



Note que em verde são os lugares que vc deverá colocar protect zone e em roxo os locais onde vc deve colocar no logout zone. Agora perceba que nas posições onde o player irá andar, você vai colocar tanto no logout zone como protect zone, isso pra evitar ele de matar o bixo com spells e pra evitar que ele deslogue durante o mini game. Essa contagem de sqms eu vou explicar mais tarde na configuração do script, mas tenham ela em mente.

Agora vamos aos scripts:
Comece criando em data/lib um arquivo chamado 045- Bird Hunt Lib.lua e colocando isso dentro dele:

 

-- Bird Hunt Lib

--1º
function countDown(position, time, color) -- faz a contagem de tempo
    local msg = os.date("%M:%S", time)
    if time > 0 then
        doSendAnimatedText(position, msg, color)
        addEvent(countDown, 1000, position, time - 1, color)
    end
return true
end

--2º
function isRoomBusy(pos, rangey1, rangey2) -- checa se a sala está ocupada
    local minj = math.min(rangey1, rangey2)
    local maxj = math.max(rangey1, rangey2)
    for j = minj, maxj do
    local cPos = {x = pos.x, y = pos.y + j, z = pos.z}
    local creature = getTopCreature(cPos).uid
        if isCreature(creature) then
            return true
        end
    end
return false
end

--3º
function startEvent(posi, delay, color, mob, tempo) -- começa tudo e retorna o tempo de delay até carregar o evento
    local msgs = {3, 2, 1, "GO!!"}
    local monster = doCreateMonster(mob, posi)
    for index, str in ipairs (msgs) do
        addEvent(doSendAnimatedText, delay * index, posi, str, color)
    end
    addEvent(doRemoveCreature, (#msgs * delay) + (tempo * 1000), monster)
return (#msgs * delay)
end

--4º
function startShooting(uid, shots, a, delay, rangemax, color, key) -- começa a atirar e teleport o player após acabar o numero de tiros.
local points = getPlayerStorageValue(uid, key)
local fromPos = getCreaturePosition(uid)
fromPos.x = fromPos.x + (3 * a)
local toPos = {x = fromPos.x, y = fromPos.y, z = fromPos.z}
    for i = 1, (rangemax-4) do            
        toPos.x = toPos.x + (1 * a)
        local creature = getTopCreature(toPos)
        if (creature.uid > 0) then
            local ePos = {x= toPos.x, y = toPos.y, z = toPos.z}
            setPlayerStorageValue(uid, key, points + 1)
            doSendAnimatedText(ePos, tostring(points + 1), color)
            doSendMagicEffect(ePos, 0)
        break
        end
    end
doSendDistanceShoot(fromPos, toPos, 2)
doSendAnimatedText(getCreaturePosition(uid), "Shoot!", color)
addEvent(function()
    if isPlayer(uid) and shots > 1 then
        startShooting(uid, shots - 1, a, delay, rangemax, color, key)
    elseif isPlayer(uid) and shots <= 1 then
        local initPos = getCreaturePosition(uid)
        initPos.x = initPos.x - (3 * a)        
        doTeleportThing(uid, initPos) --- teleporta o player pra posição inicial
    end
end, delay)
return true
end

--5º
function getBestaPos(pos, a)
    local bestapos = {
        [-1] = {
            ids = {5698, 5700, 5699},
            [1] = {x = pos.x - 2, y = pos.y, z = pos.z},
            [2] = {x = pos.x - 3, y = pos.y, z = pos.z},
            [3] = {x = pos.x - 3, y = pos.y - 1, z = pos.z}
            },
        [1] = {
            ids = {5701, 5703, 5702},
            [1] = {x = pos.x + 2, y = pos.y, z = pos.z},
            [2] = {x = pos.x + 3, y = pos.y, z = pos.z},
            [3] = {x = pos.x + 3, y = pos.y - 1, z = pos.z}
            }
    }
return bestapos[a]
end

--6º
function moveBesta(position, a, dir)
local posBesta = getBestaPos(position, a)
local bestaId = getBestaPos(position, a).ids
    for i = 1, 3 do
    local item = getTileItemById(posBesta[i], bestaId[i])
        if item.uid > 0 then
        local createPos = {x = posBesta[i].x, y = posBesta[i].y - dir, z = posBesta[i].z}
            doRemoveItem(item.uid)
            doCreateItem(item.itemid, 1, createPos)            
        end
    end
return true
end

--7º
function createBesta(position, a)
    local posBesta = getBestaPos(position, a)
    local bestaId = getBestaPos(position, a).ids
    for i = 1, 3 do
        local createPos = {x = posBesta[i].x, y = posBesta[i].y, z = posBesta[i].z}
        doCreateItem(bestaId[i], 1, createPos)            
    end
return true
end

--8º
function removeBesta(position, a)
    local posBesta = getBestaPos(position, a)
    local bestaId = getBestaPos(position, a).ids
    for i = 1, 3 do        
        local item = getTileItemById(posBesta[i], bestaId[i])
        doSendMagicEffect(posBesta[i], 14)
        if item.uid > 0 then
            doRemoveItem(item.uid)        
        end
    end
return true
end

 



Feito isso vá em data/actions/scripts e adicione um arquivo chamado seagul.lua que deverá conter:

 

local config = {
rangecima = {x = -8, y = -4}, -- distancia em x e y da topos (ate a pos de cima)
rangebaixo = {x = 0, y = 4}, -- distancia em x e y da topos (ate a pos de baixo)
cor = 129 or 215, -- cor dos textos (a primeira eh branca e a segunda eh cinza)
tempo = 60, -- tempo que vc fica no evento (segundos)
delay = 1000, -- intervalo que os tiros saem (milisegundos)
storage = 17367, -- storage que salva algumas informações
mob = "Seagull" -- nome do monstro
}

function onUse(cid, item, frompos, itemEx, topos)
    if getPlayerStorageValue(cid, config.storage) < 0 then
        local a = getCreaturePosition(cid).x > topos.x and -1 or 1
        local pos = {x = topos.x, y = topos.y, z = topos.z}
        pos.x = topos.x + (1 * a)
        if not isRoomBusy(pos, config.rangecima.y, config.rangebaixo.y) then
            doTeleportThing(cid, pos)
            setPlayerStorageValue(cid, config.storage, 0)
            local middlePos = {x = pos.x, y = pos.y, z = pos.z}
            middlePos.x = middlePos.x + (4 * a)
            tempoinit = startEvent(middlePos, config.delay, config.cor, config.mob, config.tempo)
            local cucoPos = {x = middlePos.x, y = middlePos.y, z = middlePos.z}
            cucoPos.x = cucoPos.x + (a * 1) --- qnt vai aumentar o cucopos.x
            cucoPos.y = cucoPos.y + config.rangecima.y -- qnt vai aumentar o cucopos.y
addEvent(function()
    countDown(cucoPos, config.tempo, config.cor)
    if isPlayer(cid) then            
        startShooting(cid, math.floor(((config.tempo * 1000) / config.delay)), a, config.delay, math.abs(config.rangecima.x), config.cor, config.storage)
    end
end, tempoinit)    
        else
            doPlayerSendCancel(cid, "This room is full.")
        end
    else
        doPlayerSendCancel(cid, "You're already inside a room.")
    end
return true
end

 


e adicione em actions.xml:
<action uniqueid="16480" event="script" value="seagul.lua"/>
Agora vá em data/movements/scripts e crie um arquivo chamado seagulmove.lua com o seguinte conteúdo:

local config = {
position = -1, -- coloque 1 se a sala estiver pra direita > e -1 se estiver pra esquerda <
storage = 17367, -- storage que salva os pontos
recorde = 17368 -- storage que vai salvar sua maior pontuacao
}


function onStepIn(cid, item, topos, frompos)
if not isPlayer(cid) then return true end
    if math.abs(frompos.x - getCreaturePos(cid).x) > 0 then
        createBesta(getCreaturePos(cid), config.position) -- cria besta ao entrar
        return true
    end
    local movePos = {x = frompos.x, y = frompos.y, z = frompos.z}
    local dir = movePos.y - topos.y
    local posBesta = getBestaPos(frompos, config.position)
    moveBesta(movePos, config.position, dir) -- move ao se mexer
return true
end


function onStepOut(cid, item, frompos, topos, lastpos)
    if math.abs(frompos.x - getCreaturePos(cid).x) <= 0 then
        return true
    end
    local movePos = {x = frompos.x, y = frompos.y, z = frompos.z}
    local posBesta = getBestaPos(frompos, config.position)
    removeBesta(movePos, config.position) -- remove a besta ao sair
    if not isPlayer(cid) then return true end
    if getPlayerStorageValue(cid, config.recorde) <= getPlayerStorageValue(cid, config.storage) then
        setPlayerStorageValue(cid, config.recorde, getPlayerStorageValue(cid, config.storage))
        doPlayerSendTextMessage(cid, MESSAGE_STATUS_WARNING, "[Bird Hunt]\nYou made ".. getPlayerStorageValue(cid, config.recorde) .." points, that\'\s your new record!")
    end
    setPlayerStorageValue(cid, config.storage, -1)
return true
end

 

 

E adicione as tags em movements.xml:

 <movevent type="StepIn" actionid="14872" event="script" value="seagulmove.lua"/>
 <movevent type="StepOut" actionid="14872" event="script" value="seagulmove.lua"/>

Agora, pra deixar nosso sistema mais real e difícil, altere a velocidade do seagul de 200 pra 300 na pasta data/monsters/Birds/seagull.xml
eu alterei tb a quantidade de vida q ele começa a fugir pra vida atual dele e fiz outras alterações pra tornar mais difícil, mas isso é com vcs.

A maioria das coisas tá bem compreensível, com exceção das duas primeiras linhas de actions:
rangecima = {x = -8, y = -4}, -- distancia em x e y da topos (ate a pos de cima)
rangebaixo = {x = 0, y = 4}, -- distancia em x e y da topos (ate a pos de baixo)

é aqui que entra aquela imagem, vc vai considerar a porta (o ponto cinza) como sendo nossa origem, ou seja, o ponto (0,0)
rangecima é a distancia que eu tenho que percorrer em x e y pra chegar até a ponta de cima < e rangebaixo é a distancia que eu tenho que percorrer em x e y pra chegar até a ponta de baixo. Se vcs mudarem o tamanho da sala, fiquem ligados nisso.
Obs: algumas pessoas fazem a sala virada pra direita também, nesse caso vc mantém a actions (pode usar inclusive o mesmo arquivo), só tem que alterar o movements pois lá vc define se é direita ou esquerda.

É isso, espero que tenham gostado. O jogo é só por diversão mas vc pode alterar a função de atirar pra ganhar dinheiro por cada acerto ou então criar um npc que vc te dá X premio dependendo do seu recorde.. podendo esse premio inclusive ser uma key pra uma quest. Usem a imaginação e espero que aproveitem esse sistema.

Abraços do Lobo.

Edited by Night Wolf
Link to comment
Share on other sites

 

 

Porque um pássaro? Ele é tão fofinho... Poe um porco logo =]

ali no mob = "" vc pode definir qlqer monstro haha, é que originalmente haviam feito pra imitar aquele jogo Bird Hunt do master system, lembra? que os passaros saiam voando e vc tinha que atirar e se vc errava o cachorro ria de vc.
Link to comment
Share on other sites

  • Administrador

 

ali no mob = "" vc pode definir qlqer monstro haha, é que originalmente haviam feito pra imitar aquele jogo Bird Hunt do master system, lembra? que os passaros saiam voando e vc tinha que atirar e se vc errava o cachorro ria de vc.

 

kk clássico, de certa forma, ótimo release.

 

Link to comment
Share on other sites

  • 4 months later...
×
×
  • Create New...