-- Load Lua-made functions
dofile(getDataDir() .. 'functions.lua')
TRUE = 1
FALSE = 0
LUA_ERROR = -1
LUA_NO_ERROR = 0
NORTH = 0
EAST = 1
SOUTH = 2
WEST = 3
SOUTHWEST = 4
SOUTHEAST = 5
NORTHWEST = 6
NORTHEAST = 7
COMBAT_FORMULA_UNDEFINED = 0
COMBAT_FORMULA_LEVELMAGIC = 1
COMBAT_FORMULA_SKILL = 2
COMBAT_FORMULA_VALUE = 3
COMBAT_FORMULA_DAMAGE = 3
CONDITION_PARAM_OWNER = 1
CONDITION_PARAM_TICKS = 2
--CONDITION_PARAM_OUTFIT = 3
CONDITION_PARAM_HEALTHGAIN = 4
CONDITION_PARAM_HEALTHTICKS = 5
CONDITION_PARAM_MANAGAIN = 6
CONDITION_PARAM_MANATICKS = 7
CONDITION_PARAM_DELAYED = 8
CONDITION_PARAM_SPEED = 9
CONDITION_PARAM_LIGHT_LEVEL = 10
CONDITION_PARAM_LIGHT_COLOR = 11
CONDITION_PARAM_MINVALUE = 12
CONDITION_PARAM_MAXVALUE = 13
CONDITION_PARAM_STARTVALUE = 14
CONDITION_PARAM_TICKINTERVAL = 15
CONDITION_PARAM_FORCEUPDATE = 16
CONDITION_PARAM_SKILL_MELEE = 17
CONDITION_PARAM_SKILL_FIST = 18
CONDITION_PARAM_SKILL_CLUB = 19
CONDITION_PARAM_SKILL_SWORD = 20
CONDITION_PARAM_SKILL_AXE = 21
CONDITION_PARAM_SKILL_DISTANCE = 22
CONDITION_PARAM_SKILL_SHIELD = 23
CONDITION_PARAM_SKILL_FISHING = 24
CONDITION_PARAM_STAT_MAXHITPOINTS = 25
CONDITION_PARAM_STAT_MAXMANAPOINTS = 26
CONDITION_PARAM_STAT_MAGICPOINTS = 27
CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT = 28
CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT = 29
CONDITION_PARAM_STAT_MAGICPOINTSPERCENT = 30
CONDITION_PARAM_PERIODICDAMAGE = 31
CONDITION_PARAM_SKILL_MELEEPERCENT = 32
CONDITION_PARAM_SKILL_FISTPERCENT = 33
CONDITION_PARAM_SKILL_CLUBPERCENT = 34
CONDITION_PARAM_SKILL_SWORDPERCENT = 35
CONDITION_PARAM_SKILL_AXEPERCENT = 36
CONDITION_PARAM_SKILL_DISTANCEPERCENT = 37
CONDITION_PARAM_SKILL_SHIELDPERCENT = 38
CONDITION_PARAM_SKILL_FISHINGPERCENT = 39
COMBAT_PARAM_TYPE = 1
COMBAT_PARAM_EFFECT = 2
COMBAT_PARAM_DISTANCEEFFECT = 3
COMBAT_PARAM_BLOCKSHIELD = 4
COMBAT_PARAM_BLOCKARMOR = 5
COMBAT_PARAM_TARGETCASTERORTOPMOST = 6
COMBAT_PARAM_CREATEITEM = 7
COMBAT_PARAM_AGGRESSIVE = 8
COMBAT_PARAM_DISPEL = 9
CALLBACK_PARAM_LEVELMAGICVALUE = 1
CALLBACK_PARAM_SKILLVALUE = 2
CALLBACK_PARAM_TARGETTILE = 3
CALLBACK_PARAM_TARGETCREATURE = 4
COMBAT_NONE = 0
COMBAT_PHYSICALDAMAGE = 1
COMBAT_ENERGYDAMAGE = 2
COMBAT_POISONDAMAGE = 4
COMBAT_FIREDAMAGE = 8
COMBAT_UNDEFINEDDAMAGE = 16
COMBAT_LIFEDRAIN = 32
COMBAT_MANADRAIN = 64
COMBAT_HEALING = 128
CONDITION_NONE = 0
CONDITION_POISON = 1
CONDITION_FIRE = 2
CONDITION_ENERGY = 4
CONDITION_LIFEDRAIN = 8
CONDITION_HASTE = 16
CONDITION_PARALYZE = 32
CONDITION_OUTFIT = 64
CONDITION_INVISIBLE = 128
CONDITION_LIGHT = 256
CONDITION_MANASHIELD = 512
CONDITION_INFIGHT = 1024
CONDITION_DRUNK = 2048
CONDITION_YELL = 4096
CONDITION_REGENERATION = 8192
CONDITION_MUTED = 16384
CONDITION_ATTRIBUTES = 32768
CONDITION_EXHAUST_COMBAT = 65536
CONDITION_EXHAUST_HEAL = 131072
PLAYERLOSS_EXPERIENCE = 0
PLAYERLOSS_MANA = 1
PLAYERLOSS_SKILL = 2
CONST_SLOT_HEAD = 1
CONST_SLOT_NECKLACE = 2
CONST_SLOT_BACKPACK = 3
CONST_SLOT_ARMOR = 4
CONST_SLOT_RIGHT = 5
CONST_SLOT_LEFT = 6
CONST_SLOT_LEGS = 7
CONST_SLOT_FEET = 8
CONST_SLOT_RING = 9
CONST_SLOT_AMMO = 10
CONST_ME_DRAWBLOOD = 0
CONST_ME_LOSEENERGY = 1
CONST_ME_POFF = 2
CONST_ME_BLOCKHIT = 3
CONST_ME_EXPLOSIONAREA = 4
CONST_ME_EXPLOSIONHIT = 5
CONST_ME_FIREAREA = 6
CONST_ME_YELLOW_RINGS = 7
CONST_ME_GREEN_RINGS = 8
CONST_ME_HITAREA = 9
CONST_ME_ENERGYAREA = 10
CONST_ME_ENERGYHIT = 11
CONST_ME_MAGIC_BLUE = 12
CONST_ME_MAGIC_RED = 13
CONST_ME_MAGIC_GREEN = 14
CONST_ME_HITBYFIRE = 15
CONST_ME_HITBYPOISON = 16
CONST_ME_MORTAREA = 17
CONST_ME_SOUND_BLUE = 18
CONST_ME_SOUND_RED = 19
CONST_ME_POISONAREA = 20
CONST_ME_SOUND_YELLOW = 21
CONST_ME_SOUND_PURPLE = 22
CONST_ME_SOUND_BLUE = 23
CONST_ME_SOUND_WHITE = 24
CONST_ME_NONE = 255
CONST_ANI_SPEAR = 0
CONST_ANI_BOLT = 1
CONST_ANI_ARROW = 2
CONST_ANI_FIRE = 3
CONST_ANI_ENERGY = 4
CONST_ANI_POISONARROW = 5
CONST_ANI_BURSTARROW = 6
CONST_ANI_THROWINGSTAR = 7
CONST_ANI_THROWINGKNIFE = 8
CONST_ANI_SMALLSTONE = 9
CONST_ANI_SUDDENDEATH = 10
CONST_ANI_LARGEROCK = 11
CONST_ANI_SNOWBALL = 12
CONST_ANI_POWERBOLT = 13
CONST_ANI_POISON = 14
CONST_ANI_NONE = 255
TALKTYPE_SAY = 1
TALKTYPE_WHISPER = 2
TALKTYPE_YELL = 3
TALKTYPE_BROADCAST = 11
TALKTYPE_ORANGE_1 = 18
TALKTYPE_ORANGE_2 = 19
TALKTYPE_ORANGE = TALKTYPE_ORANGE_1
TALKTYPE_ORANGE_YELL = TALKTYPE_ORANGE_2
MESSAGE_STATUS_CONSOLE_YELLOW = 1
MESSAGE_STATUS_CONSOLE_LBLUE = 4
MESSAGE_STATUS_CONSOLE_ORANGE = 17
MESSAGE_STATUS_CONSOLE_BLUE = 24
MESSAGE_STATUS_CONSOLE_RED = 25
MESSAGE_STATUS_WARNING = 18
MESSAGE_STATUS_DEFAULT = 21
MESSAGE_STATUS_SMALL = 23
MESSAGE_EVENT_ADVANCE = 19
MESSAGE_EVENT_DEFAULT = 20
MESSAGE_INFO_DESCR = 22
TEXTCOLOR_BLUE = 5
TEXTCOLOR_LIGHTBLUE = 35
TEXTCOLOR_LIGHTGREEN = 30
TEXTCOLOR_LIGHTGREY = 129
TEXTCOLOR_RED = 180
TEXTCOLOR_ORANGE = 198
TEXTCOLOR_WHITE_EXP = 215
TEXTCOLOR_NONE = 255
ITEM_TYPE_NONE = 0
ITEM_TYPE_DEPOT = 1
ITEM_TYPE_MAILBOX = 2
ITEM_TYPE_TRASHHOLDER = 3
ITEM_TYPE_CONTAINER = 4
ITEM_TYPE_DOOR = 5
ITEM_TYPE_MAGICFIELD = 6
ITEM_TYPE_TELEPORT = 7
ITEM_TYPE_BED = 8
ITEM_TYPE_KEY = 9
ITEM_TYPE_RUNE = 10
CONST_PROP_BLOCKSOLID = 0
CONST_PROP_HASHEIGHT = 1
CONST_PROP_BLOCKPROJECTILE = 2
CONST_PROP_BLOCKPATHFIND = 3
CONST_PROP_ISVERTICAL = 4
CONST_PROP_ISHORIZONTAL = 5
CONST_PROP_MOVEABLE = 6
CONST_PROP_BLOCKINGANDNOTMOVEABLE = 7
CONST_PROP_SUPPORTHANGABLE = 8
RETURNVALUE_NOERROR = 1
RETURNVALUE_NOTPOSSIBLE = 2
RETURNVALUE_NOTENOUGHROOM = 3
RETURNVALUE_PLAYERISPZLOCKED = 4
RETURNVALUE_PLAYERISNOTINVITED = 5
RETURNVALUE_CANNOTTHROW = 6
RETURNVALUE_THEREISNOWAY = 7
RETURNVALUE_DESTINATIONOUTOFREACH = 8
RETURNVALUE_CREATUREBLOCK = 9
RETURNVALUE_NOTMOVEABLE = 10
RETURNVALUE_DROPTWOHANDEDITEM = 11
RETURNVALUE_BOTHHANDSNEEDTOBEFREE = 12
RETURNVALUE_CANONLYUSEONEWEAPON = 13
RETURNVALUE_NEEDEXCHANGE = 14
RETURNVALUE_CANNOTBEDRESSED = 15
RETURNVALUE_PUTTHISOBJECTINYOURHAND = 16
RETURNVALUE_PUTTHISOBJECTINBOTHHANDS = 17
RETURNVALUE_TOOFARAWAY = 18
RETURNVALUE_FIRSTGODOWNSTAIRS = 19
RETURNVALUE_FIRSTGOUPSTAIRS = 20
RETURNVALUE_CONTAINERNOTENOUGHROOM = 21
RETURNVALUE_NOTENOUGHCAPACITY = 22
RETURNVALUE_CANNOTPICKUP = 23
RETURNVALUE_THISISIMPOSSIBLE = 24
RETURNVALUE_DEPOTISFULL = 25
RETURNVALUE_CREATUREDOESNOTEXIST = 26
RETURNVALUE_CANNOTUSETHISOBJECT = 27
RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE = 28
RETURNVALUE_NOTREQUIREDLEVELTOUSERUNE = 29
RETURNVALUE_YOUAREALREADYTRADING = 30
RETURNVALUE_THISPLAYERISALREADYTRADING = 31
RETURNVALUE_YOUMAYNOTLOGOUTDURINGAFIGHT = 32
RETURNVALUE_DIRECTPLAYERSHOOT = 33
RETURNVALUE_NOTENOUGHLEVEL = 34
RETURNVALUE_NOTENOUGHMAGICLEVEL = 35
RETURNVALUE_NOTENOUGHMANA = 36
RETURNVALUE_NOTENOUGHSOUL = 37
RETURNVALUE_YOUAREEXHAUSTED = 38
RETURNVALUE_PLAYERISNOTREACHABLE = 39
RETURNVALUE_CANONLYUSETHISRUNEONCREATURES = 40
RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE = 41
RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER = 42
RETURNVALUE_YOUMAYNOTATTACKAPERSONINPROTECTIONZONE = 43
RETURNVALUE_YOUMAYNOTATTACKAPERSONWHILEINPROTECTIONZONE = 44
RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE = 45
RETURNVALUE_YOUCANONLYUSEITONCREATURES = 46
RETURNVALUE_CREATUREISNOTREACHABLE = 47
RETURNVALUE_TURNSECUREMODETOATTACKUNMARKEDPLAYERS = 48
RETURNVALUE_YOUNEEDPREMIUMACCOUNT = 49
RETURNVALUE_YOUNEEDTOLEARNTHISSPELL = 50
RETURNVALUE_YOURVOCATIONCANNOTUSETHISSPELL = 51
RETURNVALUE_YOUNEEDAWEAPONTOUSETHISSPELL = 52
RETURNVALUE_PLAYERISPZLOCKEDLEAVEPVPZONE = 53
RETURNVALUE_PLAYERISPZLOCKEDENTERPVPZONE = 54
RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE = 55
RETURNVALUE_YOUCANNOTLOGOUTHERE = 56
RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL = 57
RETURNVALUE_CANNOTCONJUREITEMHERE = 58
RETURNVALUE_YOUNEEDTOSPLITYOURSPEARS = 59
RETURNVALUE_NAMEISTOOAMBIGIOUS = 60
RETURNVALUE_YOUARENOTTHEOWNER = 61
ITEM_GOLD_COIN = 2148
ITEM_PLATINUM_COIN = 2152
ITEM_CRYSTAL_COIN = 2160
function doPlayerGiveItem(cid, itemid, count, charges)
local hasCharges = (isItemRune(itemid) == TRUE or isItemFluidContainer(itemid) == TRUE)
if(hasCharges and charges == nil) then
charges = 1
end
while count > 0 do
local tempcount = 1
if(hasCharges) then
tempcount = charges
end
if(isItemStackable(itemid) == TRUE) then
tempcount = math.min (100, count)
end
local ret = doPlayerAddItem(cid, itemid, tempcount)
if(ret == LUA_ERROR) then
ret = doCreateItem(itemid, tempcount, getPlayerPosition(cid))
end
if(ret ~= LUA_ERROR) then
if(hasCharges) then
count = count-1
else
count = count-tempcount
end
else
return LUA_ERROR
end
end
return LUA_NO_ERROR
end
function doPlayerTakeItem(cid, itemid, count)
if(getPlayerItemCount(cid,itemid) >= count) then
while count > 0 do
local tempcount = 0
if(isItemStackable(itemid) == TRUE) then
tempcount = math.min (100, count)
else
tempcount = 1
end
local ret = doPlayerRemoveItem(cid, itemid, tempcount)
if(ret ~= LUA_ERROR) then
count = count-tempcount
else
return LUA_ERROR
end
end
if(count == 0) then
return LUA_NO_ERROR
end
else
return LUA_ERROR
end
end
function doPlayerAddMoney(cid, amount)
local crystals = math.floor(amount/10000)
amount = amount - crystals*10000
local platinum = math.floor(amount/100)
amount = amount - platinum*100
local gold = amount
local ret = 0
if(crystals > 0) then
ret = doPlayerGiveItem(cid, ITEM_CRYSTAL_COIN, crystals)
if(ret ~= LUA_NO_ERROR) then
return LUA_ERROR
end
end
if(platinum > 0) then
ret = doPlayerGiveItem(cid, ITEM_PLATINUM_COIN, platinum)
if(ret ~= LUA_NO_ERROR) then
return LUA_ERROR
end
end
if(gold > 0) then
ret = doPlayerGiveItem(cid, ITEM_GOLD_COIN, gold)
if(ret ~= LUA_NO_ERROR) then
return LUA_ERROR
end
end
return LUA_NO_ERROR
end
function doPlayerBuyItem(cid, itemid, count, cost, charges)
if(doPlayerRemoveMoney(cid, cost) == TRUE) then
return doPlayerGiveItem(cid, itemid, count, charges)
else
return LUA_ERROR
end
end
function doPlayerSellItem(cid, itemid, count, cost)
if(doPlayerTakeItem(cid, itemid, count) == LUA_NO_ERROR) then
if(doPlayerAddMoney(cid, cost) ~= LUA_NO_ERROR) then
error('Could not add money to ' .. getPlayerName(cid) .. '(' .. cost .. 'gp)')
end
return LUA_NO_ERROR
else
return LUA_ERROR
end
end
function string.explode(str, delimiter)
if str == nil then
return {}
end
t = {}
for v in string.gmatch(str, "([^,]*)" .. delimiter .. "?") do
table.insert(t, v)
end
table.remove(t) -- Removes last element (Always "")
return t
end
function string.strip_whitespace(str)
if str == nil then return str end
local start = string.find(str, "[^%s]") -- First non-whitespace character
local _end = #str + 1 - string.find(str:reverse(), "[^%s]") -- Last non-whitespace character
if start ~= nil and _end ~= nil then
return string.sub(str, start, _end)
elseif start ~= nil then
return string.sub(str, start)
elseif _end ~= nil then
return string.sub(str, 1, _end)
end
return str
end
function getPlayerByAccountNumber(acc)
players = getPlayersByAccountNumber(acc)
if #players == 0 then
return 0
end
return players[1]
end
function convertIntToIP(int, mask)
local b4 = bit.urshift(bit.uband(int, 4278190080), 24)
local b3 = bit.urshift(bit.uband(int, 16711680), 16)
local b2 = bit.urshift(bit.uband(int, 65280), 8)
local b1 = bit.urshift(bit.uband(int, 255), 0)
if mask ~= nil then
local m4 = bit.urshift(bit.uband(mask, 4278190080), 24)
local m3 = bit.urshift(bit.uband(mask, 16711680), 16)
local m2 = bit.urshift(bit.uband(mask, 65280), 8)
local m1 = bit.urshift(bit.uband(mask, 255), 0)
if (m1 == 255 or m1 == 0) and (m2 == 255 or m2 == 0) and (m3 == 255 or m3 == 0) and (m4 == 255 or m4 == 0) then
if m1 == 0 then b1 = "x" end
if m2 == 0 then b2 = "x" end
if m3 == 0 then b3 = "x" end
if m4 == 0 then b4 = "x" end
else
if m1 ~= 255 or m2 ~= 255 or m3 ~= 255 or m4 ~= 255 then
return b1 .. "." .. b2 .. "." .. b3 .. "." .. b4 .. " : " .. m1 .. "." .. m2 .. "." .. m3 .. "." .. m4
end
end
end
return b1 .. "." .. b2 .. "." .. b3 .. "." .. b4
end
function convertIPToInt(str)
local maskindex = str:find(":")
if maskindex ~= nil then
-- IP:Mask style
if maskindex <= 1 then
return 0, 0
else
ipstring = str:sub(1, maskindex - 1)
maskstring = str:sub(maskindex)
local ipint = 0
local maskint = 0
local index = 0
for b in ipstring:gmatch("(%d+).?") do
if tonumber(b) > 255 or tonumber(b) < 0 then
return 0, 0
end
ipint = bit.ubor(ipint, bit.ulshift(b, index))
index = index + 8
if index > 24 then
break
end
end
if index ~= 32 then -- Invalid
return 0, 0
end
index = 0
for b in maskstring:gmatch("(%d+)%.?") do
if tonumber(b) > 255 or tonumber(b) < 0 then
return 0, 0
end
maskint = bit.ubor(maskint, bit.ulshift(b, index))
index = index + 8
if index > 24 then
break
end
end
if index ~= 32 then
return 0, 0
end
return ipint, maskint
end
else
local ipint = 0
local maskint = 0
local index = 24
for b in str:gmatch("([x%d]+)%.?") do
if b ~= "x" then
if b:find("x") ~= nil then
return 0, 0
end
if tonumber(b) > 255 or tonumber(b) < 0 then
return 0, 0
end
maskint = bit.ubor(maskint, bit.ulshift(255, index))
ipint = bit.ubor(ipint, bit.ulshift(b, index))
end
index = index - 8
if index < 0 then
break
end
end
if index ~= -8 then -- Invalid
return 0, 0
end
return ipint, maskint
end
end
dofile(getDataDir() .. "game_classes/calculator.lua")
--]]
-- Global consts
MAGES = 1
PALADINS = 2
KNIGHTS = 3
ROOKERS = 4
Calculator = {}
Calculator.__index = Calculator
-- Returns the experience of the desired level
function Calculator:getLevelExp(level)
return (50 / 3) * level ^ 3 - (100 * level ^ 2) + ((850 / 3) * level) - 200
end
-- Returns the experience left between a current level and a desired level
function Calculator:getExpLeft(currentLevel, desiredLevel)
return self:getLevelExp(desiredLevel) - self:getLevelExp(currentLevel)
end
-- Returns the exp gain percent into the exp left to up a level
function Calculator:getExpGainPercent(creatureExp, currentLevel)
return (100 * creatureExp) / (self:getExpLeft(currentLevel, currentLevel + 1))
end
-- Returns how much creatures the player have to kill to get the desired level beeing in the current level
function Calculator:getCreatureLeft(currentLevel, desiredLevel, creatureExp)
return (self:getExpLeft(currentLevel, desiredLevel) / getConfigInfo(rateExp)) * (1 / creatureExp)
end
-- Returns how much the creature's exp represents in percent in the current level exp of a player
function Calculator:getCreatureExpPercent(level, creatureExp)
local levelExp = self:getLevelExp(level)
local totalExp = levelExp + creatureExp
return ((totalExp - levelExp) / totalExp) * 100
end
-- Returns how much mana points the player have to spend to advance to the next magic level
function Calculator:getMPLeft(currentML, vocation)
local multipliers = {1.1, 1.4, 3}
return 1600 * multipliers[vocation] ^ currentML
end
-- Returns the cap of a player
function Calculator:getCap(level, vocation)
local capGain = {10, 20, 25, 10}
return (level - 8) * capGain[vocation] + 470
end
-- Returns the free cap percent of a player
function Calculator:getCapStats(cid, level, vocation)
return (getPlayerFreeCap(cid) / self:getCap(level, vocation)) * 100
end
-- Returns the experience gained by the killer in enforced servers
function Calculator:getEnforcedExpGain(killerLevel, victimLevel)
return (1 - (math.floor(killerLevel * 0.9) / victimLevel)) * 0.05 * self:getLevelExp(victimLevel)
end
-- Returns how much worms a player can buy with a desired amount of money
function Calculator:getWormsAmount(money)
return money * 1.2
end
How can i put this to get exp from lower lvls?
It's an enforced war server, using Avesta 7.6...