Ir para conteúdo
  • Cadastre-se

Posts Recomendados

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:

image.thumb.png.1f1c36a50b8f25c1d827903509762d41.png

 

 

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:

 

image.thumb.png.596e2fb77719d8032bcb0307c4c167ab.png

 

Desde já, agradeço!!

Link para o post
Compartilhar em outros sites

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 por faelzn69 (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
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:

image.thumb.png.2e4b6a234c9f39235992b09adf3dae01.png

 

mesmo erro de antes!

 

 

OBS.:

Verifiquei e as skills estão funcionando normalmente, só acontece esse erro quando o player usa magia.

 

Obrigado!!!

Link para o post
Compartilhar em outros sites

@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 por faelzn69 (veja o histórico de edições)
Link para o post
Compartilhar em outros sites

@faelzn69, cara fiz as alterações, porém aparece isso agora:

 

image.thumb.png.ac0f46e83399dc39c4cf7f1c6c42e616.png

 

meu código ficou:

Spoiler

local config = {
	[1] = {
		[SKILL_FIST] = {
			[1] = {
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_CLUB] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_SWORD] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_AXE] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_DISTANCE] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_SHIELD] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_FISHING] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_MAGLEVEL] = {				
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 100
			}
		}
	}
	
}

--[[
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 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

function Player:onGainSkillTries(skill, tries)
	if not APPLY_SKILL_MULTIPLIER then
		return tries
	end

	return tries * getSkillRate(self, skill)
end

 

 

Link para o post
Compartilhar em outros sites

@faelzn69 

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.. "Empty Slot, "
					else
						imbuingSlots = imbuingSlots.. "Empty 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: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
	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: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
	--- 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

	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)
	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 = {
	[1] = {
		[SKILL_FIST] = {
			[1] = {
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_CLUB] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_SWORD] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_AXE] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_DISTANCE] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_SHIELD] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_FISHING] = {
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 5
			}
		},
		[SKILL_MAGLEVEL] = {				
			[1] = { 
				"fromLevel" = 10,
				"toLevel" = 19,
				"rate" = 10
			},
			
			[2] = { 
				"fromLevel" = 20,
				"toLevel" = 29,
				"rate" = 100
			}
		}
	}
	
}

