Por
Garou
Nome: Perfect Upgrade System
Tipo: Biblioteca, Action, Sistema
Autor: Oneshot
Essa é a versão final do Perfect Refine System ou Perfect Upgrade System criado por mim.
É um sistema construído em cima de funções em POO (orientação a objetos), o que o torna muito versátil, possibilitando a outros programadores/scripters criarem seus próprios sistemas com base na biblioteca.
A função do sistema é simples. Não passa de um sistema de refino, presente em todos os servidores, onde você usa um item em um equipamento e este fica mais forte e ganha um nome caracterizando o nível de força - bem clichê - mas muito interessante.
Meu sistema é um pouco diferente dos outros, pois possui algumas características exclusivas, listadas abaixo:
O nível máximo configurável é praticamente ilimitado
O sistema funciona com armas de combate corpo-a-corpo, bows e crossbows.
O refino pode falhar, não acontecendo nada, regredindo o nível ou resetando ele.
Há um sistema nativo de broadcasts, que são enviados quando um jogador consegue refinar um equipamento até um certo nível ou maior.
As chances são configuradas manualmente e sua randomização é muito precisa.
Há dois modos de instalar o sistema em seu servidor, o primeiro é baixar a pasta com os scripts necessários e apenas copiar as chaves nos arquivos XMLs ou então seguir o curto tutorial de instalação.
Crie um arquivo chamado upgradesystem.lua na pasta data/lib e copie o conteúdo abaixo:
--[[
PERFECT UPGRADE SYSTEM
2.0
Criado por Oneshot
É 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
Crie um arquivo chamado upgrade.lua em data/actions/scripts e cole o conteúdo abaixo:
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
No arquivo actions.xml, cole a seguinte linha:
<action itemid="8306" event="script" value="upgrade.lua"/>
Para adicionar mais níveis de refino no sistema, edite a seguinte tabela:
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}
},
Por padrão, ela já está configurado como na maioria dos MMORPGs, 10 níveis de refino, com chances de sucesso, regressão e "quebra". Mas se você quiser, por exemplo, adicionar mais dois níveis, siga o modelo, sempre colocando uma vírgula no final com exceção da última linha da tabela:
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}
},
O primeiro valor é chance de sucesso, o segundo se o item pode regredir na tentativa e o terceiro é se o item para "quebrar" (perder todo o nível de refino). Para criar novas ferramentas (itens) de refinar, configure a tabela abaixo:
tools = {
[8306] = {range = {0, 10}, info = {chance = 0, removeable = true}},
},
Seguindo o mesmo esquema da tabela anterior, vírgulas em todas as linhas com exceção da última, seguindo o modelo abaixo. Por exemplo, uma ferramenta de ID 8303 que refine do level +6 ao +10, que dê 10% de chance bônus e que seja finita, eu faço assim:
tools = {
[8306] = {range = {0, 10}, info = {chance = 0, removeable = true}},
[8310] = {range = {6, 10}, info = {chance = 10, removeable = true}}
},
Em breve vídeo de demonstração com sistema em funcionamento.
Perfect Upgrade System.rar