Oneshot 24 #1 Postado 31 Janeiro, 2014 (editado) Perfect Upgrade System Refinar Orientado a Objetos Boa tarde, Continuando com novos conteúdos para este fórum, este é um sistema que desenvolvi muito bem recebido em outros fóruns. A ideia é simples e já existe em muitos MMORPGs. Por que os jogadores tem que "estagnar" seu poder de ataque e defesa com um full set? Que tal inovar o Tibia, e poder refinar seus itens até um nível de poder mais alto? Este é o sistema que possibilita isso, embora exista um sistema criado pelo Mock muito difundido entre fóruns de conteúdo, meu sistema é mais fácil e intuitivo de configurar. E tem algumas características bem maneiras. - O nível máximo é praticamente ilimitado - O sistema funciona com armas físicas e de longa distância, exceto wands e ammunitions (stackable). - Você pode configurar um sistema de chances dinâmico, que varia entre sucesso, falha e falha crítica. - Broadcast para jogadores que atingem certo nível de refino. - As chances são configuradas manualmente e não por uma fórmula, sua randomização é muito precisa. Para instalar, é fácil, siga o tutorial abaixo. 1. Crie um arquivo chamado upgrade-system.lua em data/lib, cole o seguinte conteúdo abaixo. --[[ PERFECT UPGRADE SYSTEM 2.0 Criado por Garou É proibido a venda, ou a cópia sem os devidos créditos desse script. ]]-- UpgradeHandler = { levels = { [1] = {100, false, false}, [2] = {90, false, false}, [3] = {75, false, false}, [4] = {60, true, false}, [5] = {45, true, false}, [6] = {30, true, false}, [7] = {25, true, false}, [8] = {20, true, true}, [9] = {15, true, true}, [10] = {10, true, true}, [11] = {10, true, true}, [12] = {5, true, true} }, broadcast = 7, attributes = { ["attack"] = 2, ["defense"] = 1, ["armor"] = 1 }, message = { console = "Trying to refine %s to level +%s with %s%% success rate.", success = "You have upgraded %s to level +%s", fail = "You have failed in upgrade of %s to level +%s", downgrade = "The upgrade level of %s has downgraded to +%s", erase = "The upgrade level of %s has been erased.", maxlevel = "The targeted %s is already on max upgrade level.", notupgradeable = "This item is not upgradeable.", broadcast = "The player %s was successful in upgrading %s to level +%s.\nCongratulations!!", invalidtool = "This is not a valid upgrade tool.", toolrange = "This upgrade tool can only be used in items with level between +%s and +%s" }, tools = { [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}}, }, isEquipment = function(self) local weaponType = self:getItemWeaponType() return ((weaponType > 0 and weaponType < 7) or self.item.armor ~= 0) end, setItemName = function(self, name) return doItemSetAttribute(self.item.uid, "name", name) end, chance = function(self) local chances = {} chances.upgrade = (self.levels[self.item.level + 1][1] or 100) chances.downgrade = (self.item.level * 5) chances.erase = (self.item.level * 3) return chances end } function UpgradeHandler:new(item) local obj, ret = {} obj.item = {} obj.item.level = 0 obj.item.uid = item.uid for key, value in pairs(getItemInfo(item.itemid)) do obj.item[key] = value end ret = setmetatable(obj, {__index = function(self, index) if _G[index] then return (setmetatable({callback = _G[index]}, {__call = function(self, ...) return self.callback(item.uid, ...) end})) else return UpgradeHandler[index] end end}) if ret:isEquipment() then ret:update() return ret end return false end function UpgradeHandler:update() self.item.level = (tonumber(self:getItemName():match("%+(%d+)")) or 0) end function UpgradeHandler:refine(uid, item) if not self.item then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.notupgradeable) return "miss" end local tool = self.tools[item.itemid] if(tool == nil) then doPlayerSendTextMessage(uid, MESSAGE_EVENT_DEFAULT, self.message.invalidtool) return "miss" end if(self.item.level > #self.levels) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.maxlevel:format(self.item.name)) return "miss" end if(self.item.level < tool.range[1] or self.item.level >= tool.range[2]) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.toolrange:format(unpack(tool.range))) return "miss" end local chance = (self:chance().upgrade + tool.info.chance) doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_BLUE, self.message.console:format(self.item.name, (self.item.level + 1), math.min(100, chance))) if(tool.info.removeable == true) then doRemoveItem(item.uid, 1) end if chance * 100 > math.random(1, 10000) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_ORANGE, self.message.success:format(self.item.name, (self.item.level + 1))) if (self.item.level + 1) >= self.broadcast then doBroadcastMessage(self.message.broadcast:format(getCreatureName(uid), self.item.name, (self.item.level + 1))) end self:setItemName((self.item.level > 0 and self:getItemName():gsub("%+(%d+)", "+".. (self.item.level + 1)) or (self:getItemName() .." +1"))) for key, value in pairs(self.attributes) do if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then doItemSetAttribute(self.item.uid, key, (self.item.level > 0 and getItemAttribute(self.item.uid, key) or self.item[key]) + value) end end return "success" else if(self.levels[self.item.level][3] == true and (self:chance().erase * 100) > math.random(1, 10000)) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.erase:format(self.item.name)) self:setItemName(self.item.name) for key, value in pairs(self.attributes) do if self.item[key] > 0 then doItemSetAttribute(self.item.uid, key, self.item[key]) end end elseif(self.levels[self.item.level][2] == true and (self:chance().downgrade * 100) > math.random(1, 10000)) then doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.downgrade:format(self.item.name, (self.item.level - 1))) self:setItemName((self.item.level == 1 and self.item.name or self:getItemName():gsub("%+(%d+)", "+".. (self.item.level - 1)))) for key, value in pairs(self.attributes) do if getItemAttribute(self.item.uid, key) ~= nil or self.item[key] ~= 0 then doItemSetAttribute(self.item.uid, key, (self.item[key] + value * (self.item.level - 1))) end end else doPlayerSendTextMessage(uid, MESSAGE_STATUS_CONSOLE_RED, self.message.fail:format(self.item.name, (self.item.level + 1))) end return "fail" end end Se o seu servidor for baseado em 0.2 e não tiver pasta lib, crie um arquivo na pasta data e cole a seguinte linha no arquivo global.lua dofile(getDataDir() .."/upgrade-system.lua") 2. Crie um arquivo em data/actions/scripts, cole o conteúdo: function onUse(cid, item, fromPosition, itemEx, toPosition) if isCreature(itemEx.uid) then return doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTPOSSIBLE) end local obj = UpgradeHandler:new(itemEx) if(obj == false) then return doPlayerSendCancel(cid, UpgradeHandler.message.notupgradeable) end local status = obj:refine(cid, item) if status == "success" then --doSendAnimatedText(toPosition, "Success!", COLOR_GREEN) doSendMagicEffect(toPosition, CONST_ME_MAGIC_GREEN) elseif status == "fail" then --doSendAnimatedText(toPosition, "Fail!", COLOR_RED) doSendMagicEffect(toPosition, CONST_ME_POFF) else doSendMagicEffect(toPosition, CONST_ME_POFF) end return true end 3. Cole a tag no actions.xml. <action itemid="8306" event="script" value="upgrade.lua"/> 4. Para adicionar mais níveis de refino, só editar a seguinte tabela. O primeiro valor é a chance de sucesso, os outros dois são valores lógicos que definem se o item pode regredir de nível ou se pode ter o nível resetado. levels = { [1] = {100, false, false}, [2] = {90, false, false}, [3] = {75, false, false}, [4] = {60, true, false}, [5] = {45, true, false}, [6] = {30, true, false}, [7] = {25, true, false}, [8] = {20, true, true}, [9] = {15, true, true}, [10] = {10, true, true}, }, 5. Para criar novas ferramentas de refinar, edite a seguinte tabela. O index range define de que nível até que nível a ferramenta funciona, o index chance define o bônus de chance que a ferramenta dá e o index removeable define se a ferramenta é infinita para false e, o contrário para true. tools = { [8306] = {range = {0, 10}, info = {chance = 0, removeable = true}}, }, Atenção para a vírgula final nas linhas da tabela, nunca esqueça dela. É isso aí, abraço. Editado 31 Janeiro, 2014 por Garou 6 1 1 anivia2010, itsmeKenji, Slec e 5 outros reagiu a isto Compartilhar este post Link para o post
Lordfire 110 #2 Postado 31 Janeiro, 2014 Nossa, cara, essa lib ficou linda demais. Seu mito. Parabens, ficou sensacional *-* Compartilhar este post Link para o post
karygalock 1 #3 Postado 28 Abril, 2014 parabéns pelo post, muito perfeito e facilmente configurável, unica questão é: é possível fazer aprimorar o ML? para spellbooks, helmets entre outros items que aumentam o ML? :S se sim.. alguém explique plis @_@ iria ficar 100% perfeito Compartilhar este post Link para o post
Oneshot 24 #4 Postado 29 Abril, 2014 (editado) parabéns pelo post, muito perfeito e facilmente configurável, unica questão é: é possível fazer aprimorar o ML? para spellbooks, helmets entre outros items que aumentam o ML? :S se sim.. alguém explique plis @_@ iria ficar 100% perfeito Infelizmente não. Há algumas limitações na função doItemSetAttribute, ela não altera atributos dinâmicos, aqueles que precisam que o item esteja no movements.xml para funcionar, como magiclevelpoints, magiclevelpercent, increasehealth, increasehealthpercent, entre outros. Vou explorar melhor as sources para verificar uma maneira de fazer isso. Já me pediram também para fazer com assassin stars, arrows e bolts, só que como são itens stackable, não vai também mesmo que o item seja infinito, refinar um só e mover ele da backpack para o chão, retorna os atributos ao padrão. Abraço. Editado 29 Abril, 2014 por Oneshot 1 karygalock reagiu a isto Compartilhar este post Link para o post
karygalock 1 #5 Postado 2 Maio, 2014 Ok, muito obrigado! eu fico no aguardo se você conseguir Compartilhar este post Link para o post
victor8 0 #7 Postado 24 Novembro, 2014 (editado) Funciona perfeitamente em tfs 0.3. Aproveitando a deixa. Quero agradecer ao Oneshot, por disponibilizar o script. Hoje em dia é difícil ver alguém divulgar o seu trabalho. Obrigado. Editado 24 Novembro, 2014 por victor8 Compartilhar este post Link para o post