Ir para conteúdo

Featured Replies

Postado

Acabei implementando um sistema de skill stages em meu server, ele até funciona, porém a cada magia que um player utiliza, aparece o seguinte erro no console:

(Estou usando tfs 1.3x)

 

 

Citar

Lua Script Error: [Event Interface]
data/events/scripts/player.lua:Player@onGainSkillTries
data/events/scripts/player.lua:896: bad argument #1 to 'next' (table expected, got nil)
stack traceback:
        [C]: at 0x005be450
        [C]: in function 'next'
        data/events/scripts/player.lua:896: in function <data/events/scripts/player.lua:891>

 

Players.lua:

 -- Internal Use
STONE_SKIN_AMULET = 2197
GOLD_POUNCH = 26377
ITEM_STORE_INBOX = 26052
ITEM_PARCEL = 2595
CONTAINER_PESO = 450000

-- 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 getSeconds(seconds)
	return 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

local function getTimeinWords(secs)
	local hours, minutes, seconds = getHours(secs), getMinutes(secs), getSeconds(secs)
	if (minutes > 59) then
		minutes = minutes-hours*60
	end

	local timeStr = ''

	if hours > 0 then
		timeStr = timeStr .. ' hours '
	end

	timeStr = timeStr .. minutes .. ' minutes and '.. seconds .. 'seconds.'

	return timeStr
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
	else
		description = description .. thing:getDescription(distance)
		if thing:isMonster() then
			local master = thing:getMaster()
			if master and table.contains({'thundergiant','grovebeast','emberwing','skullfrost'}, thing:getName():lower()) then
				description = description..' (Master: ' .. master:getName() .. '). It will disappear in ' .. getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time())
			end
		end
	end

	if self:getGroup():getAccess() then
		if thing:isItem() then
			description = string.format("%s\nItem ID: %d", description, thing:getId())

			local actionId = thing:getActionId()
			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

			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:isPlayer() and 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() then
			if thing:isPlayer() then
				description = string.format("%s\nIP: %s.", description, Game.convertIpToString(thing:getIp()))
			end
		end
	end
	
	if thing:isCreature() then
		if thing:isPlayer() then
			local KD = (math.max(0, thing:getStorageValue(STORAGEVALUE_KILLS)) + math.max(0, thing:getStorageValue(STORAGEVALUE_ASSISTS))) / math.max(1, thing:getStorageValue(STORAGEVALUE_DEATHS))
			description = string.format("%s\nKD: [%0.2f]", description, KD)
		end
	end
	self:sendTextMessage(MESSAGE_INFO_DESCR, description)
end

