local storage = 9756
local mins = 60
local hours = 60 * 60
local days = 24 * 60 * 60
local time = 6 * hours
local timeNow = os.time()
---@ Create by Sarah Wesker | Tested Version: TFS 0.4
---@ list of training dummies.
local dummies = {
[5777] = { skillRate = 1, skillSpeed = 1 },
[5778] = { skillRate = 1, skillSpeed = 1 },
[5787] = { skillRate = 1, skillSpeed = 1 },
[5788] = { skillRate = 1, skillSpeed = 1 }
}
---@ Global training parameters of the system.
local staminaTries = 1 --# on minutes
local skillTries = 5 --# tries by blow
local skillSpent = function() return math.random(425, 575) end --# mana consumed by blow
local slotForUse = CONST_SLOT_AMMO
---@ list of weapons to train.
local weapons = {
[2433] = { shootEffect = CONST_ME_HITAREA, shootDistEffect = CONST_ANI_CAKE, skillType = SKILL_MAGLEVEL }, -- magicLevel
[2414] = { shootEffect = CONST_ME_HITAREA, shootDistEffect = CONST_ANI_SPEAR, skillType = SKILL_DISTANCE }, -- distance
[2446] = { shootEffect = CONST_ME_HITAREA, skillType = SKILL_SWORD }, -- sword
[2443] = { shootEffect = CONST_ME_HITAREA, skillType = SKILL_AXE }, -- axe
[2444] = { shootEffect = CONST_ME_HITAREA, skillType = SKILL_CLUB } -- club
}
---@ EDTE is the global event table to control the system correctly.
if not EDTE then EDTE = {} end
---@ functions to assign or obtain the training status of a player.
function getPlayerExerciseTrain(cid) return EDTE[cid] or false end
function setPlayerExerciseTrain(cid, status) EDTE[cid] = status return status end
---@ local training function.
local function exerciseDummyTrainEvent(params, weapon)
if isPlayer(params.cid) then
local item = getPlayerSlotItem(params.cid, slotForUse)
local playerPosition = getCreaturePosition(params.cid)
if getDistanceBetween(playerPosition, params.currentPos) == 0 and item.itemid == params.itemid then
local weaponCharges = getItemAttribute(item.uid, "charges") or getItemInfo(params.itemid).charges
local reloadMs = getVocationInfo(getPlayerVocation(params.cid)).attackSpeed * params.dummy.skillSpeed
if weaponCharges >= 1 then
doItemSetAttribute(item.uid, "charges", weaponCharges -1)
if weapon.shootDistEffect then doSendDistanceShoot(playerPosition, params.dummyPos, weapon.shootDistEffect) end
if weapon.shootEffect then doSendMagicEffect(params.dummyPos, weapon.shootEffect) end
if weapon.skillType == SKILL_MAGLEVEL then
doPlayerAddManaSpent(params.cid, (skillSpent() * params.dummy.skillRate) * getConfigValue("rateMagic"))
else
doPlayerAddSkillTry(params.cid, weapon.skillType, (skillTries * params.dummy.skillRate) * getConfigValue("rateSkill"))
end
local currentStamina = getPlayerStamina(params.cid)
doPlayerSetStamina(params.cid, currentStamina + staminaTries)
if weaponCharges <= 1 then
exerciseDummyTrainEvent(params, weapon)
else
setPlayerExerciseTrain(params.cid, addEvent(exerciseDummyTrainEvent, reloadMs, params, weapon))
end
return true
else
doRemoveItem(item.uid)
doPlayerSendTextMessage(params.cid, MESSAGE_EVENT_ADVANCE, "Your exercise weapon has expired, therefore your training too.")
end
else
doPlayerSendTextMessage(params.cid, MESSAGE_EVENT_ADVANCE, "You have finished your training.")
end
end
return setPlayerExerciseTrain(params.cid, nil)
end
function onUse(cid, item, fromPos, target, toPos, isHotkey)
if timeNow - getPlayerStorageValue(cid, storage) < 0 then
if getPlayerStorageValue(cid, storage)-timeNow > days then
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You must wait '.. math.ceil(((getPlayerStorageValue(cid, storage)) - timeNow)/days) ..' days to do it again.')
elseif getPlayerStorageValue(cid, storage)-timeNow > hours then
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You must wait '.. math.ceil(((getPlayerStorageValue(cid, storage)) - timeNow)/hours) ..' hours to do it again.')
else
doPlayerSendTextMessage(cid, MESSAGE_INFO_DESCR, 'You must wait '.. math.ceil(((getPlayerStorageValue(cid, storage)) - timeNow)/mins) ..' minutes to do it again.')
end
return true
end
local ammo = getPlayerSlotItem(cid, slotForUse)
if ammo.uid ~= item.uid then
return doPlayerSendCancel(cid, "The weapon must be located in your slot ammunition.")
end
if not target then
return doPlayerSendDefaultCancel(cid, RETURNVALUE_NOTPOSSIBLE)
end
local playerPosition = getCreaturePosition(cid)
if not getTileInfo(playerPosition).protection then
return doPlayerSendCancel(cid, "You can only train in protection zone.")
end
local dummy = dummies[target.itemid]
local weapon = weapons[item.itemid]
if not weapon or not dummy then
return doPlayerSendDefaultCancel(cid, RETURNVALUE_CANNOTUSETHISOBJECT)
end
local dummyPosition = getThingPosition(target.uid)
if getDistanceBetween(playerPosition, dummyPosition) > 1 then
return doPlayerSendDefaultCancel(cid, RETURNVALUE_THEREISNOWAY)
end
if not getPlayerExerciseTrain(cid) then
local params = {}
params.cid = cid
params.currentPos = playerPosition
params.dummyPos = dummyPosition
params.itemid = item.itemid
params.dummy = dummy
exerciseDummyTrainEvent(params, weapon)
doPlayerSendTextMessage(cid, MESSAGE_EVENT_ADVANCE, "You have started training with dummy.")
setPlayerStorageValue(cid, storage, timeNow + time)
else
doPlayerSendCancel(cid, "You can not train")
end
return true
end