Ir para conteúdo
  • 0
Entre para seguir isso  
Neykos

Scripting Base do Erick otx 3.10 Bug Stage Skill

Pergunta

Neykos    4
Neykos

Olá tudo bom, estou usando uma base  do Erick da otx 3.10
Com suporte ao tibia 10/11
Porem estou tentando implementar o skill stage mais já tentei todos os códigos que aparecem na busca do google e em diversos forums.
Aqui tem um tópico onde parece 3 scripts com a possível solução, porem já tentei os 3 códigos.

Essa primeira solução não aparece nem um erro no console e também não funciona não sobe nem skills e nem ml dos personagens.

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 

 

O segundo script apanas funciona para skills quando vou utilizar alguma magia aparece erro no console.

Spoiler

SkillsTable = {
  [0] = { --[[ SKILL_FIST ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [1] = { --[[ SKILL_CLUB ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [2] = { --[[ SKILL_SWORD ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [3] = { --[[ SKILL_AXE ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [4] = { --[[ SKILL_DISTANCE ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [5] = { --[[ SKILL_SHIELD ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [6] = { --[[ SKILL_FISHING ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [7] = { --[[ SKILL_MAGLEVEL ]]
    stage = {
      [{0, 50}] = 10,
      [{51, 70}] = 8,
      [{71, 80}] = 7,
      [{81, 90}] = 6,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_MAGIC
  }
}

function getSkillsRate(level, skill)
  local skillRange = SkillsTable[skill]
  if skillRange 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(skill == SKILL_MAGLEVEL and self:getMagicLevel() or self:getEffectiveSkillLevel(skill), skill)
    end
  end
end

O ultimo acontece a mesma coisa que a segunda possível solução skill sobe normalmente sem aparecer qualquer erro no console porem assim que utiliza magia aparece o mesmo erro. 

Spoiler

SkillsTable = {
  [0] = { --[[ SKILL_FIST ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [1] = { --[[ SKILL_CLUB ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [2] = { --[[ SKILL_SWORD ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [3] = { --[[ SKILL_AXE ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [4] = { --[[ SKILL_DISTANCE ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [5] = { --[[ SKILL_SHIELD ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [6] = { --[[ SKILL_FISHING ]]
    stage = {
      [{10, 30}] = 50,
      [{31, 50}] = 30,
      [{51, 70}] = 20,
      [{71, 90}] = 10,
      [{91, 110}] = 5,
      [{111, 300}] = 3
    },
    rate = configKeys.RATE_SKILL
  },
  [7] = { --[[ SKILL_MAGLEVEL ]]
    stage = {
      [{0, 50}] = 10,
      [{51, 70}] = 8,
      [{71, 80}] = 7,
      [{81, 90}] = 6,
      [{91, 110}] = 5,
      [{111, 300}] = 2
    },
    rate = configKeys.RATE_MAGIC
  }
}

function getSkillsRate(level, skill)
  local skillRange = SkillsTable[skill]
  if next(skillRange.stage) then
    for sLevel, multiplier in pairs(skillRange.stage) do
      if level >= sLevel[1] and level <= sLevel[2] then
        return multiplier
      end
    end
  end
  return 1
end

function Player:onGainSkillTries(skill, tries)
	if APPLY_SKILL_MULTIPLIER == false then
    return tries
  end
  local skills = SkillsTable[skill]
  if next(skills) and skills.rate then
    local rate = configManager.getNumber(skills.rate)
    if rate > 0 then
      return tries * rate
    else
      return tries * getSkillsRate(self:getEffectiveSkillLevel(skill), skill)
    end
  end
end

O erro apresentado no segundo e terceiro script são os mesmos.

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

Editado por Neykos
Erros de explicação.

Compartilhar este post


Link para o post
Compartilhar em outros sites

2 respostass a esta questão

Recommended Posts

  • 0
Majesty    1755
Majesty

Opção 1:

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

 

Créditos:  Ninja.

Opção 2:

Substitua o código do seu player.lua por esse:

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

 

Créditos: Beloria, faelzn69

Faça o teste e veja se funciona.

Compartilhar este post


Link para o post
Compartilhar em outros sites
  • 0
Neykos    4
Neykos
15 horas atrás, Majesty disse:

Opção 1:

  Ocultar conteúdo


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

 

Créditos:  Ninja.

Opção 2:

Substitua o código do seu player.lua por esse:

  Ocultar conteúdo


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

 

Créditos: Beloria, faelzn69

Faça o teste e veja se funciona.

Olá bom dia tentei os 2 e ambos não sobem o skill e nem dá erro no console... não acontece nada e na minha config eu deixo sempre como 0 de skills e 0 de magic level.

Compartilhar este post


Link para o post
Compartilhar em outros sites
Visitante
Este tópico está impedido de receber novos posts.
Entre para seguir isso  

  • Quem Está Navegando   0 membros estão online

    Nenhum usuário registrado visualizando esta página.

×