FJ
suporte otserv

(resolvido) Tempos não acumulaveis

Por Fjinst, 07 de dez. de 2016 em Resolvidos

tempo
magia
bug
otserv
12
3.1k
FjinstF
07 de dezembro de 2016 às 16:52

Olá a todos, eu possuo um script de prisão no qual ao utiliar eu crio uma barreira na frente, porem, quando essa prisao é retirada e depois criada novamente, o tempo da antiga esta contando e esta removendo a nova antes do tempo total da nova, o que eu queria é a solução para cada vez que eu utilizar a magia, o tempo seja unico de cada uma, ja consegui resolver por meio de criar uma atribuição de decay no item, porém queria saber se tem como resolver sem ter que colocar um tempo unico para cada ID de barreira. segue abaixo o script

 

 

Citar

local config = {
    gatesTime = 5, -- tempo em segundos
    exhaustStorage = 41000,
    exhaustTime = 1,
    createGates = {5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787} -- ID dos portoes na ordem certa
}

local combat = createCombatObject()
setCombatArea(combat, createCombatArea({
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 1, 2, 1, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}


}))

local rollarea = createCombatArea{
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 1, 2, 1, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}


local condicao = createConditionObject(CONDITION_MUTED) --- condição que vai setar
setConditionParam(condicao, CONDITION_PARAM_TICKS, 5700) --- tempo (-1 significa infinito)
setCombatCondition(combat, condicao)


local permittedPos = {}
function onTargetTile(cid, pos)

    table.insert(permittedPos[cid], pos)

end
setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile")

 

 

local function doSpell(cid, var)
doAreaCombatHealth(cid, COMBAT_PHYSICALDAMAGE, getThingPos(cid), rollarea, -5, -10, 12)
doCreatureSay(cid, "Aprisionar!", TALKTYPE_MONSTER)
if(not isCreature(cid)) then
return true
end
exhaustion.set(cid, config.exhaustStorage, config.exhaustTime) -- adiciona isso aqui
doCombat(cid, combat, var)for n, pos in ipairs(permittedPos[cid]) do
local break_scope
 for i = 1, #TRAP_IDS do
if getTileItemById(pos, TRAP_IDS).uid > 0 then
break_scope = true
break
end
end
    
if not break_scope then
doSendMagicEffect(pos, 12)

l
addEvent(function()
if(getTileItemById(pos, config.createGates[n]).uid > 0) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
end
end, config.gatesTime*1000)
end
end
end

local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)

function onCastSpell(cid, var)
    permittedPos[cid] = {}
    if(isPlayer(cid) and exhaustion.check(cid, config.exhaustStorage)) then
        doPlayerSendCancel(cid, "Aguarde "..exhaustion.get(cid, config.exhaustStorage).." segundo"..(exhaustion.get(cid, config.exhaustStorage) > 1 and "s" or "").." para usar novamente.")
        doSendMagicEffect(getThingPos(cid), 2)
        return false
    end
     doSpell(cid, var)
    return doCombat(cid, combat, var)
end

 

 

 

Acredito que esse seja o problema

addEvent(function()
if(getTileItemById(pos, config.createGates[n]).uid > 0) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
end
end, config.gatesTime*1000)

A minha duvida é, existe como fazer a criação do item com um tempo individual? Digamos, usei a magia, criei e retirei ela, depois criei no mesmo sqm novamente, ta contando o tempo da magia anterior, existe a posibilidade de criar um tempo individual para cada usada da magia?

Editado Dezembro 7 por Fjinst

PoccnnP
07 de dezembro de 2016 às 17:18

Coloque a função em uma variável global e depois é só usar stopEvent(evento) para parar a função antes de chama-lá de novo.

FjinstF
07 de dezembro de 2016 às 17:27

Eu não entendo muito de script, tem como você fazer isso para mim? por favor, ficarei eternamente grato!

PoccnnP
07 de dezembro de 2016 às 20:26
Citar

_retorno = function(pos)

if(getTileItemById(pos, config.createGates[n]).uid > 0) then

doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)

end

end

Põe fora do escopo da função principal. 

 

Citar

addEvent(_retorno(pos),config.gatesTime*1000)

Essa tu põe no lugar do addEvent existente.

 

Citar

stopEvent(_evento)

 

Põe no início da função principal. 

 

Não consIgor editar o postinho acima. Troca o addEvent por este.

Citar

addEvent(_retorno,pos,config.gatesTime*1000)

 

FjinstF
07 de dezembro de 2016 às 23:02

Não deu certo, segue a baixo as alterações que eu entendi que deviam ter sido feitas

 

Citar