function Player:onLookInBattleList(creature, distance)
	local description = "You see " .. creature:getDescription(distance)
	if creature:isMonster() then
		local master = creature:getMaster()
		if master and table.contains({'thundergiant','grovebeast','emberwing','skullfrost'}, creature:getName():lower()) then
			description = description..' (Master: ' .. master:getName() .. '). It will disappear in ' .. getTimeinWords(master:getStorageValue(Storage.PetSummon) - os.time())
		end
	end
	if self:getGroup():getAccess() then
		local str = "%s\nHealth: %d / %d"
		if creature:isPlayer() and 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)
	-- No move if item count > 20 items
	local tile = Tile(toPosition)
	if tile and tile:getItemCount() > 20 then
		self:sendCancelMessage(RETURNVALUE_NOTPOSSIBLE)
		return false
	end
	
	-- Loot Analyser apenas 11.x+
	--[[if self:getClient().os == CLIENTOS_NEW_WINDOWS then
    	local t = Tile(fromCylinder:getPosition())
    	local corpse = t:getTopDownItem()
    	if corpse then
    	    local itemType = corpse:getType()
    		if itemType:isCorpse() and toPosition.x == CONTAINER_POSITION then
    		    self:sendLootStats(item)
    		end
    	end
    end]]--

	checkWallArito(item, toPosition)

	-- No move parcel very heavy
	if ItemType(item:getId()):isContainer() and item:getWeight() > CONTAINER_PESO then
       self:sendCancelMessage('You cannot move containers with more than ' .. CONTAINER_PESO .. ' oz.')
        return false
    end

	-- Cults of Tibia begin
	local frompos = Position(33023, 31904, 14) -- Checagem
	local topos = Position(33052, 31932, 15) -- Checagem
	if self:getPosition():isInRange(frompos, topos) and item:getId() == 26397 then
		local tileBoss = Tile(toPosition)
		if tileBoss and tileBoss:getTopCreature() and tileBoss:getTopCreature():isMonster() then
			if tileBoss:getTopCreature():getName():lower() == 'the remorseless corruptor' then
				tileBoss:getTopCreature():addHealth(-17000)
				item:remove(1)
				if tileBoss:getTopCreature():getHealth() <= 300 then
					tileBoss:getTopCreature():remove()
					local monster  = Game.createMonster('the corruptor of souls', toPosition)
					monster:registerEvent('checkPiso')
					if Game.getStorageValue('healthSoul') > 0 then
						monster:addHealth(-(monster:getHealth() - Game.getStorageValue('healthSoul')))
					end
					Game.setStorageValue('checkPiso', os.time()+30)
				end
			elseif tileBoss:getTopCreature():getName():lower() == 'the corruptor of souls' then
				Game.setStorageValue('checkPiso', os.time()+30)
				item:remove(1)
			end
		end
	end
	-- Cults of Tibia end
	
	--- 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() == 2147 and toPosition.x == 33069 and toPosition.y == 32298  and toPosition.z == 9 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 item = Tile(Position(33069, 32298, 9))
			if (item:getItemCountById(1488) > 0) then
			local flameruby = Game.createItem(1488, 1, Position(33069, 32298, 9))
			end
		end

		if item:getId() == 2146 and toPosition.x == 33069 and toPosition.y == 32302  and toPosition.z == 9 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 item = Tile(Position(33069, 32302, 9))
			if (item:getItemCountById(8058) > 0) then
			local flamesapphire = Game.createItem(8058, 1, Position(33069, 32302, 9))
			end
		end

		if item:getId() == 2150 and toPosition.x == 33077 and toPosition.y == 32302  and toPosition.z == 9 then
			-- Amethyst
			self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the amethyst on the small socket. A violet flame begins to burn.")
				checkPr = true
			if lionrock.taskactive.amethyst ~= true then
				lionrock.taskactive.amethyst = true
			end

			local item = Tile(Position(33077, 32302, 9))
			if (item:getItemCountById(1500) > 0) then
			local flameamethyst = Game.createItem(1500, 1, Position(33077, 32302, 9))
			end
		end

		if item:getId() == 9970 and toPosition.x == 33077 and toPosition.y == 32298  and toPosition.z == 9 then
			-- Topaz
			self:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You place the topaz on the small socket. A yellow flame begins to burn.")
				checkPr = true
			if lionrock.taskactive.topaz ~= true then
				lionrock.taskactive.topaz = true
			end

			local item = Tile(Position(33077, 32298, 9))
			if (item:getItemCountById(7473) > 0) then
			local flametopaz = Game.createItem(7473, 1, Position(33077, 32298, 9))
			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(6390, 1, Position(33073, 32300, 9))
				fountain:setActionId(41357)
				local stone = Tile(Position(33073, 32300, 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, 4000, 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

	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

local function hasPendingReport(name, targetName, reportType)
	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

function Player:onReportRuleViolation(targetName, reportType, reportReason, comment, translation)
	local name = self:getName()
	if hasPendingReport(name, targetName, reportType) 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("Reported by: " .. name .. "\n")
	io.write("Target: " .. 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)
	getTrade = 1
	return true
end

function Player:onTradeAccept(target, item, targetItem)
	getTrade = 0
	return true
end

local soulCondition = Condition(CONDITION_SOUL, CONDITIONID_DEFAULT)
soulCondition:setTicks(4 * 60 * 1000)
soulCondition:setParameter(CONDITION_PARAM_SOULGAIN, 1)

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

function Player:onGainExperience(source, exp, rawExp)
    if not source or source:isPlayer() then
        return exp
    end
   
    if CASTEXP[self:getName()] then
        if CASTEXP[self:getName()] <= os.time() then
            exp = (exp * CASTEXP_PERCENT) + exp
        end
    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())

	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

	-- Exp Boost Modifier
	useStaminaXp(self)

		-- Exp stats  Redundante!
	--local staminaMinutes = self:getStamina()
	--local Boost = self:getExpBoostStamina()
	--if staminaMinutes > 2400 and self:isPremium() and Boost > 0 then
	--	self:setBaseXpGain(Game.getExperienceStage(self:getLevel())*2) -- 200 = 1.0x, 200 = 2.0x, ... premium account
	--elseif staminaMinutes > 2400 and self:isPremium() and Boost <= 0 then
	--	self:setBaseXpGain(Game.getExperienceStage(self:getLevel())*1.5) -- 150 = 1.0x, 150 = 1.5x, ... premium account		
	--elseif staminaMinutes <= 2400 and staminaMinutes > 840 and self:isPremium() and Boost > 0 then
	--	self:setBaseXpGain(Game.getExperienceStage(self:getLevel())*1.5) -- 150 = 1.5x		premium account
	--elseif staminaMinutes > 840 and Boost > 0 then
	--	self:setBaseXpGain(Game.getExperienceStage(self:getLevel())*1.5) -- 150 = 1.5x		free account
	--elseif staminaMinutes <= 840 and Boost > 0 then
	--	self:setBaseXpGain(Game.getExperienceStage(self:getLevel())*1) -- 50 = 0.5x	all players
	--elseif staminaMinutes <= 840 then
	--	self:setBaseXpGain(Game.getExperienceStage(self:getLevel())*0.5) -- 50 = 0.5x	all players
	--end


	-- Extra xp to use client 12
	if self:getClient().version >= 1200 then
		exp = (exp * 0.25) + exp
	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 * 2
		elseif staminaMinutes <= 840 then
			exp = exp * 1
		end
	end

	return exp
end

function Player:onLoseExperience(exp)
	return exp
end

SkillsTable = {
  [0] = { --[[ SKILL_FIST ]]
    stage = {
      [{0, 30}] = 50,
      [{31, 50}] = 35,
      [{51, 70}] = 20,
      [{71, 80}] = 15,
	  [{81, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [1] = { --[[ SKILL_CLUB ]]
    stage = {
      [{0, 30}] = 50,
      [{31, 50}] = 35,
      [{51, 70}] = 20,
      [{71, 80}] = 15,
	  [{81, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [2] = { --[[ SKILL_SWORD ]]
    stage = {
      [{0, 30}] = 50,
      [{31, 50}] = 35,
      [{51, 70}] = 20,
      [{71, 80}] = 15,
	  [{81, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [3] = { --[[ SKILL_AXE ]]
    stage = {
      [{0, 30}] = 50,
      [{31, 50}] = 35,
      [{51, 70}] = 20,
      [{71, 80}] = 15,
	  [{81, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [4] = { --[[ SKILL_DISTANCE ]]
    stage = {
      [{0, 30}] = 50,
      [{31, 50}] = 35,
      [{51, 70}] = 20,
      [{71, 80}] = 15,
	  [{81, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [5] = { --[[ SKILL_SHIELD ]]
    stage = {
      [{0, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [6] = { --[[ SKILL_FISHING ]]
    stage = {
      [{0, 20}] = 40,
      [{21, 40}] = 30,
      [{41, 60}] = 20,
	  [{61, 80}] = 10,
      [{81, 100}] = 5,
      [{101, 300}] = 2
    },
    rate = configKeys.RATE_SKILL
  },
  [7] = { --[[ SKILL_MAGLEVEL ]]
    stage = {
      [{0, 25}] = 13,
      [{26, 50}] = 10,
      [{51, 70}] = 6,
	  [{71, 80}] = 5,
      [{81, 90}] = 4,
      [{91, 100}] = 3,
      [{101, 300}] = 2
    },
    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

function Player:onRemoveCount(item)
    -- Apenas cliente 11.x
    if self:getClient().os == CLIENTOS_NEW_WINDOWS then
  	    self:sendWaste(item:getId())
    end
end

local breakableItems = {29087, 3798, 3799, 7539, 7538}
function Player:onUseItem(item, target)	
	local itemId = item:getId()
	if (itemId == 2550) and (target:getId() == 1445) then
		if (target:getActionId() == 32931) then
			if (player:getStorageValue(SECRET_LIBRARY_FINAL_STORAGE) ~= 1) then return true end
			self:teleportTo({x = 32515, y = 32537, z = 12})
			self:getPosition():sendMagicEffect(CONST_ME_MORTAREA)
			self:updateSecretLibraryQuestlog(SL_VELLED_HOARD, 1)
		end
	end
	
	if isInArray({WEAPON_AXE, WEAPON_SWORD, WEAPON_CLUB}, ItemType(itemId):getWeaponType()) then
		if isInArray(breakableItems, target:getId()) then
			local bi_mr = math.random(1, 10)
			if (bi_mr > 7) then
				target:remove()
				target:getPosition():sendMagicEffect(CONST_ME_POFF)
				return false
			else
				target:getPosition():sendMagicEffect(CONST_ME_POFF)
				return false
			end
		end
	end
return true
end

function Player:onSendBestiaryMonsters(requestType, className)
	if (requestType == 1) then
		sendSearchedCreatures(self:getId(), requestType, className)
	else
		sendCreatures(self:getId(), requestType, className)
	end
	return true
end

function Player:onLoadCyclopedia()
	sendRaces(self:getId())
	Charms.sendCharmInfo(self:getId())
	return true
end

function Player:onBestiaryMonsterInfo(monsterId)
	sendMonsterData(self:getId(), monsterId)
	return true
end

function Player:onCharmSlots(charmId, state, raceId)
	Charms.charmSlots(self:getId(), charmId + 1, state, raceId)
	return true
end

function Player:onSendBestiaryTracker(raceId, isEnabled)
	if (isEnabled == true) then
		BestiaryTracker[#BestiaryTracker + 1] = raceId
	else
		BestiaryTracker[#BestiaryTracker] = nil
	end
	
	Bestiary.sendBestiaryTracker(self:getId(), raceId)
	return true
end

 

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.

Visitante
Responder

Quem Está Navegando 0

  • Nenhum usuário registrado visualizando esta página.

Conteúdo Similar

Estatísticas dos Fóruns

  • Tópicos 96.9k
  • Posts 519.9k

Informação Importante

Confirmação de Termo