FapFap 13 Report post Posted September 25, 2017 (edited) Hey can someone explain me how amplifier works? ex: this is Mini Amplifier( lv 10-40 ) Quote function ItemUse_WeiXing( role , Item ) local statelv = 1 local ChaStateLv = GetChaStateLv ( role , STATE_SBJYGZ ) if ChaStateLv > statelv then SystemNotice ( role , "Better fruit in effect. Please try again later." ) UseItemFailed ( role ) return end local lv_star = GetChaAttr( role , ATTR_LV) if lv_star > 40 then SystemNotice ( role , "Effective only for those below Lv 40" ) UseItemFailed ( role ) return end SystemNotice ( role , "Mini Amplifier has been used." ) local statetime = 60+5*(lv_star-1) local Cha_Boat = 0 Cha_Boat = GetCtrlBoat ( role ) if Cha_Boat == nil then AddState( role , role , STATE_SBJYGZ , statelv , statetime ) else AddState( Cha_Boat , Cha_Boat , STATE_SBJYGZ , statelv , statetime ) end end What i want to know is where to edit the Double Exp it adds? 2. How to make it give random Time when you use it! Like i used it and i got 3min double exp.. next time i use it i get 4min and soo.. random.. 3. Is there a possibility to make amp run even if you relog? ex: i used amp and i had dc or i went off, when i log back on, the time continues right where i left, and how?!.. Edited September 25, 2017 by FapFap Quote Share this post Link to post Share on other sites
Angelix 374 Report post Posted September 27, 2017 EXP effect is determined on function ShareTeamExp (I guess it's called like that, located on exp_and_level.lua). Yes, just change statetime to math.random(X, Y). Values must be in seconds. Yes, by using serialize functions table.save and table.load. Quote Share this post Link to post Share on other sites
MonkeyCode 453 Report post Posted September 27, 2017 print('Loading amplifier.lua') --[[---------------------------------------- amplifier handler for KOP/TOP/PKO 1.3X version 1.1 [email protected] credits: [email protected] for code review -------------------------------------------- INFO: EXP and DROP rate no longer used as states Single file data Upon getting killed (by monsters and players), players will lose their bonus EXP and DROP rate will persist throughout diconnection and/or server restart every couple minutes, players will receive a message on the remaining time players will not be allowed to use lower tier amps if a higher tier is active players will be notified when an amp has come to an end TODO: Autocreate folders poor performance (better if load once on enter_map/enter_game) --]]---------------------------------------- local string,os,math,io,table = string,os,math,io,table if table.load == nil then error('serialize.lua cannot be found!') end local minToSec = minToSec or function(min) return min * 60 end local ToClockFormat = ToClockFormat or function(sec) local num = tonumber(sec) if(num == 0)then return "00:00:00" else now_hour = string.format("%02.f",math.floor(num / 3600 )) now_minute = string.format("%02.f",math.floor(num / 60 - (now_hour*60))) now_second = string.format("%02.f",math.floor(num - now_hour*3600 - now_minute*60)) return now_hour..":"..now_minute..":"..now_second end end local file_exists = file_exists or function(name) local f = io.open(name, 'r') if(f ~= nil)then io.close(f) return true else return false end end local explode = explode or function(separator, str) local pos, arr = 0, {} for st, sp in function() return string.find(str, separator, pos, true) end do table.insert(arr, string.sub(str, pos, st-1)) pos = sp + 1 end table.insert(arr, string.sub(str, pos)) return arr end local function num2hex(IN) local B,K,OUT,I,D=16,"0123456789ABCDEF","",0 while IN>0 do I=I+1 IN,D=math.floor(IN/B),math.mod(IN,B)+1 OUT=string.sub(K,D,D)..OUT end return OUT end ampData_conf = { path = GetResPath('../lua/database/'), db = 'persistamp.dat' } local function initamp() -- itemid,state,statelv,lvmin,lvma,minutes,functionName local lm = LV_LIMIT -- EXP FRUITS amp.add(0898, 'xp', 002, 30, lm, 015, 'ItemUse_MoreItemAndExpGz') -- Mystical Fruit amp.add(1128, 'xp', 002, 00, 40, 005, 'ItemUse_WeiXing') -- mini amp amp.add(2586, 'xp', 3.5, 75, lm, 030, 'ItemUse_MoreExpGzLv3x5A') -- 3.5x EXP amp amp.add(2587, 'xp', 004, 80, lm, 030, 'ItemUse_MoreExpGzLv4A') -- 4x EXP amp amp.add(2645, 'xp', 002, 00, lm, 120, 'ItemUse_ZJSB') -- Mid Amplifier of Strive amp.add(2646, 'xp', 002, 00, lm, 240, 'ItemUse_GJSB') -- High Amplifier of Strive amp.add(2647, 'xp', 002, 00, lm, 360, 'ItemUse_CJSB') -- Super Amplifier of Strive amp.add(2648, 'xp', 002, 00, lm, 480, 'ItemUse_MHSB') -- Ultra Amplifier of Strive amp.add(3094, 'xp', 002, 00, lm, 030, 'ItemUse_MoreExpGzA') -- amp of strive amp.add(3095, 'xp', 2.5, 60, lm, 030, 'ItemUse_MoreExpGzLv3A') -- hi amp of strive amp.add(3844, 'xp', 002, 00, lm, 015, 'ItemUse_MoreExpGz') -- heavens berry amp.add(5638, 'xp', 002, 40, lm, 015, 'ItemUse_molilucky') -- Novice 2X Exp Fruit amp.add(5639, 'xp', 003, 50, lm, 030, 'ItemUse_moliegis') -- 3x Exp Fruit amp.add(5694, 'xp', 3.5, 75, lm, 030, 'ItemUse_MoreExpGzLv3x5A') -- 3.5x EXP amp amp.add(5695, 'xp', 004, 80, lm, 030, 'ItemUse_MoreExpGzLv4A') -- 4x EXP amp amp.add(5767, 'xp', 003, 70, lm, 030, 'ItemUse_HighExpGzLv3A') -- 3x EXP amp amp.add(6405, 'xp', 002, 00, 40, 015, 'ItemUse_molilucky') -- Magic Lucky Fruit amp.add(6406, 'xp', 005, 50, 75, 030, 'ItemUse_molibless1') -- Magic Blessing Fruit amp.add(8330, 'xp', 003, 50, lm, 030, 'ItemUse_moliegis') -- 3x Exp Fruit -- DROP FRUITS amp.add(3096, 'mf', 002, 00, lm, 030, 'ItemUse_MoreItemGzA') -- amp of luck amp.add(3097, 'mf', 003, 60, lm, 030, 'ItemUse_MoreItemGzLv3A') -- hi amp of luck amp.add(3845, 'mf', 002, 00, lm, 015, 'ItemUse_MoreItemGz') -- charmed berry amp.add(5640, 'mf', 003, 60, lm, 030, 'ItemUse_molimoney') -- 3x Drop Fruit amp.add(8331, 'mf', 003, 60, lm, 030, 'ItemUse_molimoney') -- 3x Drop Fruit -- CLEAN DATABASE IF NECCESSARY amp.cleandata() end ampData_fruit = {} local function ampData_addFruit(id, bonus, rate, minLv, maxLv, min, funcName) ampData_fruit[id] = { bonus = bonus, rate = rate, minLv = minLv, maxLv = maxLv, min = min } -- hook original ItemUse_* to call/replace custom one (UseAmpDefault) _G[funcName] = function(cha, item) UseAmpDefault(cha, item) end end -- Creates a database file given path and filename local function CreateDatabase(path, db) if not file_exists(path..db) then local f = io.open(path..db, 'a') table.save({}, path..db) f:close() end return table.load(path..db) end -- reading routine of database file -- id - Player ID -- type - 'xp' or 'mf' local function GetChaAmpData(id, type) local t = amp.loadtable(ampData_conf['path'], ampData_conf['db']) if t[id] == nil then return 1,nil end local a,b = string.find(t[id], type) if not a and not b then return 1,nil end b = b + 2 local c = string.find(t[id], ';', b) local data = string.sub(t[id], b, c-1) -- exp=statelv,os.time; local ret = explode(',', data) ret[1] = tonumber(ret[1]) ret[2] = tonumber(ret[2], 16) -- hex here return ret[1], ret[2] end -- writing routine of database file -- insert "state" into file for persistency -- id - Player ID -- type - 'xp' or 'mf' -- ampState - the level of the state -- statesec - remaining time of state in seconds local function InsertToAmpDatabase(id, type, ampState, statesec) local t = amp.loadtable(ampData_conf['path'], ampData_conf['db']) local str = type..'='..ampState..','..statesec..';' if t[id] == nil then t[id] = str else local a,b = string.find(t[id], type) if not a and not b then t[id] = t[id]..str else -- recursion here cuz im lazy amp.deldata(id, type) return InsertToAmpDatabase(id, type, ampState, statesec) end end table.save(t, ampData_conf['path']..ampData_conf['db']) end -- deletion of state in database -- id - Player ID -- type - state to delete local function DeleteAmpData(id, type) local t = amp.loadtable(ampData_conf['path'], ampData_conf['db']) local a,b = string.find(t[id], type) if not a and not b then return end b = b + 2 local c = string.find(t[id], ';', b) local str = string.sub(t[id], a, c) local d = string.gsub(t[id], str, '') t[id] = d if t[id] == '' then t[id] = nil end table.save(t, ampData_conf['path']..ampData_conf['db']) end -- automatic cleans db upon loaded/updateall local function CleanAmpData() local t = amp.loadtable(ampData_conf['path'], ampData_conf['db']) for i,v in pairs(t) do local chaState,chaTime = amp.getdata(i, 'xp') if chaState ~= 1 and chaTime ~= nil then if os.time() >= chaTime then amp.deldata(i, 'xp') end end chaState,chaTime = amp.getdata(i, 'mf') if chaState ~= 1 and chaTime ~= nil then if os.time() >= chaTime then amp.deldata(i, 'mf') end end end end -- function to remove states upon death, called by GetExp_MKP (monster kill player) -- and by GetExp_PKP (player kill player) local function ClearAmpOnDeath(dead) local charId = GetCharID(dead) local chaState,chaTime = amp.getdata(charId, 'xp') if chaState ~= 1 then SystemNotice(dead, chaState..'x EXP bonus has vanished...') amp.deldata(charId, 'xp') end chaState,chaTime = amp.getdata(charId, 'mf') if chaState ~= 1 then SystemNotice(dead, chaState..'x LUCK bonus has vanished...') amp.deldata(charId, 'mf') end end -- used function and provided interface amp = { loadtable = CreateDatabase, insert = InsertToAmpDatabase, getdata = GetChaAmpData, add = ampData_addFruit, init = initamp, timer = player_timer, pkp = GetExp_PKP, mkp = GetExp_MKP, deldata = DeleteAmpData, cleandata = CleanAmpData, clear = ClearAmpOnDeath, } amp.init() -- persistency upon updateall? playerampdata = playerampdata or {} -- timer to notify players: -- when exp vanishes -- remaining time left -- todo: do not constantly load serialize file function player_timer(cha) amp.timer(cha) playerampdata[cha] = playerampdata[cha] or {} if playerampdata[cha].xpstate == nil and playerampdata[cha].xptime == nil then playerampdata[cha].xpstate, playerampdata[cha].xptime = amp.getdata(GetCharID(cha), 'xp') end if playerampdata[cha].xpstate ~= 1 and playerampdata[cha].xptime ~= nil then if os.time() >= playerampdata[cha].xptime then local charId = GetCharID(cha) BickerNotice(cha, playerampdata[cha].xpstate..'x EXP bonus has vanished...') amp.deldata(charId, 'xp') playerampdata[cha].xpstate, playerampdata[cha].xptime = nil,nil end local tick = GetChaParam(cha, 1) playerampdata[cha].xpcycle = playerampdata[cha].xpcycle or math.random(120,240) if math.mod(tick, playerampdata[cha].xpcycle) == 0 then playerampdata[cha].xpstate, playerampdata[cha].xptime = amp.getdata(GetCharID(cha), 'xp') if os.time() < playerampdata[cha].xptime then local stateTime = playerampdata[cha].xptime - os.time() BickerNotice(cha, 'Remaining '..playerampdata[cha].xpstate..'x EXP: '..ToClockFormat(stateTime)..'!') playerampdata[cha].xpcycle = math.random(120,240) end end end if playerampdata[cha].mfstate == nil and playerampdata[cha].mftime == nil then playerampdata[cha].mfstate, playerampdata[cha].mftime = amp.getdata(GetCharID(cha), 'mf') end if playerampdata[cha].mfstate ~= 1 and playerampdata[cha].mftime ~= nil then if os.time() >= playerampdata[cha].mftime then local charId = GetCharID(cha) BickerNotice(cha, playerampdata[cha].mfstate..'x DROP bonus has vanished...') amp.deldata(charId, 'mf') playerampdata[cha].mfstate, playerampdata[cha].mftime = nil,nil end local tick = GetChaParam(cha, 1) playerampdata[cha].mfcycle = playerampdata[cha].mfcycle or math.random(120,240) if math.mod(tick, playerampdata[cha].mfcycle) == 0 then playerampdata[cha].mfstate, playerampdata[cha].mftime = amp.getdata(GetCharID(cha), 'mf') if os.time() < playerampdata[cha].mftime then local stateTime = playerampdata[cha].mftime - os.time() BickerNotice(cha, 'Remaining '..playerampdata[cha].mfstate..'x DROP: '..ToClockFormat(stateTime)..'!') playerampdata[cha].mfcycle = math.random(120,240) end end end end -- GetExp_MKP hooks (to clear amp data upon death) function GetExp_MKP(dead, atk) amp.mkp(dead, atk) amp.clear(dead) end -- GetExp_PKP hooks (to clear amp data upon death) function GetExp_PKP(dead, atk) amp.pkp(dead, atk) amp.clear(dead) end local getstatehook = GetChaStateLv -- maybe hook and change param for obtion to serialize? function GetChaStateLv(cha, state) if state == STATE_SBJYGZ then local charId = GetCharID(cha) local chaState,chaTime = amp.getdata(charId, 'xp') if chaState == 2.5 then chaState = 3 end if chaState == 001 then chaState = 0 end return chaState elseif state == STATE_SBBLGZ then local charId = GetCharID(cha) local chaState,chaTime = amp.getdata(charId, 'mf') if chaState == 2.5 then chaState = 3 end if chaState == 001 then chaState = 0 end return chaState else return getstatehook(cha, state) end end -- custom ItemUse_ function that will be called function UseAmpDefault(cha, item) local charId = GetCharID(cha) local t = amp.loadtable(ampData_conf['path'], ampData_conf['db']) -- check if the amp is functional local ampId = GetItemID(item) if ampData_fruit[ampId] == nil then SystemNotice(cha, 'Amplifier has expired. Please use again later...') UseItemFailed(cha) return end -- check if player has a better amp local ampState,ampType = ampData_fruit[ampId].rate,ampData_fruit[ampId].bonus local chaState,chaTime = amp.getdata(charId, ampType) if chaState > ampState then SystemNotice(cha, 'Better fruit in effect. Please use again later...') UseItemFailed(cha) return end -- check if said amp is currently in effect if chaState == ampState then local statetime = chaTime - os.time() BickerNotice(cha, 'Current fruit still in effect for '..ToClockFormat(statetime)..'!') UseItemFailed(cha) return end -- check if player level is in range to use amp local chaLv = Lv(cha) if chaLv > ampData_fruit[ampId].maxLv then SystemNotice(cha, 'Effective only against players lv: '..ampData_fruit[ampId].maxLv..' and below!') UseItemFailed(cha) return end if chaLv < ampData_fruit[ampId].minLv then SystemNotice(cha, 'Only players lv: '..ampData_fruit[ampId].minLv..'+ may use!') UseItemFailed(cha) return end -- add state and time to db (this should be done only on leave_map/leave_game) -- but would require GameServer hex for "GetChaStateTime(stateID) local time = minToSec(ampData_fruit[ampId].min) local statesec = num2hex(os.time() + time) -- hex here amp.insert(charId, ampType, ampState, statesec) BickerNotice(cha, 'Feel the effect of '..GetItemName(ampId)..' for '..ToClockFormat(time)..'!') playerampdata[cha] = playerampdata[cha] or {} playerampdata[cha][ampType..'state'], playerampdata[cha][ampType..'time'] = amp.getdata(charId, ampType) end 1 Quote Share this post Link to post Share on other sites
Rinor 59 Report post Posted August 15, 2018 @KONG I'm having this error: your script: Quote Share this post Link to post Share on other sites
Dan 184 Report post Posted August 15, 2018 Use the one by @Satan I think he released one, with modifications extending with this. Quote Share this post Link to post Share on other sites