-
Total de itens
1347 -
Registro em
-
Última visita
-
Dias Ganhos
36
Tudo que Oneshot postou
-
O Spell Forge não é uma magia, mas sim uma talkaction que usava as funções da minha biblioteca. Por enquanto ele está incompleto, estou reescrevendo ele, e tentando encontrar uma maneira de ele ficar o mais simples possível para o uso do sistema por qualquer pessoa que saiba o mínimo de Lua. Grande abraço.
-
E no caso recompilou seu servidor, deletando o obj ou usando a opção Rebuild All?
-
Você precisa compilar um servidor com o parâmetro -D__WAR_SYSTEM__ Abraços.
-
Oneshot Spell Lib Boa tarde, meus queridos. Como eu disse no último post do tópico do Spell Forge, sim, ele estava ficando funcional o bastante, mas uma coisa não me agradava, o nível de dificuldade de configuração do sistema estava aumentando, e uma hora, não teria como OT-admins usarem meu sistema, pois não saberiam configurar. Então resolvi parar o desenvolvimento dele por enquanto, mas segue minha biblioteca que estava usando para desenvolvimento do sistema. Uma biblioteca completa para desenvolvimento de magias, orientada a objetos, torna a coisa bem mais interessante. Para utilizar minha biblioteca, basta criar arquivo com qualquer nome na pasta data/lib do seu servidor e colar o seguinte conteúdo abaixo: -- This library is part of Oneshot Spell System -- Copyright (C) 2013 Oneshot -- -- This program is free software: you can redistribute it and/or modify -- it under the terms of the GNU General Public License as published by -- the Free Software Foundation, either version 3 of the License, or -- (at your option) any later version. -- -- This program is distributed in the hope that it will be useful, -- but WITHOUT ANY WARRANTY; without even the implied warranty of -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -- GNU General Public License for more details. -- -- You should have received a copy of the GNU General Public License -- along with this program. If not, see <http://www.gnu.org/licenses/>. -- constant CONST_SPELL_AREA = 0 -- area spells, like exevo gran mas vis CONST_SPELL_DIRECTION = 1 -- wave spells, like exevo flam hur CONST_SPELL_TARGETORDIRECTION = 2 -- mix between area and wave spells WEAPON_SKILLS = { [WEAPON_SWORD] = SKILL_SWORD, [WEAPON_CLUB] = SKILL_CLUB, [WEAPON_AXE] = SKILL_AXE, } -- class for combats (spell instances) Combat = { type = 0, me = 0, ani = 0, formula = { type = 0, values = {}, }, condition = nil, delay = 0, id = 0, } function Combat:New(_type, me, ani, delay, id) local new_spellinstance = { type = _type or COMBAT_NONE, me = me or CONST_ME_NONE, ani = ani or CONST_ANI_NONE, formula = { type = COMBAT_FORMULA_UNDEFINED, values = {0, 0, 0, 0, 0, 0, 0, 0}, }, condition = nil, delay = delay or -1, id = id or 1, } return setmetatable(new_spellinstance, {__index = self}) end function Combat:SetType(_type) self.type = (tonumber(_type) and _type or COMBAT_NONE) end function Combat:SetEffect(me) self.me = (tonumber(me) and me or CONST_ME_NONE) end function Combat:SetDistanceEffect(ani) self.ani = (tonumber(ani) and ani or CONST_ANI_NONE) end function Combat:SetFormula(_type, ...) local args = select("#", ...) self.formula.type = (tonumber(_type and _type or COMBAT_FORMULA_UNDEFINED)) local minc, maxc if args > 8 then minc, maxc = select(9, ...) end local minm, maxm = getConfigValue("formulaMagic") or 1 maxm = minm local minl, maxl = getConfigValue("formulaLevel") or 5 maxl = minl if args > 6 then minm, maxm = select(7, ...) end if args > 4 then minl, maxl = select(5, ...) end local mina, minb, maxa, maxb = select(1, ...) self.formula.values = {mina, minb, maxa, maxb, minl, maxl, minm, maxm, minc, maxc} end function Combat:SetCondition(condition) -- condition needs to be a createConditionObject(), e.g -- local condition = createConditionObject(CONDITION_FIRE) -- setConditionParam(condition, CONDITION_PARAM_TICKS, 1 * 1000) self.condition = condition end function Combat:GetDelay() return self.delay end function Combat:SetDelay(delay) self.delay = (tonumber(delay) and delay or -1) end function Combat:GetId() return self.id end function Combat:SetId(id) self.id = (tonumber(id) and id or 1) end function Combat:getMinMaxValues(cid, ex) local min, max = 0, 0 local n = self.formula.values if not isCreature(cid) then return false end if not isPlayer(cid) then self.formula.type = COMBAT_FORMULA_DAMAGE end if self.formula.type == COMBAT_FORMULA_LEVELMAGIC then min = (getPlayerLevel(cid) / n[5] + getPlayerMagLevel(cid) * n[7]) * n[1] + n[2] max = (getPlayerLevel(cid) / n[6] + getPlayerMagLevel(cid) * n[8]) * n[3] + n[4] if n[9] then min = math.max(n[9], min) end if n[10] then max = math.max(n[10], max) end elseif self.formula.type == COMBAT_FORMULA_SKILL then local weapon = getPlayerWeapon(cid) if weapon.uid > 0 then max = getPlayerWeaponDamage(cid, weapon) * n[3] + n[4] else max = n[4] end if n[10] then max = math.max(n[10], max) end elseif self.formula.type == COMBAT_FORMULA_DAMAGE then min = n[2] max = n[4] end return min, max end function Combat:Callback(position, cid, ex) if not isCreature(cid) then return false end local min, max = self:getMinMaxValues(cid, ex) doCombatAreaHealth(cid, self.type, position, 0, min, max, self.me) if self.condition then doCombatAreaCondition(cid, position, 0, self.condition, CONST_ME_NONE) end return true end -- class for spells Spell = { type = 0, level = 0, maglevel = 0, mana = 0, needtarget = false, target_or_direction = false, range = 0, needweapon = false, selftarget = false, vocations = {}, combats = {}, } function Spell:New(_type, level, maglevel, mana, needtarget, range, needweapon, selftarget, ...) local new_spell = { type = _type or CONST_SPELL_AREA, level = level or 1, maglevel = maglevel or 0, mana = mana or 0, needtarget = needtarget or false, range = range or 1, needweapon = needweapon or false, selftarget = selftarget or false, vocations = {...}, combat = {}, area = {{3}}, } return setmetatable(new_spell, {__index = self}) end function Spell:SetType(_type) self.type = (tonumber(_type) and _type or CONST_SPELLarea) end function Spell:SetLevel(level) self.level = (tonumber(level) and level or 1) end function Spell:SetMagLevel(maglevel) self.maglevel = (tonumber(maglevel) and maglevel or 0) end function Spell:SetMana(mana) self.mana = (tonumber(mana) and mana or 0) end function Spell:SetNeedTarget(needtarget) self.needtarget = (type(needtarget) == "boolean" and needtarget or false) end function Spell:SetRange(range) self.range = (tonumber(range) and range or 1) end function Spell:SetNeedWeapon(needweapon) self.needweapon = (type(needweapon) == "boolean" and needweapon or false) end function Spell:SetSelfTarget(selftarget) self.selftarget = (type(selftarget) == "boolean" and selftarget or false) end function Spell:SetVocations(...) self.vocations = {...} end function Spell:Append(...) local t = {...} for i = 1, #t do self.combat[t[i]:GetId()] = t[i] end end function Spell:SetArea(area) self.area = area end function Spell:Cast(cid) if not isCreature(cid) then return false end if #self.combat == 0 then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) return false end if isPlayer(cid) then if not getPlayerFlagValue(cid, PLAYERFLAG_IGNORESPELLCHECK) then if getPlayerLevel(cid) < self.level then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTENOUGHLEVEL) return false end if getCreatureMana(cid) < self.mana then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTENOUGHMANA) return false end if getPlayerMagLevel(cid) < self.maglevel then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTENOUGHMAGICLEVEL) return false end if self.needweapon and (getPlayerWeapon(cid).uid == 0) then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_YOUNEEDAWEAPONTOUSETHISSPELL) return false end local vocation = getPlayerVocation(cid) if #self.vocations > 0 and not (table.find(self.vocations, vocation) or table.find(self.vocations, getVocationInfo(vocation).fromVocation)) then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_YOURVOCATIONCANNOTUSETHISSPELL) return false end end end local target = getCreatureTarget(cid) if self.needtarget == true then if self.type == CONST_SPELL_DIRECTION then self.type = CONST_SPELL_TARGETORDIRECTION elseif self.type == CONST_SPELL_AREA and not isCreature(target) then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_YOUCANONLYUSEITONCREATURES) return false end end if self.range and isCreature(target) then if getDistanceBetween(getCreaturePosition(cid), getCreaturePosition(target)) > self.range then doSendMagicEffect(getCreaturePosition(cid), CONST_ME_POFF) doPlayerSendDefaultCancel(cid, RETURNVALUE_TOOFARAWAY) return false end end local area = self.area if self.type == CONST_SPELL_DIRECTION or (self.type == CONST_SPELL_TARGETORDIRECTION and not isCreature(target)) then area = getAreaByDir(area, getCreatureLookDirection(cid)) end local centre = getCreaturePosition(cid) local target = getCreatureTarget(cid) if self.type == CONST_SPELL_DIRECTION then centre = getPosByDir(getCreaturePosition(cid), getCreatureLookDirection(cid), 1) elseif self.type == CONST_SPELL_TARGETORDIRECTION then centre = (isCreature(target) and getCreaturePosition(target) or getPosByDir(getCreaturePosition(cid), getCreatureLookDirection(cid), 1)) elseif self.type == CONST_SPELL_AREA then if self.needtarget and isCreature(target) then centre = getCreaturePosition(target) end end local positions = getAreaPositions(area, centre) for i = 1, #area do for j = 1, #area[i] do local tmp = area[i][j] if tmp == 3 then for k = 1, #self.combat do local combat = self.combat[k] if combat then addEvent(function() if self.selftarget then combat:Callback(positions[i][j], 0) else combat:Callback(positions[i][j], cid) end doSendDistanceShoot(getCreaturePosition(cid), centre, combat.ani) end, combat:GetDelay()) end end elseif type(tmp) == "number" and self.combat[tmp] then local combat = self.combat[tmp] if combat then addEvent(function() if self.selftarget then combat:Callback(positions[i][j], 0) else combat:Callback(positions[i][j], cid) end doSendDistanceShoot(getCreaturePosition(cid), centre, combat.ani) end, combat:GetDelay()) end elseif type(tmp) == "table" then for k = 1, #tmp do local tile = tmp[k] local combat = self.combat[tile] if combat then addEvent(function() if self.selftarget then combat:Callback(positions[i][j], 0) else combat:Callback(positions[i][j], cid) end doSendDistanceShoot(getCreaturePosition(cid), centre, combat.ani) end, combat:GetDelay()) end end end end end if self.mana > 0 then doCreatureAddMana(cid, -self.mana, 0) end return true end function rotate(area) local ret = {} for i = 1, #area do for j = 1, #area[i] do if not ret[#area[i]-j+1] then ret[#area[i]-j+1] = {} end ret[#area[i]-j+1][i] = area[i][j] end end return ret end function getAreaByDir(area, direction) local ret = area if direction > NORTH then local n = (4 - direction) repeat ret = rotate(ret) n = n - 1 until n == 0 end return ret end function getAreaCentre(area) local x, y = 0, 0 for i = 1, #area do for j = 1, #area[i] do if area[i][j] == 3 then x = j y = i break end end end return x, y end function getAreaPositions(area, centre) local ret = {} local x, y = getAreaCentre(area) for i = 1, #area do for j = 1, #area[i] do if not ret[i] then ret[i] = {} end ret[i][j] = {x = centre.x + (j - x), y = centre.y + (i - y), z = centre.z} end end return ret end function getPlayerMeleeDamage(cid, item) local skill, attack if item.uid > 0 then local info = getItemInfo(item.itemid) skill = getPlayerSkillLevel(cid, WEAPON_SKILLS[getItemWeaponType(item.uid)]) attack = ((getItemAttribute(item.uid, "attack") or info.attack) + (getItemAttribute(item.uid, "extraAttack") or info.extraAttack) - info.abilities.elementDamage) else skill = getPlayerSkillLevel(cid, SKILL_FIST) attack = 0 end local damage = math.ceil((2 * (attack * (skill + 5.8) / 25 + (getPlayerLevel(cid) - 1) / 10.)) / getPlayerAttackFactor(cid)) return -math.random(0, damage) end function getPlayerAttackFactor(cid) local switch = { 1.0, 1.2, 2.0, } return switch[(getPlayerModes(cid).fight + 1)] end dofile(getDataDir() .."/spells/lib/spells.lua") É uma biblioteca orientada a objetos que facilita o desenvolvimento de magias. Comparando a forma dos scripts de magias, com a minha biblioteca e sem, podemos ver a diferença. Sem a biblioteca: local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) setCombatParam(combat, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) setAttackFormula(combat, COMBAT_FORMULA_LEVELMAGIC, 5, 5, 4.5, 9) local area = createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5) setCombatArea(combat, area) function onCastSpell(cid, var) return doCombat(cid, combat, var) end Com a biblioteca: local combat = Combat:New(COMBAT_ENERGYDAMAGE, CONST_ME_ENERGYAREA, CONST_ANI_ENERGY) combat:SetFormula(COMBAT_FORMULA_LEVELMAGIC, -1, 0, -1, 0, 5, 5, 4.5, 9) local spell = Spell:New(CONST_SPELL_DIRECTION) spell:Append(combat) spell:SetArea(AREA_WAVE4) function onCastSpell(cid, var) return spell:Cast(cid) end Mas o melhor mesmo é notado quando você quer desenvolver as magias com mais de uma variável combat. Aquelas magias de múltiplos hits e efeitos. Vou pegar uma magia de 3 efeitos e danos diferentes. local combat1 = createCombatObject() setCombatParam(combat1, COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE) setCombatParam(combat1, COMBAT_PARAM_EFFECT, CONST_ME_ENERGYAREA) setCombatParam(combat1, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGY) setAttackFormula(combat1, COMBAT_FORMULA_LEVELMAGIC, 5, 5, 4.5, 9) local combat2 = createCombatObject() setCombatParam(combat2, COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE) setCombatParam(combat2, COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA) setCombatParam(combat2, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE) setAttackFormula(combat2, COMBAT_FORMULA_LEVELMAGIC, 5, 5, 1, 2) local combat3 = createCombatObject() setCombatParam(combat3, COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE) setCombatParam(combat3, COMBAT_PARAM_EFFECT, CONST_ME_SMALLPLANTS) setCombatParam(combat3, COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH) setAttackFormula(combat3, COMBAT_FORMULA_LEVELMAGIC, 5, 5, 3.5, 7) local area = createCombatArea(AREA_SQUAREWAVE5, AREADIAGONAL_SQUAREWAVE5) setCombatArea(combat1, area) setCombatArea(combat2, area) setCombatArea(combat3, area) function onCastSpell1(cid, var) doCombat(cid, combat1, var) end function onCastSpell2(cid, var) doCombat(cid, combat2, var) end function onCastSpell3(cid, var) doCombat(cid, combat3, var) end function onCastSpell(cid, var) onCastSpell1(cid, var) addEvent(onCastSpell2, 300, cid, var) addEvent(onCastSpell3, 600, cid, var) return true end Com o uso da minha biblioteca, podemos notar a redução de linhas, e a limpeza do código: local combat1 = Combat:New(COMBAT_ENERGYDAMAGE, CONST_ME_ENERGYAREA, CONST_ANI_ENERGY) combat1:SetFormula(COMBAT_FORMULA_LEVELMAGIC, -1, 0, -1, 0, 5, 5, 4.5, 9) local combat2 = Combat:New(COMBAT_ICEDAMAGE, CONST_ME_ICEAREA, CONST_ANI_ICE) combat2:SetFormula(COMBAT_FORMULA_LEVELMAGIC, -1, 0, -1, 0, 5, 5, 1, 2) combat2:SetId(2) combat2:SetDelay(300) local combat3 = Combat:New(COMBAT_EARTHDAMAGE, CONST_ME_SMALLPLANTS, CONST_ANI_EARTH) combat3:SetFormula(COMBAT_FORMULA_LEVELMAGIC, -1, 0, -1, 0, 5, 5, 3.5, 7) combat3:SetId(4) combat3:SetDelay(600) local T = {1, 2, 4} local area = { {T, T, T}, {T, T, T}, {T, T, T}, {0, T, 0}, {0, 3, 0}, } local spell = Spell:New(CONST_SPELL_DIRECTION) spell:SetArea(area) spell:Append(combat1, combat2, combat3) function onCastSpell(cid, var) return spell:Cast(cid) end Qualquer dúvida quanto ao uso da biblioteca no desenvolvimento de magias, basta postar neste tópico que estarei esclarecendo. Grande Abraço, Oneshot.
-
Toma. local combat = createCombatObject() setCombatParam(combat, COMBAT_PARAM_TYPE, COMBAT_PHYSICALDAMAGE) setCombatParam(combat, COMBAT_PARAM_EFFECT, CONST_ME_HITAREA) setCombatParam(combat, COMBAT_PARAM_USECHARGES, true) setCombatArea(combat, createCombatArea(AREA_SQUARE1X1)) function getMinMaxValues(cid, level, skill, attack, factor) local min = skill * 9 local max = skill * 11 return -min, -max end setCombatCallback(combat, CALLBACK_PARAM_SKILLVALUE, "getMinMaxValues") function onCastSpell(cid, var) return doCombat(cid, combat, var) end
-
http://www.xtibia.com/forum/topic/222505-show-off-spell-forge/ -> Dê uma olhada no protótipo do Spell Forge e comente o que você achou :)
-
Legal a iniciativa de postar conteúdo, mas o que isso tem a ver com um tutorial?
-
Poxa, tá aí uma ideia boa mesmo, um canal voltado a Open Tibia, poderia ficar bem legal, principalmente com pessoas que cuidassem de programação, outros que cuidassem de gameplays em servidores. Gostei da ideia haha.
- 6 respostas
-
- discurssão
- tibia
-
(e 1 mais)
Tags:
-
Como funcionará? Uso de OtClient ou o cliente padrão do Tibia?
-
[Arquivado]Você gosta do uso de bot em OT?
tópico respondeu ao KillerMaster de Oneshot em Noticias - Arquivo
Não gosto desses softwares, principalmente do Elfbot em servidores 8.60, que diminui, assustadoramente, o intervalo de ataques. Chega a ser escroto, o uso de bots em Open Tibia. -
É possível sim, principalmente fazendo alterações nas sources. Se tomarmos como exemplo, League of Legends, onde existem dois times, podemos fazer alterações para que monstros do Time 1, enxerguem como inimigos apenas monstros e "heróis" do Time 2. Inclusive a partir de revisões mais recentes do The Forgotten Server, foi incluida uma ótima função, doSteerCreature(cid, position), que traz a possibilidade de deslocar criaturas de um ponto até outro, como se elas andassem mesmo, não por teleporte instantâneo.
-
Terminei de desenvolver toda a biblioteca do Spell Forge, agora é só desenvolver o sistema-interpretador e pronto :P
-
Neste tópico, proponho modificações nas sources, para que você esconda a fala do jogador ao usar magias e possa usar return true nos scripts.
- 8 respostas
-
- exausted return false
- resolvido
- (e 3 mais)
-
Que tal criar a sua própria magia apenas com palavras? Estou desenvolvendo um novo sistema de magias para Open Tibia, Spell Forge, que interpreta palavras em magias :P
-
Desisto de atender pedidos. O povo pede coisas que já existem postadas, quebram as regras do tópico, ah vão catar coquinho.
-
Sim e não. Sim, eu entendi o que você quis dizer. O sistema do Vodkart é necessário pedir a task ao NPC, e o que eu fiz é automático. E não, eu não vou fazer o comando !task, você pediu um NPC, eu fiz e ainda te dei o creaturescript de brinde. E se você se sentir contrariado com este post, Manual de Referência de Lua 5.1 é serventia da casa. Um grande abraço e vai pela sombra.
-
function onUse(cid, item, fromPosition, itemEx, toPosition) if itemEx.itemid == 2157 then if itemEx.type == 100 then doTransformItem(itemEx.uid, 7762, itemEx.type) else doPlayerSendCancel(cid, "You need 100 gold nuggets.") end else doPlayerSendCancel(cid, "You can only use the battle hammer in gold nuggets.") end end
-
Não, não posso. Se quiser com talkaction, o sistema do Vodkart funciona muito bem.
-
Não, acho que você não entendeu. Eu faço do jeito que eu quero, testo, e se funcionar, eu posto. Se não gostou, o Manual de Referência de Lua 5.1 existe para estudos.
-
local PETS = { ["Rat"] = {0, 250}, } function onUse(cid, item, fromPosition, itemEx, toPosition) if getTileInfo(getCreaturePosition(cid)).protection then return doPlayerSendCancel(cid, "Você não pode invocar dentro de zonas de proteção.") end if getCreatureStorage(cid, 11548) > os.time() then return doPlayerSendCancel(cid, "A energia espiritual não é suficiente. Aguarde ".. getCreatureStorage(cid, 11548) - os.time() .." segundos.") end local summons = getConfigValue("maxPlayerSummons") if #getCreatureSummons(cid) > summons then return doPlayerSendCancel(cid, "Você já invocou criaturas o bastante.") end local tmp = nil for _, uid in ipairs(getCreatureSummons(cid)) do if PETS[getCreatureName(uid)] then tmp = uid end end if tmp then return doPlayerSendCancel(cid, "Sua criatura já foi invocada.") end for name, level in pairs(PETS) do if getPlayerLevel(cid) > level[1] and getPlayerLevel(cid) <= level[2] then local monster = doCreateMonster(name, getCreaturePosition(cid)) if doConvinceCreature(cid, monster) then doCreatureSay(cid, "Go, " .. name .. "!", TALKTYPE_ORANGE_1) doCreatureSetStorage(cid, 11548, os.time() + 30) doSendMagicEffect(getCreaturePosition(monster), 2) end break end end return true end Alguém pediu algo sobre summon, sem a função do summon voltar, eu fiz um do zero, identado e funcional. Abraços.
-
Não, não tem.
-
creatureevent Anti Fast-attack Elf Bot
tópico respondeu ao warotserv de Oneshot em Globalevents e Spells
Vá estudar Lua antes de falar asneiras. A função table.maxn ou # não retorna index de tipo string, apenas numéricos positivos. -
Creaturescript local MONSTER_TASKS = { -- ["NOME"] = QUANTIDADE, ["Troll"] = 1000, } function onKill(cid, target) local tmp = MONSTER_TASKS[getCreatureName(target)] if tmp then local name = getCreatureName(target):lower() local status_storage = name .."_status" if getCreatureStorage(cid, status_storage) == -1 then local count_storage = name .."_count" doCreatureSetStorage(cid, count_storage, math.max(getCreatureStorage(cid, count_storage), 0) + 1) doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_BLUE, getCreatureName(target) .." killed: ".. getCreatureStorage(cid, count_storage) .."/".. tmp ..".") if getCreatureStorage(cid, count_storage) >= tmp then doPlayerSendTextMessage(cid, MESSAGE_STATUS_CONSOLE_ORANGE, "You have killed ".. tmp .." of ".. getCreatureName(target) ..". You have completed the task.") doCreatureSetStorage(cid, status_storage, 1) end end end return true end NPC local keywordHandler = KeywordHandler:new() local npcHandler = NpcHandler:new(keywordHandler) NpcSystem.parseParameters(npcHandler) local talkState = {} function onCreatureAppear(cid) npcHandler:onCreatureAppear(cid) end function onCreatureDisappear(cid) npcHandler:onCreatureDisappear(cid) end function onCreatureSay(cid, type, msg) npcHandler:onCreatureSay(cid, type, msg) end function onThink() npcHandler:onThink() end local MONSTER_TASKS = { -- ["nome"] = { -- {ITEM1, QUANTIDADE}, -- {ITEM2, QUANTIDADE} -- ,} -- Para dar experiência, coloque "experience" ["troll"] = { {"experience", 20}, {2160, 1}, }, ["orc"] = { {"experience", 20}, {2160, 1}, }, } function table.size(t) -- A função table.maxn ou # não conta no tamanho da tabela index igual a string, apenas numéricos positivos. local size = 0 for _,_ in pairs(t) do size = size + 1 end return size end function callbackOnCreatureSay(cid, type, msg) if(not npcHandler:isFocused(cid)) then return false end local talkUser = NPCHANDLER_CONVBEHAVIOR == CONVERSATION_DEFAULT and 0 or cid local str = "I have so many tasks for you, choose one: " if msgcontains(msg, "task") then local n = 1 local k = table.size(MONSTER_TASKS) print(k) for name, _ in pairs(MONSTER_TASKS) do str = str .. "{" .. name .. "}" .. (n == k and "." or ", ") n = n + 1 end selfSay(str, cid) talkState[talkUser] = 1 end if talkState[talkUser] == 1 then local tmp = MONSTER_TASKS[msg:lower()] if tmp then local status = msg:lower() .. "_status" if getCreatureStorage(cid, status) == 1 then selfSay("You are a good hunter. Thank you for your help.", cid) for i=1,#tmp do if tmp[i][1] == "experience" then doPlayerAddExperience(cid, tmp[i][2]) doSendAnimatedText(getThingPosition(cid), tmp[i][2], COLOR_WHITE) else doPlayerAddItem(cid, tmp[i][1], tmp[i][2]) end end doCreatureSetStorage(cid, status, 2) elseif getCreatureStorage(cid, status) == 2 then selfSay("You already completed this hunt task.", cid) else selfSay("You don't killed the necessary count of monsters.", cid) end end end return true end npcHandler:setCallback(CALLBACK_MESSAGE_DEFAULT, callbackOnCreatureSay) npcHandler:addModule(FocusModule:new())
-
Quem Está Navegando 0 membros estão online
- Nenhum usuário registrado visualizando esta página.