--[[
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 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

function Player:onGainSkillTries(skill, tries)
	if not APPLY_SKILL_MULTIPLIER then
		return tries
	end

	return tries * getSkillRate(self, skill)
end

 

 

Link para o post
Compartilhar em outros sites

@beloria, coloque esta tabela

Spoiler

local config = {
	[1] = {
		[SKILL_FIST] = {
			[1] = {
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_CLUB] = {
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_SWORD] = {
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_AXE] = {
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_DISTANCE] = {
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_SHIELD] = {
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_FISHING] = {
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 5
			}
		},
		[SKILL_MAGLEVEL] = {				
			[1] = { 
				fromLevel = 10,
				toLevel = 19,
				rate = 10
			},
			
			[2] = { 
				fromLevel = 20,
				toLevel = 29,
				rate = 100
			}
		}
	}
}		

 

 

Editado por faelzn69 (veja o histórico de edições)
Link para o post
Compartilhar em outros sites
  • 2 weeks later...
  • 2 weeks later...
  • 1 year later...

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

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emojis são permitidos.

×   Seu link foi automaticamente incorporado.   Mostrar como link

×   Seu conteúdo anterior foi restaurado.   Limpar o editor

×   Não é possível colar imagens diretamente. Carregar ou inserir imagens do URL.

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.


  • Conteúdo Similar

    • Por cloudrun2023
      CloudRun - Sua Melhor Escolha para Hospedagem de OTServer!
      Você está procurando a solução definitiva para hospedar seu OTServer com desempenho imbatível e segurança inigualável? Não procure mais! Apresentamos a CloudRun, sua parceira confiável em serviços de hospedagem na nuvem.
       
      Recursos Exclusivos - Proteção DDoS Avançada:
      Mantenha seu OTServer online e seguro com nossa robusta proteção DDoS, garantindo uma experiência de jogo ininterrupta para seus jogadores.
       
      Servidores Ryzen 7 Poderosos: Desfrute do poder de processamento superior dos servidores Ryzen 7 para garantir um desempenho excepcional do seu OTServer. Velocidade e estabilidade garantidas!
       
      Armazenamento NVMe de Alta Velocidade:
      Reduza o tempo de carregamento do jogo com nosso armazenamento NVMe ultrarrápido. Seus jogadores vão adorar a rapidez com que podem explorar o mundo do seu OTServer.
       
      Uplink de até 1GB:
      Oferecemos uma conexão de alta velocidade com até 1GB de largura de banda, garantindo uma experiência de jogo suave e livre de lag para todos os seus jogadores, mesmo nos momentos de pico.
       
      Suporte 24 Horas:
      Estamos sempre aqui para você! Nossa equipe de suporte está disponível 24 horas por dia, 7 dias por semana, para resolver qualquer problema ou responder a qualquer pergunta que você possa ter. Sua satisfação é a nossa prioridade.
       
      Fácil e Rápido de Começar:
      Configurar seu OTServer na CloudRun é simples e rápido. Concentre-se no desenvolvimento do seu jogo enquanto cuidamos da hospedagem.
       
      Entre em Contato Agora!
      Website: https://central.cloudrun.com.br/index.php?rp=/store/cloud-ryzen-brasil
      Email: [email protected]
      Telefone: (47) 99902-5147

      Não comprometa a qualidade da hospedagem do seu OTServer. Escolha a CloudRun e ofereça aos seus jogadores a melhor experiência de jogo possível. Visite nosso site hoje mesmo para conhecer nossos planos e começar!
       
      https://central.cloudrun.com.br/index.php?rp=/store/cloud-ryzen-brasil
       
      CloudRun - Onde a Velocidade Encontra a Confiabilidade!
       

    • Por FeeTads
      SALVE rapaziada do TK, esses dias vim pensando em novos scripts pro meu OT, e em um deles eu precisava que determinada area não contasse frag pro player que matasse outros, PORÉM eu precisava que os players que morressem nessa area ainda assim tivessem as penalidades da sua morte, procurei por ai, achei alguns scripts que apenas tiravam o SKULL e não realmente o FRAG do player.

      **script atualizado 22/10/2023** - melhorado e otimizado, levei o script pra puxar as infos por .lua / creatureScripts

      vou disponibilizar o code aqui, e o que fazer pra determinada area não contar frag.

      SOURCE OTX 2 / TFS 0.x, Funciona em TFS 1.x mudando as tags e ajeitando as sintaxes.

      vá em creatureevent.cpp

      procure por:
      else if(type == "preparedeath") _type = CREATURE_EVENT_PREPAREDEATH;
      Adiciona abaixo:
      else if(type == "nocountfrag") _type = CREATURE_EVENT_NOCOUNTFRAG;

      procure por:
      case CREATURE_EVENT_PREPAREDEATH: return "onPrepareDeath";  
      Adicione abaixo: 
      case CREATURE_EVENT_NOCOUNTFRAG: return "noCountFragArea";

      procure por:
      case CREATURE_EVENT_PREPAREDEATH: return "cid, deathList";
      Adicione abaixo:
      case CREATURE_EVENT_NOCOUNTFRAG: return "cid, target";

      agora no mesmo arquivo, vá até o final do arquivo e adicione essa função:
      uint32_t CreatureEvent::executeNoCountFragArea(Creature* creature, Creature* target) { //noCountFragArea(cid, target) if(m_interface->reserveEnv()) { ScriptEnviroment* env = m_interface->getEnv(); if(m_scripted == EVENT_SCRIPT_BUFFER) { env->setRealPos(creature->getPosition()); std::ostringstream scriptstream; scriptstream << "local cid = " << env->addThing(creature) << std::endl; scriptstream << "local target = " << env->addThing(target) << std::endl; if(m_scriptData) scriptstream << *m_scriptData; bool result = true; if(m_interface->loadBuffer(scriptstream.str())) { lua_State* L = m_interface->getState(); result = m_interface->getGlobalBool(L, "_result", true); } m_interface->releaseEnv(); return result; } else { #ifdef __DEBUG_LUASCRIPTS__ std::ostringstream desc; desc << creature->getName(); env->setEvent(desc.str()); #endif env->setScriptId(m_scriptId, m_interface); env->setRealPos(creature->getPosition()); lua_State* L = m_interface->getState(); m_interface->pushFunction(m_scriptId); lua_pushnumber(L, env->addThing(creature)); lua_pushnumber(L, env->addThing(target)); bool result = m_interface->callFunction(2); m_interface->releaseEnv(); return result; } } else { std::clog << "[Error - CreatureEvent::noCountFragArea] Call stack overflow." << std::endl; return 0; } }

      agora vá em creatureevent.h

      procure por:
      CREATURE_EVENT_PREPAREDEATH
      adicione abaixo:
      CREATURE_EVENT_NOCOUNTFRAG

      procure por:
      uint32_t executePrepareDeath(Creature* creature, DeathList deathList);
      Adicione abaixo:
      uint32_t executeNoCountFragArea(Creature* creature, Creature* target);

      agora vá em player.cpp

      procure por:
      bool Player::onKilledCreature(Creature* target, DeathEntry& entry)
      abaixo de:
      War_t enemy; if(targetPlayer->getEnemy(this, enemy)) { if(entry.isLast()) IOGuild::getInstance()->updateWar(enemy); entry.setWar(enemy); }
      Adicione o seguinte código:
      if (targetPlayer){ CreatureEventList killEvents = getCreatureEvents(CREATURE_EVENT_NOCOUNTFRAG); for (const auto &event : killEvents) { if (!event->executeNoCountFragArea(this, target)) { return true; } } }

      //

      Feito isso, tudo completo na sua source, agora é necessário adicionar o creaturescript dentro do servidor

      vá até creaturescripts/scripts
      crie um arquivo chamado, "noCountFragInArea.lua"
      e dentro dele cole o código:
       
      --[[ script feito por feetads / TibiaKing ]]-- --[[ discord: feetads / FeeTads#0246 ]]-- -- Add positions here for which you do not want to count frags local areas = { [1] = {from = {x = 91, y = 122, z = 7}, to = {x = 98, y = 127, z = 7}}, -- from = area superior esquerda / to = area inferior direita (formando um quadrado) } local onlyKillerInArea = false -- only killer need to be in area? function noCountFragArea(cid, target) if not isCreature(cid) or not isCreature(target) then return true end local posKiller = getPlayerPosition(cid) local posTarget = getPlayerPosition(target) for i = 1, #areas do local area = areas[i] if isInArea(posKiller, area.from, area.to) then if onlyKillerInArea then return false elseif isInArea(posTarget, area.from, area.to) then return false end end end return true end
      agora em creaturescripts.xml
      <event type="nocountfrag" name="fragarea" event="script" value="noCountFragInArea.lua"/>
      agora em creaturescripts/scripts/login.lua
       procure por OU semelhante a esse:
      registerCreatureEvent(cid, "AdvanceSave")
      e abaixo adicione:
      registerCreatureEvent(cid, "fragarea")

      //


      Agora tudo certo, quando quiser adiciona uma area que não pega frag, vá até o script e apenas coloque a area, igual o demonstrado no script

      Exemplo:
      local areas = { [1] = {from = {x = 91, y = 122, z = 7}, to = {x = 98, y = 127, z = 7}}, [2] = {from = {x = 1000, y = 1000, z = 7}, to = {x = 1100, y = 1100, z = 7}}, }
      assim somente colocando a area no script e abrindo o server ou dando /reload, já funcionará a area como não pegar frag.
      Esse sistema pode ser bom pra areas de pvp ativo, onde você ainda quer que o player que morrer perca os atributos, como se fosse uma morte normal, porém não conta frag pra quem matar.
      Bom pra sistemas tipo castle 48h (guild war), onde há diversas mortes e risco de pegar red, atrapalhando a war.

      Façam bom proveito dos scripts, e deixem os créditos no script rsrs

      **Eu fiz as alterações e o simples código por isso vim disponibilizar, créditos meus**
    • Por Muvuka
      Abri canal a força creaturescript acho que funcione no creaturescript cria script creaturescript
       
      <channel id="9" name="HELP" logged="yes"/>
      <channel id="12" name="Report Bugs" logged="yes"/>
      <channel id="13" name="Loot" logged="yes"/>
      <channel id="14" name="Report Character Rules Tibia Rules" logged="yes"/>
      <channel id="15" name="Death Channel"/>
      <channel id="6548" name="DexSoft" level="1"/>
      <channel id="7" name="Reports" logged="yes"/>
       
      antes de 
              if(lastLogin > 0) then adicione isso:
                      doPlayerOpenChannel(cid, CHANNEL_HELP) doPlayerOpenChannel(cid, 1,  2, 3) = 1,2 ,3 Channels, entendeu? NÃO FUNCIONA EU QUERO UM MEIO DE ABRI SEM USA A SOURCE
       
      EU NÃO CONSEGUI ABRI EU NÃO TENHO SOURCE
       
       
    • Por bolachapancao
      Rapaziada seguinte preciso de um script que ao utilizar uma alavanca para até 4 jogadores.
      Os jogadores serão teleportados para hunt durante uma hora e depois de uma hora os jogadores serão teleportados de volta para o templo.
       
      Observação: caso o jogador morra ou saia da hunt o evento hunt é cancelado.

      Estou a base canary
      GitHub - opentibiabr/canary: Canary Server 13.x for OpenTibia community.
       
    • Por RAJADAO
      .Qual servidor ou website você utiliza como base? 
      Sabrehaven 8.0
      Qual o motivo deste tópico? 
      Ajuda com novos efeitos
       
      Olá amigos, gostaria de ajuda para introduzir os seguintes efeitos no meu servidor (usando o Sabrehaven 8.0 como base), adicionei algumas runas novas (avalanche, icicle, míssil sagrado, stoneshower & Thunderstorm) e alguns novos feitiços (exevo mas san, exori san, exori tera, exori frigo, exevo gran mas frigo, exevo gran mas tera, exevo tera hur, exevo frigo hur) mas nenhum dos efeitos dessas magias parece existir no servidor, alguém tem um link para um tutorial ou algo assim para que eu possa fazer isso funcionar?
      Desculpe pelo mau inglês, sou brasileiro.

      Obrigado!


      AVALANCHE RUNE id:3161 \/
      (COMBAT_PARAM_TYPE, COMBAT_ICEDAMAGE)
      (COMBAT_PARAM_EFFECT, CONST_ME_ICEAREA)
      (COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ICE)

      STONESHOWER RUNE id:3175 \/
      (COMBAT_PARAM_TYPE, COMBAT_EARTHDAMAGE)
      (COMBAT_PARAM_EFFECT, CONST_ME_STONES)
      (COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_EARTH)

      THUNDERSTORM RUNE id:3202 \/
      (COMBAT_PARAM_TYPE, COMBAT_ENERGYDAMAGE)
      (COMBAT_PARAM_EFFECT, CONST_ME_E NERGYHIT)
      (COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_ENERGYBALL)

      ICICLE RUNE id:3158 \/
      COMBAT_ICEDAMAGE
      CONST_ME_ICEAREA
      CONST_ANI_ICE

      SANTO MÍSSIL RUNA id:3182 \/
      (COMBAT_PARAM_TYPE, COMBAT_HOLYDAMAGE)
      (COMBAT_PARAM_EFFECT, CONST_ME_HOLYDAMAGE)
      (COMBAT_PARAM_EFFECT, CONST_ME_HOLYAREA)
      (COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_HOLY)

      CONST_ME_PLANTATTACK (exevo gran mas tera)
      CONST_ME_ICETORNADO (exevo gran mas frigo)
      CONST_ME_SMALLPLANTS (exevo tera hur)
      CONST_ME_ICEAREA (exevo frigo hur)
      CONST_ME_ICEATTACK (exori frigo)
      CONST_ME_CARNIPHILA (exori tera)

      EXORI SAN \/
      (COMBAT_PARAM_DISTANCEEFFECT, CONST_ANI_SMALLHOLY)
      CONST_ME_HOLYDAM IDADE

      EXEVO MAS SAN \/
      CONST_ME_HOLYAREA
×
×
  • Criar Novo...

Informação Importante

Confirmação de Termo