local config = {
    gatesTime = 5, -- tempo em segundos
    exhaustStorage = 41000,
    exhaustTime = 1,
    createGates = {5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787, 5787} -- ID dos portoes na ordem certa
}

local combat = createCombatObject()
setCombatArea(combat, createCombatArea({
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 1, 2, 1, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}


}))

local rollarea = createCombatArea{
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 0, 1, 2, 1, 0, 1, 0, 0},
{0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0},
{0, 0, 1, 1, 0, 0, 0, 1, 1, 0, 0},
{0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
}


local condicao = createConditionObject(CONDITION_MUTED) --- condição que vai setar
setConditionParam(condicao, CONDITION_PARAM_TICKS, 5700) --- tempo (-1 significa infinito)
setCombatCondition(combat, condicao)


local permittedPos = {}
function onTargetTile(cid, pos)

    table.insert(permittedPos[cid], pos)

end
setCombatCallback(combat, CALLBACK_PARAM_TARGETTILE, "onTargetTile")

 

_retorno = function(pos)
if(getTileItemById(pos, config.createGates[n]).uid > 0) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
end
end

local function doSpell(cid, var)
stopEvent(_evento)
doAreaCombatHealth(cid, COMBAT_PHYSICALDAMAGE, getThingPos(cid), rollarea, -5, -10, 12)
doCreatureSay(cid, "Ninpo Seal Triture!", TALKTYPE_MONSTER)
if(not isCreature(cid)) then
return true
end
exhaustion.set(cid, config.exhaustStorage, config.exhaustTime) -- adiciona isso aqui
doCombat(cid, combat, var)for n, pos in ipairs(permittedPos[cid]) do
local break_scope
 for i = 1, #TRAP_IDS do
if getTileItemById(pos, TRAP_IDS).uid > 0 then
break_scope = true
break
end
end
    
if not break_scope then
doSendMagicEffect(pos, 12)
if isPlayer(getTopCreature(pos).uid) then
    doAddCondition(getTopCreature(pos).uid, condicao)
end
local tile = getTileThingByPos(pos)
if tile.itemid ~= 0 then
doCreateItem(config.createGates[n], 1, pos)
end
addEvent(_retorno,pos,config.gatesTime*1000)
end
end
end

local combat = createCombatObject()
setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE)

function onCastSpell(cid, var)
doCreatureAddHealth(cid, -(getCreatureMaxHealth(cid) / 100) * 1)
    permittedPos[cid] = {}
    if(isPlayer(cid) and exhaustion.check(cid, config.exhaustStorage)) then
        doPlayerSendCancel(cid, "Aguarde "..exhaustion.get(cid, config.exhaustStorage).." segundo"..(exhaustion.get(cid, config.exhaustStorage) > 1 and "s" or "").." para usar novamente.")
        doSendMagicEffect(getThingPos(cid), 2)
        return false
    end
     doSpell(cid, var)
    return doCombat(cid, combat, var)
end

 

 

 

Citar

[21:56:41.378] [Error - Spell Interface]
[21:56:41.385] In a timer event called from:
[21:56:41.388] data/spells/scripts/prisao.lua:onCastSpell
[21:56:41.391] Description:
[21:56:41.401] attempt to index a number value
[21:56:41.405] stack traceback:
[21:56:41.411]  [C]: in function 'getTileItemById'
[21:56:41.415]  ...ata/spells/scripts/prisao.lua:56: in function <...ata/spells/scripts/prisao.lua:55>

Não entendo muito de script, por isso não sei direito onde colocar as coisas.

zipter98Z
08 de dezembro de 2016 às 02:16

Acima de:

local config = {

coloque:

local events = {}

 

Depois, substitua:

doSendMagicEffect(pos, 12)if isPlayer(getTopCreature(pos).uid) then    doAddCondition(getTopCreature(pos).uid, condicao)endlocal tile = getTileThingByPos(pos)if tile.itemid ~= 0 then    doCreateItem(config.createGates[n], 1, pos)endaddEvent(function()    if(getTileItemById(pos, config.createGates[n]).uid > 0) then        doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)    endend, config.gatesTime*1000)

por:

doSendMagicEffect(pos, 12)if isPlayer(getTopCreature(pos).uid) then    doAddCondition(getTopCreature(pos).uid, condicao)endlocal tile = getTileThingByPos(pos)if tile.itemid ~= 0 then    local old_wall = getTileItemById(pos, config.createGates[n]).uid    if old_wall > 0 then        stopEvent(events[old_wall])    end        local new_wall = doCreateItem(config.createGates[n], 1, pos)        events[new_wall] = addEvent(function()        if getTileItemById(pos, config.createGates[n]).uid > 0 then            doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)        end    end, config.gatesTime * 1000)end

 

