local config = {
summonItemId = 8300, -- ID of the item that summons the monster
monsterName = "Training Dummy", -- Name of the monster to be summoned
summonStorage = 7550, -- Storage used to control if the monster has been summoned
summonDuration = 36000, -- Summon duration in seconds (10 hours)
cooldownTime = 10, -- Cooldown time in seconds
allowSummonInPZ = false -- Set to true to allow summon in PZ, false to restrict it
}
local function removeDummyIfCreaturesNearby(summonCreatureId, playerGuid, item)
local summonCreature = Creature(summonCreatureId)
if not summonCreature then return end
local spectators = Game.getSpectators(summonCreature:getPosition(), false, false, 5, 5, 5, 5)
for _, spectator in ipairs(spectators) do
if spectator:isMonster() and spectator:getName() ~= config.monsterName then
summonCreature:remove()
local player = Player(playerGuid)
if player then
local summonExpiry = item:getCustomAttribute("summonExpiry")
local remainingTime = summonExpiry - os.time()
item:setCustomAttribute("remainingSummonTime", remainingTime)
player:setStorageValue(config.summonStorage, nil)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Your Training Dummy was removed because a monster approached.")
end
return
end
if spectator:isPlayer() then
local skull = spectator:getSkull()
if skull == SKULL_WHITE or skull == SKULL_RED or skull == SKULL_BLACK then
summonCreature:remove()
local player = Player(playerGuid)
if player then
local summonExpiry = item:getCustomAttribute("summonExpiry")
local remainingTime = summonExpiry - os.time()
item:setCustomAttribute("remainingSummonTime", remainingTime)
player:setStorageValue(config.summonStorage, nil)
player:sendTextMessage(MESSAGE_INFO_DESCR, "Your Training Dummy was removed because a player with a skull was nearby.")
end
return
end
end
end
addEvent(function() removeDummyIfCreaturesNearby(summonCreatureId, playerGuid, item) end, 1000)
end
local function removeDummy(player, item)
local summonCreatureId = player:getStorageValue(config.summonStorage)
local summonCreature = Creature(summonCreatureId)
if summonCreature then
local summonExpiry = item:getCustomAttribute("summonExpiry")
local remainingTime = summonExpiry - os.time()
if remainingTime > 0 then
item:setCustomAttribute("remainingSummonTime", remainingTime)
end
summonCreature:remove()
player:sendTextMessage(MESSAGE_INFO_DESCR, "The Training Dummy has been removed.")
end
end
local function createSummon(player, item, remainingTime)
local creature = Game.createMonster(config.monsterName, player:getPosition())
if creature then
local summonCreatureId = creature:getId()
player:setStorageValue(config.summonStorage, summonCreatureId)
player:getPosition():sendMagicEffect(CONST_ME_MAGIC_BLUE)
local playerGuid = player:getGuid()
local summonExpirationTime
if remainingTime then
summonExpirationTime = os.time() + remainingTime
else
summonExpirationTime = os.time() + config.summonDuration
end
item:setCustomAttribute("summonExpiry", summonExpirationTime)
addEvent(function()
local summonCreature = Creature(player:getStorageValue(config.summonStorage))
if summonCreature then
summonCreature:remove()
local player = Player(playerGuid)
if player then
player:setStorageValue(config.summonStorage, nil)
player:removeItem(config.summonItemId, 1)
end
item:removeCustomAttribute("summonExpiry")
end
end, (summonExpirationTime - os.time()) * 1000)
addEvent(function() removeDummyIfCreaturesNearby(summonCreatureId, playerGuid, item) end, 1000)
player:setStorageValue("cooldownSummon", os.time() + config.cooldownTime)
end
end
local function formatTime(seconds)
local hours = math.floor(seconds / 3600)
local minutes = math.floor((seconds % 3600) / 60)
local remainingSeconds = seconds % 60
return string.format("%02d:%02d:%02d", hours, minutes, remainingSeconds)
end
local Dummy = Action()
function Dummy.onUse(player, item, fromPosition, target, toPosition, isHotkey)
local tile = Tile(player:getPosition())
local skull = player:getSkull()
if skull == SKULL_WHITE or skull == SKULL_RED or skull == SKULL_BLACK then
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You cannot summon the Training Dummy while having a skull.")
return true
end
if not config.allowSummonInPZ and tile and tile:hasFlag(TILESTATE_PROTECTIONZONE) then
player:sendCancelMessage("You cannot use this item in a protection zone.")
return true
end
if player:isPzLocked() then
player:sendCancelMessage("You cannot use this item while PZ locked.")
return true
end
local summonCreatureId = player:getStorageValue(config.summonStorage)
local cooldownTime = player:getStorageValue("cooldownSummon")
local currentTime = os.time()
if cooldownTime > currentTime then
local remainingTime = cooldownTime - currentTime
player:sendTextMessage(MESSAGE_INFO_DESCR, "You need to wait " .. formatTime(remainingTime) .. " before summoning the Training Dummy again.")
return true
end
local summonCreature = Creature(summonCreatureId)
if summonCreature then
removeDummy(player, item)
return true
end
local remainingTime = item:getCustomAttribute("remainingSummonTime")
if remainingTime and remainingTime > 0 then
createSummon(player, item, remainingTime)
else
createSummon(player, item)
end
item:removeCustomAttribute("remainingSummonTime")
return true
end
Dummy:id(config.summonItemId)
Dummy:register()
local DummyLook = EventCallback
function DummyLook.onLook(player, thing, position, distance, description)
if thing:isItem() and thing:getId() == config.summonItemId then
local expiryTime = thing:getCustomAttribute("summonExpiry")
local remainingTime = thing:getCustomAttribute("remainingSummonTime")
if remainingTime and remainingTime > 0 then
description = description .. "\nTraining Dummy remaining time: " .. formatTime(remainingTime)
elseif expiryTime and expiryTime > os.time() then
local totalTime = expiryTime - os.time()
description = description .. "\nTraining Dummy remaining time: " .. formatTime(totalTime)
else
thing:removeCustomAttribute("summonExpiry")
end
end
return description
end
DummyLook:register(2)
local creatureevent = CreatureEvent("onLogoutDummy")
function creatureevent.onLogout(player)
local summonCreatureId = player:getStorageValue(config.summonStorage)
if summonCreatureId > 0 then
local summonCreature = Creature(summonCreatureId)
if summonCreature then
local item = player:getItemById(config.summonItemId)
if item then
local summonExpiry = item:getCustomAttribute("summonExpiry")
if summonExpiry then
local remainingTime = summonExpiry - os.time()
if remainingTime > 0 then
item:setCustomAttribute("remainingSummonTime", remainingTime)
end
end
end
summonCreature:remove()
player:setStorageValue(config.summonStorage, nil)
end
end
return true
end
creatureevent:register()