Postado Maio 25, 2018 7 anos Boa noite, estou com um problema que persiste e não consigo solucionar. mesmo vendo tópicos sobre o assunto não consegui fazer funcionar a tal Skill em stages. No maximo, funciona as Skills fisicas, porém a MAGIC fica bugada. Eu utilizo o TFS 1.3. Testei os seguintes codigos. Spoiler SkillsTable = { [0] = { --[[ SKILL_FIST ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 10, [{111, 300}] = 3 }, rate = configKeys.RATE_SKILL }, [1] = { --[[ SKILL_CLUB ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 10, [{111, 300}] = 3 }, rate = configKeys.RATE_SKILL }, [2] = { --[[ SKILL_SWORD ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 10, [{111, 300}] = 3 }, rate = configKeys.RATE_SKILL }, [3] = { --[[ SKILL_AXE ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 10, [{111, 300}] = 3 }, rate = configKeys.RATE_SKILL }, [4] = { --[[ SKILL_DISTANCE ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 18, [{91, 110}] = 8, [{111, 300}] = 2 }, rate = configKeys.RATE_SKILL }, [5] = { --[[ SKILL_SHIELD ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 10, [{111, 300}] = 3 }, rate = configKeys.RATE_SKILL }, [6] = { --[[ SKILL_FISHING ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 10, [{111, 300}] = 3 }, rate = configKeys.RATE_SKILL }, [7] = { --[[ SKILL_MAGLEVEL ]] stage = { [{10, 30}] = 100, [{31, 50}] = 70, [{51, 70}] = 40, [{71, 90}] = 20, [{91, 110}] = 5, [{111, 300}] = 1 }, rate = configKeys.RATE_MAGIC } } function getSkillsRate(level, skill) local skillRange = SkillsTable[skill] if next(skillRange.stage) then for sLevel, multiplier in pairs(skillRange.stage) do if level >= sLevel[1] and level <= sLevel[2] then return multiplier end end end return 1 end function Player:onGainSkillTries(skill, tries) if APPLY_SKILL_MULTIPLIER == false then return tries end local skills = SkillsTable[skill] if next(skills) and skills.rate then local rate = configManager.getNumber(skills.rate) if rate > 0 then return tries * rate else return tries * getSkillsRate(self:getEffectiveSkillLevel(skill), skill) end end end Utilizando esse código, deixei no CONFIG.LUA os rates de Skill e Magic em 0. e o erro foi esse: Spoiler local config = { -- base vocationId [1] = { -- skillId [SKILL_FIST] = { -- [{skillLevel}] = skillRate [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_CLUB] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_SWORD] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_AXE] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_DISTANCE] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_SHIELD] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_FISHING] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_MAGLEVEL] = { [{10, 19}] = 10, [{20, 29}] = 5 } } } --[[ function Vocation.getBase(self) local demotion = self:getDemotion() while demotion do local tmp = demotion:getDemotion() if not tmp then return demotion end demotion = tmp end return self end ]] local function getSkillRate(player, skillId) local targetVocation = config[player:getVocation():getBase():getId()] if targetVocation then local targetSkillStage = targetVocation[skillId] if targetSkillStage then local skillLevel = player:getSkillLevel(skillId) for level, rate in pairs(targetSkillStage) do if skillLevel >= level[1] and skillLevel <= level[2] then return rate end end end end return skillId == SKILL_MAGLEVEL and configManager.getNumber(configKeys.RATE_MAGIC) or configManager.getNumber(configKeys.RATE_SKILL) end function Player:onGainSkillTries(skill, tries) if not APPLY_SKILL_MULTIPLIER then return tries end return tries * getSkillRate(self, skill) end Porém apresentaram os seguintes erros: Desde já, agradeço!!
Postado Maio 25, 2018 7 anos Você setou o skill rate como 0 no config.lua e a função retorna esse zero que você configurou no config.lua, linha: return skillId == SKILL_MAGLEVEL and configManager.getNumber(configKeys.RATE_MAGIC) or configManager.getNumber(configKeys.RATE_SKILL) configManager.getNumber(configKeys.RATE_MAGIC) >> retorna o que vc definiu para Magic no config.lua configManager.getNumber(configKeys.RATE_SKILL) >> retorna o que vc definiu para Skill no config.lua As linhas acima estão retornando zero... e ai o algoritmo tenta calcular multiplicando por zero que resulta em zero novamente no código: function Player:onGainSkillTries(skill, tries) if not APPLY_SKILL_MULTIPLIER then return tries end return tries * getSkillRate(self, skill) end 10 horas atrás, Beloria disse: Utilizando esse código, deixei no CONFIG.LUA os rates de Skill e Magic em 0. Altere esses valores, e coloque 1 em tudo. Teste e nos mostre o resultado. Editado Maio 25, 2018 7 anos por faelzn69 (veja o histórico de edições)
Postado Maio 25, 2018 7 anos Autor Spoiler -- Internal Use STONE_SKIN_AMULET = 2197 ITEM_STORE_INBOX = 26052 GOLD_POUNCH = 26377 -- No move items with actionID 8000 NOT_MOVEABLE_ACTION = 8000 -- Players cannot throw items on teleports if set to true local blockTeleportTrashing = true local titles = { {storageID = 14960, title = " Scout"}, {storageID = 14961, title = " Sentinel"}, {storageID = 14962, title = " Steward"}, {storageID = 14963, title = " Warden"}, {storageID = 14964, title = " Squire"}, {storageID = 14965, title = " Warrior"}, {storageID = 14966, title = " Keeper"}, {storageID = 14967, title = " Guardian"}, {storageID = 14968, title = " Sage"}, {storageID = 14969, title = " Tutor"}, {storageID = 14970, title = " Senior Tutor"}, {storageID = 14971, title = " King"}, } local function getTitle(uid) local player = Player(uid) if not player then return false end for i = #titles, 1, -1 do if player:getStorageValue(titles[i].storageID) == 1 then return titles[i].title end end return false end function Player:onBrowseField(position) return true end local function getHours(seconds) return math.floor((seconds/60)/60) end local function getMinutes(seconds) return math.floor(seconds/60) end local function getTime(seconds) local hours, minutes = getHours(seconds), getMinutes(seconds) if (minutes > 59) then minutes = minutes-hours*60 end if (minutes < 10) then minutes = "0" ..minutes end return hours..":"..minutes.. "h" end function Player:onLook(thing, position, distance) local description = 'You see ' if thing:isItem() then if thing.actionid == 5640 then description = description .. 'a honeyflower patch.' elseif thing.actionid == 5641 then description = description .. 'a banana palm.' elseif thing.itemid >= ITEM_HEALTH_CASK_START and thing.itemid <= ITEM_HEALTH_CASK_END or thing.itemid >= ITEM_MANA_CASK_START and thing.itemid <= ITEM_MANA_CASK_END or thing.itemid >= ITEM_SPIRIT_CASK_START and thing.itemid <= ITEM_SPIRIT_CASK_END or thing.itemid >= ITEM_KEG_START and thing.itemid <= ITEM_KEG_END then description = description .. thing:getDescription(distance) local charges = thing:getCharges() if charges then description = string.format('%s\nIt has %d refillings left.', description, charges) end else description = description .. thing:getDescription(distance) end local itemType = thing:getType() if (itemType and itemType:getImbuingSlots() > 0) then local imbuingSlots = "Imbuements: (" for i = 1, itemType:getImbuingSlots() do local specialAttr = thing:getSpecialAttribute(i) local time = 0 if (thing:getSpecialAttribute(i+3)) then time = getTime(thing:getSpecialAttribute(i+3)) end if (specialAttr and specialAttr ~= 0) then if (i ~= itemType:getImbuingSlots()) then imbuingSlots = imbuingSlots.. "" ..specialAttr.." " ..time..", " else imbuingSlots = imbuingSlots.. "" ..specialAttr.." " ..time..")." end else if (i ~= itemType:getImbuingSlots()) then imbuingSlots = imbuingSlots.. "Free Slot, " else imbuingSlots = imbuingSlots.. "Free Slot)." end end end description = string.gsub(description, "It weighs", imbuingSlots.. "\nIt weighs") end else description = description .. thing:getDescription(distance) end if self:getGroup():getAccess() then if thing:isItem() then description = string.format('%s\nItem ID: %d', description, thing.itemid) local actionId = thing.actionid if actionId ~= 0 then description = string.format('%s, Action ID: %d', description, actionId) end local uniqueId = thing:getAttribute(ITEM_ATTRIBUTE_UNIQUEID) if uniqueId > 0 and uniqueId < 65536 then description = string.format('%s, Unique ID: %d', description, uniqueId) end description = description .. '.' local itemType = thing:getType() local transformEquipId = itemType:getTransformEquipId() local transformDeEquipId = itemType:getTransformDeEquipId() if transformEquipId ~= 0 then description = string.format('%s\nTransforms to: %d (onEquip)', description, transformEquipId) elseif transformDeEquipId ~= 0 then description = string.format('%s\nTransforms to: %d (onDeEquip)', description, transformDeEquipId) end local decayId = itemType:getDecayId() if decayId ~= -1 then description = string.format('%s\nDecays to: %d', description, decayId) end elseif thing:isCreature() then local str = '%s\nHealth: %d / %d' if thing:getMaxMana() > 0 then str = string.format('%s, Mana: %d / %d', str, thing:getMana(), thing:getMaxMana()) end description = string.format(str, description, thing:getHealth(), thing:getMaxHealth()) .. '.' end local position = thing:getPosition() description = string.format( '%s\nPosition: %d, %d, %d', description, position.x, position.y, position.z ) if thing:isCreature() and thing:isPlayer() then description = string.format('%s\nIP: %s.', description, Game.convertIpToString(thing:getIp())) end end self:sendTextMessage(MESSAGE_INFO_DESCR, description) end function Player:onLookInBattleList(creature, distance) local description = "You see " .. creature:getDescription(distance) if self:getGroup():getAccess() then local str = "%s\nHealth: %d / %d" if creature:getMaxMana() > 0 then str = string.format("%s, Mana: %d / %d", str, creature:getMana(), creature:getMaxMana()) end description = string.format(str, description, creature:getHealth(), creature:getMaxHealth()) .. "." local position = creature:getPosition() description = string.format( "%s\nPosition: %d, %d, %d", description, position.x, position.y, position.z ) if creature:isPlayer() then description = string.format("%s\nIP: %s", description, Game.convertIpToString(creature:getIp())) end end self:sendTextMessage(MESSAGE_INFO_DESCR, description) end function Player:onLookInTrade(partner, item, distance) self:sendTextMessage(MESSAGE_INFO_DESCR, "You see " .. item:getDescription(distance)) end function Player:onLookInShop(itemType, count) return true end local config = { maxItemsPerSeconds = 1, exhaustTime = 2000, } if not pushDelay then pushDelay = { } end local function antiPush(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder) if toPosition.x == CONTAINER_POSITION then return true end local tile = Tile(toPosition) if not tile then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end local cid = self:getId() if not pushDelay[cid] then pushDelay[cid] = {items = 0, time = 0} end pushDelay[cid].items = pushDelay[cid].items + 1 local currentTime = os.mtime() if pushDelay[cid].time == 0 then pushDelay[cid].time = currentTime elseif pushDelay[cid].time == currentTime then pushDelay[cid].items = pushDelay[cid].items + 1 elseif currentTime > pushDelay[cid].time then pushDelay[cid].time = 0 pushDelay[cid].items = 0 end if pushDelay[cid].items > config.maxItemsPerSeconds then pushDelay[cid].time = currentTime + config.exhaustTime end if pushDelay[cid].time > currentTime then self:sendCancelMessage("You can't move that item so fast.") return false end return true end function Player:onMoveItem(item, count, fromPosition, toPosition, fromCylinder, toCylinder) --- LIONS ROCK START if self:getStorageValue(lionrock.storages.playerCanDoTasks) - os.time() < 0 then local p, i = lionrock.positions, lionrock.items local checkPr = false if item:getId() == lionrock.items.ruby and toPosition.x == p.ruby.x and toPosition.y == p.ruby.y and toPosition.z == p.ruby.z then -- Ruby self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the ruby on the small socket. A red flame begins to burn.") checkPr = true if lionrock.taskactive.ruby ~= true then lionrock.taskactive.ruby = true end local tile = Tile(p.ruby) if tile:getItemCountById(i.redflame) < 1 then Game.createItem(i.redflame, 1, p.ruby) end end if item:getId() == lionrock.items.sapphire and toPosition.x == p.sapphire.x and toPosition.y == p.sapphire.y and toPosition.z == p.sapphire.z then -- Sapphire self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the sapphire on the small socket. A blue flame begins to burn.") checkPr = true if lionrock.taskactive.sapphire ~= true then lionrock.taskactive.sapphire = true end local tile = Tile(p.sapphire) if tile:getItemCountById(i.blueflame) < 1 then Game.createItem(i.blueflame, 1, p.sapphire) end end if item:getId() == lionrock.items.amethyst and toPosition.x == p.amethyst.x and toPosition.y == p.amethyst.y and toPosition.z == p.amethyst.z then -- Amethyst self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the topaz on the small socket. A yellow flame begins to burn.") checkPr = true if lionrock.taskactive.amethyst ~= true then lionrock.taskactive.amethyst = true end local tile = Tile(p.amethyst) if tile:getItemCountById(i.yellowflame) < 1 then Game.createItem(i.yellowflame, 1, p.amethyst) end end if item:getId() == lionrock.items.topaz and toPosition.x == p.topaz.x and toPosition.y == p.topaz.y and toPosition.z == p.topaz.z then -- Topaz self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the amethyst on the small socket. A violet flame begins to burn.") checkPr = true if lionrock.taskactive.topaz ~= true then lionrock.taskactive.topaz = true end local tile = Tile(p.topaz) if tile:getItemCountById(i.violetflame) < 1 then Game.createItem(i.violetflame, 1, p.topaz) end end if checkPr == true then -- Adding the Fountain which gives present if lionrock.taskactive.ruby == true and lionrock.taskactive.sapphire == true and lionrock.taskactive.amethyst == true and lionrock.taskactive.topaz == true then local fountain = Game.createItem(i.rewardfountain, 1, { x=33073, y=32300, z=9}) fountain:setActionId(41357) local stone = Tile({ x=33073, y=32300, z=9}):getItemById(3608) if stone ~= nil then stone:remove() end self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Something happens at the centre of the room ..."); end -- Removing Item item:remove(1) end end ---- LIONS ROCK END -- SSA exhaust local exhaust = { } if toPosition.x == CONTAINER_POSITION and toPosition.y == CONST_SLOT_NECKLACE and item:getId() == STONE_SKIN_AMULET then local pid = self:getId() if exhaust[pid] then self:sendCancelMessage(RETURNVALUE_YOUAREEXHAUSTED) return false else exhaust[pid] = true addEvent(function() exhaust[pid] = false end, 2000, pid) return true end end -- Store Inbox local containerIdFrom = fromPosition.y - 64 local containerFrom = self:getContainerById(containerIdFrom) if (containerFrom) then if (containerFrom:getId() == ITEM_STORE_INBOX and toPosition.y >= 1 and toPosition.y <= 11 and toPosition.y ~= 3) then self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM) return false end end local containerTo = self:getContainerById(toPosition.y-64) if (containerTo) then if (containerTo:getId() == ITEM_STORE_INBOX) then self:sendCancelMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM) return false end -- Gold Pounch if (containerTo:getId() == GOLD_POUNCH) then if (not (item:getId() == ITEM_CRYSTAL_COIN or item:getId() == ITEM_PLATINUM_COIN or item:getId() == ITEM_GOLD_COIN)) then self:sendCancelMessage("You can move only money to this container.") return false end end end -- No move gold pounch if item:getId() == GOLD_POUNCH then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end -- No move items with actionID 8000 if item:getActionId() == NOT_MOVEABLE_ACTION then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end -- Check two-handed weapons if toPosition.x ~= CONTAINER_POSITION then return true end if item:getTopParent() == self and bit.band(toPosition.y, 0x40) == 0 then local itemType, moveItem = ItemType(item:getId()) if bit.band(itemType:getSlotPosition(), SLOTP_TWO_HAND) ~= 0 and toPosition.y == CONST_SLOT_LEFT then moveItem = self:getSlotItem(CONST_SLOT_RIGHT) elseif itemType:getWeaponType() == WEAPON_SHIELD and toPosition.y == CONST_SLOT_RIGHT then moveItem = self:getSlotItem(CONST_SLOT_LEFT) if moveItem and bit.band(ItemType(moveItem:getId()):getSlotPosition(), SLOTP_TWO_HAND) == 0 then return true end end if moveItem then local parent = item:getParent() if parent:getSize() == parent:getCapacity() then self:sendTextMessage(MESSAGE_STATUS_SMALL, Game.getReturnMessage(RETURNVALUE_CONTAINERNOTENOUGHROOM)) return false else return moveItem:moveTo(parent) end end end -- Reward System if toPosition.x == CONTAINER_POSITION then local containerId = toPosition.y - 64 local container = self:getContainerById(containerId) if not container then return true end -- Do not let the player insert items into either the Reward Container or the Reward Chest local itemId = container:getId() if itemId == ITEM_REWARD_CONTAINER or itemId == ITEM_REWARD_CHEST then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end -- The player also shouldn't be able to insert items into the boss corpse local tile = Tile(container:getPosition()) for _, item in ipairs(tile:getItems() or { }) do if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 and item:getName() == container:getName() then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end end end -- Do not let the player move the boss corpse. if item:getAttribute(ITEM_ATTRIBUTE_CORPSEOWNER) == 2^31 - 1 then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end -- Players cannot throw items on reward chest local tile = Tile(toPosition) if tile and tile:getItemById(ITEM_REWARD_CHEST) then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) self:getPosition():sendMagicEffect(CONST_ME_POFF) return false end -- Players cannot throw items on teleports if blockTeleportTrashing and toPosition.x ~= CONTAINER_POSITION then local thing = Tile(toPosition):getItemByType(ITEM_TYPE_TELEPORT) if thing then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) self:getPosition():sendMagicEffect(CONST_ME_POFF) return false end end -- No move parcel very heavy if item:getWeight() > 90000 and item:getId() == ITEM_PARCEL then self:sendCancelMessage('YOU CANNOT MOVE PARCELS TOO HEAVY.') return false end -- No move if item count > 20 items if tile and tile:getItemCount() > 20 then self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) return false end if tile and tile:getItemById(370) then -- Trapdoor self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE) self:getPosition():sendMagicEffect(CONST_ME_POFF) return false end if not antiPush(self, item, count, fromPosition, toPosition, fromCylinder, toCylinder) then return false end return true end function Player:onMoveCreature(creature, fromPosition, toPosition) return true end -- Temporal disable --[[function Player:onReportRuleViolation(targetName, reportType, reportReason, comment, translation) local name = self:getName() local pendingReport = function () local f = io.open(string.format("data/reports/players/%s-%s-%d.txt", name, targetName, reportType), "r") ; if f then io.close(f) return true else return false end end if pendingReport() then self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "Your report is being processed.") return end local file = io.open(string.format("data/reports/players/%s-%s-%d.txt", name, targetName, reportType), "a") if not file then self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "There was an error when processing your report, please contact a gamemaster.") return end io.output(file) io.write("------------------------------\n") io.write("Complainter: " .. name .. "\n") io.write("Reported: " .. targetName .. "\n") io.write("Type: " .. reportType .. "\n") io.write("Reason: " .. reportReason .. "\n") io.write("Comment: " .. comment .. "\n") if reportType ~= REPORT_TYPE_BOT then io.write("Translation: " .. translation .. "\n") end io.write("------------------------------\n") io.close(file) self:sendTextMessage(MESSAGE_EVENT_ADVANCE, string.format("Thank you for reporting %s. Your report will be processed by %s team as soon as possible.", targetName, configManager.getString(configKeys.SERVER_NAME))) return end]] function Player:onReportBug(message, position, category) local name = self:getName() local file = io.open("data/reports/bugs/" .. name .. " report.txt", "a") if not file then self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "There was an error when processing your report, please contact a gamemaster.") return true end io.output(file) io.write("------------------------------\n") io.write("Name: " .. name) if category == BUG_CATEGORY_MAP then io.write(" [Map position: " .. position.x .. ", " .. position.y .. ", " .. position.z .. "]") end local playerPosition = self:getPosition() io.write(" [Player Position: " .. playerPosition.x .. ", " .. playerPosition.y .. ", " .. playerPosition.z .. "]\n") io.write("Comment: " .. message .. "\n") io.close(file) self:sendTextMessage(MESSAGE_EVENT_DEFAULT, "Your report has been sent to " .. configManager.getString(configKeys.SERVER_NAME) .. ".") return true end function Player:onTurn(direction) if self:getGroup():getAccess() and self:getDirection() == direction then local nextPosition = self:getPosition() nextPosition:getNextPosition(direction) self:teleportTo(nextPosition, true) end return true end function Player:onTradeRequest(target, item) return true end function Player:onTradeAccept(target, item, targetItem) return true end local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT) soulCondition:setTicks(4 * 60 * 1000) soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1) function useStaminaImbuing(playerId, itemuid) local player = Player(playerId) if not player then return false end local item = Item(itemuid) if not item then return false end for i = 1, item:getType():getImbuingSlots() do if (item:isActiveImbuement(i+3)) then local staminaMinutes = item:getSpecialAttribute(i+3)/60 if (staminaMinutes > 0) then local currentTime = os.time() local timePassed = currentTime - item:getSpecialAttribute(i+6) if timePassed > 0 then if timePassed > 60 then if staminaMinutes > 2 then staminaMinutes = staminaMinutes - 2 else staminaMinutes = 0 end item:setSpecialAttribute(i+6, currentTime + 120) else staminaMinutes = staminaMinutes - 1 item:setSpecialAttribute(i+6, currentTime + 60) end end item:setSpecialAttribute(i+3, staminaMinutes*60) if (staminaMinutes <= 0) then player:removeCondition(CONDITION_HASTE, item:getId() + i) player:removeCondition(CONDITION_ATTRIBUTES, item:getId() + i) item:setSpecialAttribute(i, 0, i+3, 0, i+6, 0) end end end end end local function useStamina(player) local staminaMinutes = player:getStamina() if staminaMinutes == 0 then return end local playerId = player:getId() local currentTime = os.time() local timePassed = currentTime - nextUseStaminaTime[playerId] if timePassed <= 0 then return end if timePassed > 60 then if staminaMinutes > 2 then staminaMinutes = staminaMinutes - 2 else staminaMinutes = 0 end nextUseStaminaTime[playerId] = currentTime + 120 else staminaMinutes = staminaMinutes - 1 nextUseStaminaTime[playerId] = currentTime + 60 end player:setStamina(staminaMinutes) end local function useStaminaXp(player) local staminaMinutes = player:getExpBoostStamina() / 60 if staminaMinutes == 0 then return end local playerId = player:getId() local currentTime = os.time() local timePassed = currentTime - nextUseXpStamina[playerId] if timePassed <= 0 then return end if timePassed > 60 then if staminaMinutes > 2 then staminaMinutes = staminaMinutes - 2 else staminaMinutes = 0 end nextUseXpStamina[playerId] = currentTime + 120 else staminaMinutes = staminaMinutes - 1 nextUseXpStamina[playerId] = currentTime + 60 end player:setExpBoostStamina(staminaMinutes * 60) end -- useStaminaPrey local function useStaminaPrey(player, name) for i = 1, 3 do if (player:isActiveByName(i-1, name)) then local staminaMinutes = player:getPreyStamina(i-1)/60 if (staminaMinutes > 0) then local playerId = player:getId()+i local currentTime = os.time() local timePassed = currentTime - nextUseStaminaPrey[playerId].Time if timePassed > 0 then if timePassed > 60 then if staminaMinutes > 2 then staminaMinutes = staminaMinutes - 2 else staminaMinutes = 0 end nextUseStaminaPrey[playerId].Time = currentTime + 120 else staminaMinutes = staminaMinutes - 1 nextUseStaminaPrey[playerId].Time = currentTime + 60 end end player:setPreyStamina(i-1, staminaMinutes*60) player:sendPreyTimeLeft(i-1, staminaMinutes*60) end end end end function Player:onUseWeapon(normalDamage, elementType, elementDamage) -- Imbuement local weapon = self:getSlotItem(CONST_SLOT_LEFT) if not weapon or weapon:getType():getWeaponType() == WEAPON_SHIELD then weapon = self:getSlotItem(CONST_SLOT_RIGHT) if not weapon or weapon:getType():getWeaponType() == WEAPON_SHIELD then weapon = nil end end for slot = 1, 10 do local nextEquip = self:getSlotItem(slot) if nextEquip and nextEquip:getType():getImbuingSlots() > 0 then for i = 1, nextEquip:getType():getImbuingSlots() do local slotEnchant = nextEquip:getSpecialAttribute(i) if (slotEnchant) then local percentDamage, enchantPercent = 0, nextEquip:getImbuementPercent(slotEnchant) local typeEnchant = nextEquip:getImbuementType(i) or "" if (typeEnchant ~= "" and typeEnchant ~= "skillShield" and not typeEnchant:find("absorb") and typeEnchant ~= "speed") then useStaminaImbuing(self:getId(), nextEquip:getUniqueId()) end if (typeEnchant ~= "hitpointsleech" and typeEnchant ~= "manapointsleech" and typeEnchant ~= "criticaldamage" and typeEnchant ~= "skillShield" and typeEnchant ~= "magiclevelpoints" and not typeEnchant:find("absorb") and typeEnchant ~= "speed") then local weaponType = nextEquip:getType():getWeaponType() if weaponType ~= WEAPON_NONE and weaponType ~= WEAPON_SHIELD and weaponType ~= WEAPON_AMMO then percentDamage = normalDamage*(enchantPercent/100) normalDamage = normalDamage - percentDamage elementDamage = nextEquip:getType():getAttack()*(enchantPercent/100) end end if (typeEnchant == "hitpointsleech") then local healAmountHP = normalDamage*(enchantPercent/100) self:addHealth(math.abs(healAmountHP)) elseif (typeEnchant == "manapointsleech") then local healAmountMP = normalDamage*(enchantPercent/100) self:addMana(math.abs(healAmountMP)) end if (typeEnchant == "firedamage") then elementType = COMBAT_FIREDAMAGE elseif (typeEnchant == "earthdamage") then elementType = COMBAT_EARTHDAMAGE elseif (typeEnchant == "icedamage") then elementType = COMBAT_ICEDAMAGE elseif (typeEnchant == "energydamage") then elementType = COMBAT_ENERGYDAMAGE elseif (typeEnchant == "deathdamage") then elementType = COMBAT_DEATHDAMAGE end end end end end return normalDamage, elementType, elementDamage end function Player:onCombatSpell(normalDamage, elementDamage, elementType, changeDamage) -- Imbuement local weapon = self:getSlotItem(CONST_SLOT_LEFT) if not weapon or weapon:getType():getWeaponType() == WEAPON_SHIELD then weapon = self:getSlotItem(CONST_SLOT_RIGHT) if not weapon or weapon:getType():getWeaponType() == WEAPON_SHIELD then weapon = nil end end if normalDamage < 0 then for slot = 1, 10 do local nextEquip = self:getSlotItem(slot) if nextEquip and nextEquip:getType():getImbuingSlots() > 0 then for i = 1, nextEquip:getType():getImbuingSlots() do local slotEnchant = nextEquip:getSpecialAttribute(i) if (slotEnchant and type(slotEnchant) == 'string') then local percentDamage, enchantPercent = 0, nextEquip:getImbuementPercent(slotEnchant) local typeEnchant = nextEquip:getImbuementType(i) or "" if (typeEnchant ~= "" and typeEnchant ~= "skillShield" and not typeEnchant:find("absorb") and typeEnchant ~= "speed") then useStaminaImbuing(self:getId(), nextEquip:getUniqueId()) end if (typeEnchant == "firedamage" or typeEnchant == "earthdamage" or typeEnchant == "icedamage" or typeEnchant == "energydamage" or typeEnchant == "deathdamage") then local weaponType = nextEquip:getType():getWeaponType() if weaponType ~= WEAPON_NONE and weaponType ~= WEAPON_SHIELD and weaponType ~= WEAPON_AMMO then percentDamage = normalDamage*(enchantPercent/100) normalDamage = normalDamage - percentDamage elementDamage = nextEquip:getType():getAttack()*(enchantPercent/100) end end if (typeEnchant == "firedamage") then elementType = COMBAT_FIREDAMAGE elseif (typeEnchant == "earthdamage") then elementType = COMBAT_EARTHDAMAGE elseif (typeEnchant == "icedamage") then elementType = COMBAT_ICEDAMAGE elseif (typeEnchant == "energydamage") then elementType = COMBAT_ENERGYDAMAGE elseif (typeEnchant == "deathdamage") then elementType = COMBAT_DEATHDAMAGE end end end end end end return normalDamage, elementDamage, elementType, changeDamage end function Player:onMove() local haveImbuingBoots = self:getSlotItem(CONST_SLOT_FEET) and self:getSlotItem(CONST_SLOT_FEET):getType():getImbuingSlots() or 0 if haveImbuingBoots > 0 then local bootsItem = self:getSlotItem(CONST_SLOT_FEET) for slot = 1, haveImbuingBoots do local slotEnchant = bootsItem:getSpecialAttribute(slot) if (slotEnchant and type(slotEnchant) == 'string') then local typeEnchant = bootsItem:getImbuementType(slot) or "" if (typeEnchant == "speed") then useStaminaImbuing(self:getId(), bootsItem:getUniqueId()) end end end end return true end function Player:onEquipImbuement(item) local itemType = item:getType() for i = 1, itemType:getImbuingSlots() do local slotEnchant = item:getSpecialAttribute(i) if (slotEnchant and type(slotEnchant) == 'string') then conditionHaste = Condition(CONDITION_HASTE, item:getId() + i) conditionSkill = Condition(CONDITION_ATTRIBUTES, item:getId() + i) local skillValue = item:getImbuementPercent(slotEnchant) local typeEnchant = item:getImbuementType(i) or "" if (typeEnchant == "skillSword") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_SWORD, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "skillAxe") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_AXE, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "skillClub") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_CLUB, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "skillDist") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_DISTANCE, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "skillShield") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_SHIELD, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "magiclevelpoints") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_STAT_MAGICPOINTS, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "speed") then conditionHaste:setParameter(CONDITION_PARAM_TICKS, -1) conditionHaste:setParameter(CONDITION_PARAM_SPEED, self:getSpeed() * (skillValue/100)) self:addCondition(conditionHaste) elseif (typeEnchant == "criticaldamage") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_CRITICAL_HIT_CHANCE, 10) conditionSkill:setParameter(CONDITION_PARAM_SKILL_CRITICAL_HIT_DAMAGE, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "hitpointsleech") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_LIFE_LEECH_CHANCE, 100) conditionSkill:setParameter(CONDITION_PARAM_SKILL_LIFE_LEECH_AMOUNT, skillValue) self:addCondition(conditionSkill) elseif (typeEnchant == "manapointsleech") then conditionSkill:setParameter(CONDITION_PARAM_TICKS, -1) conditionSkill:setParameter(CONDITION_PARAM_SKILL_MANA_LEECH_CHANCE, 100) conditionSkill:setParameter(CONDITION_PARAM_SKILL_MANA_LEECH_AMOUNT, skillValue) self:addCondition(conditionSkill) end end end return true end function Player:onDeEquipImbuement(item) for i = 1, item:getType():getImbuingSlots() do self:removeCondition(CONDITION_HASTE, item:getId() + i) self:removeCondition(CONDITION_ATTRIBUTES, item:getId() + i) end return true end function Player:onGainExperience(source, exp, rawExp) if not source or source:isPlayer() then return exp end -- Soul regeneration local vocation = self:getVocation() if self:getSoul() < vocation:getMaxSoul() and exp >= self:getLevel() then soulCondition:setParameter(CONDITION_PARAM_SOULTICKS, vocation:getSoulGainTicks() * 1000) self:addCondition(soulCondition) end -- Apply experience stage multiplier exp = exp * Game.getExperienceStage(self:getLevel()) for i = 1, 3 do if (self:isActive(i-1)) then local bonusInfo = self:getBonusInfo(i-1) if (bonusInfo.Type == 2 and source:getName() == bonusInfo.Name) then exp = exp + math.floor(exp * (bonusInfo.Value/100)) break end end end if (self:getExpBoostStamina() <= 0 and self:getStoreXpBoost() > 0) then self:setStoreXpBoost(0) -- reset xp boost to 0 end -- More compact, after checking before (reset) it only of xp if you have if (self:getStoreXpBoost() > 0) then exp = exp + (exp * (self:getStoreXpBoost()/100)) -- Exp Boost end local party = self:getParty() if (party) then if (party:isSharedExperienceActive() and party:isSharedExperienceEnabled()) then local tableVocs = {} local count = 0 local totalCount = 0 local leaderId = party:getLeader():getVocation():getId() if (leaderId) then tableVocs[leaderId] = 1 count = count + 1 totalCount = totalCount + 1 end for i, v in pairs(party:getMembers()) do local vocId = v:getVocation():getId() if (tableVocs[vocId] == nil) then tableVocs[vocId] = 1 count = count + 1 end totalCount = totalCount + 1 end if (totalCount <= 10 and count >= 4) then exp = exp * 2 end end end -- Prey Stamina Modifier useStaminaPrey(self, source:getName()) -- Exp Boost Modifier useStaminaXp(self) -- Exp stats local staminaMinutes = self:getStamina() local Boost = self:getExpBoostStamina() if staminaMinutes > 2400 and self:isPremium() and Boost > 0 then self:setBaseXpGain(200) -- 200 = 1.0x, 200 = 2.0x, ... premium account elseif staminaMinutes > 2400 and self:isPremium() and Boost <= 0 then self:setBaseXpGain(150) -- 150 = 1.0x, 150 = 1.5x, ... premium account elseif staminaMinutes <= 2400 and staminaMinutes > 840 and self:isPremium() and Boost > 0 then self:setBaseXpGain(150) -- 150 = 1.5x premium account elseif staminaMinutes > 840 and Boost > 0 then self:setBaseXpGain(150) -- 150 = 1.5x free account elseif staminaMinutes <= 840 and Boost > 0 then self:setBaseXpGain(100) -- 50 = 0.5x all players elseif staminaMinutes <= 840 then self:setBaseXpGain(50) -- 50 = 0.5x all players end -- Stamina modifier if configManager.getBoolean(configKeys.STAMINA_SYSTEM) then useStamina(self) local staminaMinutes = self:getStamina() if staminaMinutes > 2400 and self:isPremium() then exp = exp * 1.5 elseif staminaMinutes <= 840 then exp = exp * 0.5 end end return exp end function Player:onLoseExperience(exp) return exp end local config = { -- base vocationId [1] = { -- skillId [SKILL_FIST] = { -- [{skillLevel}] = skillRate [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_CLUB] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_SWORD] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_AXE] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_DISTANCE] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_SHIELD] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_FISHING] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_MAGLEVEL] = { [{10, 19}] = 10, [{20, 29}] = 5 } } } --[[ function Vocation.getBase(self) local demotion = self:getDemotion() while demotion do local tmp = demotion:getDemotion() if not tmp then return demotion end demotion = tmp end return self end ]] local function getSkillRate(player, skillId) local targetVocation = config[player:getVocation():getBase():getId()] if targetVocation then local targetSkillStage = targetVocation[skillId] if targetSkillStage then local skillLevel = player:getSkillLevel(skillId) for level, rate in pairs(targetSkillStage) do if skillLevel >= level[1] and skillLevel <= level[2] then return rate end end end end return skillId == SKILL_MAGLEVEL and configManager.getNumber(configKeys.RATE_MAGIC) or configManager.getNumber(configKeys.RATE_SKILL) end function Player:onGainSkillTries(skill, tries) if not APPLY_SKILL_MULTIPLIER then return tries end return tries * getSkillRate(self, skill) end Esse é meu Player.lua. Configurei pra 1 como você falou e apareceu o seguinte erro: mesmo erro de antes! OBS.: Verifiquei e as skills estão funcionando normalmente, só acontece esse erro quando o player usa magia. Obrigado!!!
Postado Maio 25, 2018 7 anos @Beloria, em primeiro lugar, apesar de ser programador eu não programo LUA ou seja posso estar errado em absolutamente tudo o que eu lhe falar. Vamos por partes, ok? Reconhecendo o erro: player.lua:1047: attempt to compare number with nil Significa que na linha 1047(arquivo player.lua), ele tentou comparar um número com um valor nulo(nil), segue a linha: if skillLevel >= level[1] and skillLevel <= level[2] then Qual número ele comparou? skillLevel Com o que ele comparou esse número? level[1] e level[2] Provavelmente level[1] ou level[2] estão nulos. ---------- Analisando o código: local function getSkillRate(player, skillId) local targetVocation = config[player:getVocation():getBase():getId()] if targetVocation then local targetSkillStage = targetVocation[skillId] if targetSkillStage then local skillLevel = player:getSkillLevel(skillId) for level, rate in pairs(targetSkillStage) do if skillLevel >= level[1] and skillLevel <= level[2] then return rate end end end end return skillId == SKILL_MAGLEVEL and configManager.getNumber(configKeys.RATE_MAGIC) or configManager.getNumber(configKeys.RATE_SKILL) end skillLevel = propiedades do player { player:getSkillLevel(skillId) }level = chave do par { pairs(targetSkillStage) }rate = valor da chave Na linha: for level, rate in pairs(targetSkillRate) do { O algoritmo está passando (em pares) por uma tabela pré definda(local config) na linha 986: local config = { -- base vocationId [1] = { -- skillId [SKILL_FIST] = { -- [{skillLevel}] = skillRate [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_CLUB] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_SWORD] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_AXE] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_DISTANCE] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_SHIELD] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_FISHING] = { [{10, 19}] = 10, [{20, 29}] = 5 }, [SKILL_MAGLEVEL] = { [{10, 19}] = 10, [{20, 29}] = 5 } } } ao tentar acessar um valor da chave level na posição 1 e 2, ou seja level[1] e level[2], supostamente ele deveria retornar 10 e 19 respectivamente. Nosso erro está exatamente aqui. e finalmente baseando se nesses dois valores a função retorna a rate pré definida(linha 986). } Minha opinião: acredito que o erro seja a maneira como o código está programado para retornar os valores da tabela config(linha 986). Até onde eu sei for loops usando pairs em lua é mais ou menos assim: Citar for level, rate in pairs(targetSkillRate) do { level = é apenas um indice do par armazena apenas a posição rate = valor que está na posição level targetSkillRate = tabela Minha possível solução(não testei) { Acredito que cada skill definida na tabela deveria ter sido escrita da seguinte maneira: [SKILL_MAGLEVEL] = { [1] = { "fromLevel" = 10, "toLevel" = 19, "rate" = 10 }, [2] = { "fromLevel" = 20, "toLevel" = 29, "rate" = 5 } } E a código da função getSkillRate: local function getSkillRate(player, skillId) local targetVocation = config[player:getVocation():getBase():getId()] if targetVocation then local targetSkillStage = targetVocation[skillId] if targetSkillStage then local skillLevel = player:getSkillLevel(skillId) for index,level in pairs(targetSkillStage) do if skillLevel >= level["fromLevel"] and skillLevel <= level["toLevel"] then return level["rate"] end end end end return skillId == SKILL_MAGLEVEL and configManager.getNumber(configKeys.RATE_MAGIC) or configManager.getNumber(configKeys.RATE_SKILL) end Note a diferença entre os códigos. Eu particularmente gosto de definir todas as coisas usando strings( "fromLevel" = 10 ).... acho mais fácil de programar, mais óbvio, mais simples de entender(no caso de divulgação do código). Talvez dessa forma funcione corretamente, eu não posso lhe garantir nada pois não testei meu código. Do pouco que sei de LUA e uma pesquisa breve de uma hora, esta é a minha opinião sobre o seu problema. Espero ter ajudado de alguma forma. Recomendo estudar um pouco mais de LUA. } Boa sorte amigo. Editado Maio 25, 2018 7 anos por faelzn69 (veja o histórico de edições)
Participe da conversa
Você pode postar agora e se cadastrar mais tarde. Se você tem uma conta, faça o login para postar com sua conta.