FjinstF
08 de dezembro de 2016 às 10:26

Da maneira que você fez @Zipter98 pareceu ter dado certo, mas depois eu testei novamente, vi que estava stackando e por isso pensei que tinha dado certo, uma maneira que eu consegui resolver o problema, mais trabalhoso mas funciona como eu quero é dessa maneira, fazendo cada segundo gerar uma actionid a menos, existe alguma maneira de diminuir esse codigo?


 

Citar

 

if tile.itemid ~= 0 then
key_uid = doCreateItem(config.createGates[n], 1, pos)
doItemSetAttribute(key_uid, "aid", 109) --action ID da key que vc ganha na quest
                    

end
addEvent(function()
if(getTileItemById(pos, config.createGates[n]).actionid == 109) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
key_uid = doCreateItem(config.createGates[n], 1, pos)
doItemSetAttribute(key_uid, "aid", 108) --action ID da key que vc ganha na quest
                
end
end, 1000)
addEvent(function()
if(getTileItemById(pos, config.createGates[n]).actionid == 108) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
key_uid = doCreateItem(config.createGates[n], 1, pos)
doItemSetAttribute(key_uid, "aid", 107) --action ID da key que vc ganha na quest
                
end
end, 2000)
addEvent(function()
if(getTileItemById(pos, config.createGates[n]).actionid == 107) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
key_uid = doCreateItem(config.createGates[n], 1, pos)
doItemSetAttribute(key_uid, "aid", 106) --action ID da key que vc ganha na quest
                
end
end, 3000)
addEvent(function()
if(getTileItemById(pos, config.createGates[n]).actionid == 106) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
key_uid = doCreateItem(config.createGates[n], 1, pos)
doItemSetAttribute(key_uid, "aid", 105) --action ID da key que vc ganha na quest
                
end
end, 4000)
addEvent(function()
if(getTileItemById(pos, config.createGates[n]).actionid == 105) then
doRemoveItem(getTileItemById(pos, config.createGates[n]).uid, 1)
end
end, 5000)
end
end
end

 


 

Fazendo assim, ele checar cada actionid e diminuindo a cada segundo, foi a unica maneira que consegui resolver pra não haver problemas

Editado Dezembro 8 por Fjinst

Bug

zipter98Z
08 de dezembro de 2016 às 22:56
Melhor resposta

Desculpe, acho que não entendi muito bem o problema.

No código inicial, novas walls criadas em posições onde já houvessem outras não teriam seu tempo de remoção resetado (ou acumulado com o anterior). Uma situação hipotética para exemplificar:

(0 segundo) wall A é criada na posição x.será removida aos 5 segundos(3 segundos) uma wall B é criada na mesma posição x, substituindo a wall Ateoricamente será removida aos 8 segundos(5 segundos) a wall A seria removida agora, porém ela foi substuída pela wall B.No código inicial, a wall A não é distinguida da wall B, fazendo com que esta seja removida.(8 segundos) a wall B já foi removida aos 5s, pois a contagem não foi resetada.

 

Na correção que escrevi, seria o seguinte:

(0 segundo) wall A é criada na posição x.será removida aos 5 segundos(3 segundos) uma wall B é criada na mesma posição x, substituindo a wall Aserá removida aos 8 segundostempo de remoção de A zerado(5 segundos) a wall A seria removida agora, porém ela foi substuída pela wall B.como A não existe mais, nada acontece(8 segundos) A wall B é removida agora, como planejado.

 

Por acaso entendi o problema errado?

FjinstF
09 de dezembro de 2016 às 01:09

Sim, peço desculpas por não saber explicar, é que realmente não sou muito bom nisso, o problema era que, Eu usava a wall que tinha que ficar 10 segundos no sqm, só que eu retirava a wall antes com um item que suga ela, só que quando eu usava a wall novamente nos mesmos sqms, contava o tempo da wall anterior que eu estava tirando e saia antes do tempo, o que eu estava tentando pedir era pra ajudar a resolver esse problema, mas eu consegui resolver fazendo cada wall ser criada por um actionid checando segundo por segundo e evitando o problema, é que como não entendo muito de script, só o basicão mesmo, fiz dessa maneira, mas de qualquer forma obrigado pela ajuda!

DeadpoolD
09 de dezembro de 2016 às 02:05

Duvida sanada?

FjinstF
09 de dezembro de 2016 às 12:59

Sim, já consegui resolver, agradeço pela atenção de todos!

DeadpoolD
09 de dezembro de 2016 às 14:02

Caro membro, seu tópico foi movido de Otserv > Suporte Otserv para Suporte Otserv > Otserv > Pedidos e Dúvidas Resolvidos.