Hello, I have a problem with a boss. The script spawns a creature when someone enters the arena area. After you kill the boss, a tile should unlock so you can walk through it. The issue is that, once the boss is killed, the storage doesn’t register that it’s been defeated—it’s really strange. Anyone have an idea how to fix it?

LUA:
-- data/scripts/arena_boss_system.lua
print("[ArenaSystem] arena_boss_system.lua loaded")
local config = {
bossName = "Demon", -- Nazwa bossa (identyczna jak w pliku .xml potwora)
bossSpawnPos = Position(32911, 32408, 9), -- Pozycja spawnu bossa
arenaFromPos = Position(32895, 32392, 9), -- Lewy górny róg areny
arenaToPos = Position(32932, 32431, 9), -- Prawy dolny róg areny
globalStorage = 40001, -- Global Storage dla stanu bossa (1 = aktywny, 0 = brak bossa)
checkInterval = 5, -- Co ile sekund global event sprawdza arenę
minDamagePercent = 3, -- Minimalny procent obrażeń, by otrzymać storage
playerDamageStorage = 41000 -- Storage u gracza, jeśli zadał wystarczająco dmg
}
-- Sprawdza, czy w obszarze są jacyś gracze
local function arePlayersInArea(fromPos, toPos)
print("[ArenaSystem] Checking if players are in area...")
local spectators = Game.getSpectators(
fromPos, -- pozycja startowa
false, -- checkMultiFloor
true, -- checkPlayers
toPos.x - fromPos.x + 1,
toPos.x - fromPos.x + 1,
toPos.y - fromPos.y + 1,
toPos.y - fromPos.y + 1
)
for _, spec in ipairs(spectators) do
if spec:isPlayer() then
print("[ArenaSystem] Found player in area:", spec:getName())
return true
end
end
print("[ArenaSystem] No players in area.")
return false
end
-- Sprawdza, czy boss jest żywy
local function isBossAlive(bossName)
local creature = Creature(bossName)
local alive = (creature ~= nil)
print("[ArenaSystem] isBossAlive?", alive)
return alive
end
-- Usuwa bossa, jeśli istnieje
local function removeBoss(bossName)
print("[ArenaSystem] Trying to remove boss:", bossName)
local creature = Creature(bossName)
if creature then
creature:remove()
print("[ArenaSystem] Boss removed.")
else
print("[ArenaSystem] Boss not found.")
end
-- Po usunięciu bossa na wszelki wypadek ustawiamy globalStorage na 0
Game.setStorageValue(config.globalStorage, 0)
end
-- Tworzy bossa
local function spawnBoss()
print("[ArenaSystem] Attempting to spawn boss:", config.bossName, "at", config.bossSpawnPos)
local boss = Game.createMonster(config.bossName, config.bossSpawnPos, false, true)
if boss then
Game.setStorageValue(config.globalStorage, 1)
print("[ArenaSystem] Boss spawned successfully!")
else
print("[ArenaSystem] Failed to spawn boss. Check monster name or spawn position.")
end
end
-- Funkcja wywoływana przy StepIn na arenę
function onArenaStepIn(player)
print("[ArenaSystem] onArenaStepIn called by:", player:getName())
local storageValue = Game.getStorageValue(config.globalStorage)
print("[ArenaSystem] Current globalStorage value:", storageValue)
-- Jeśli boss nie jest aktywny (≠ 1), to go zrespawnuj
if storageValue ~= 1 then
print("[ArenaSystem] Boss is not active, spawning boss.")
spawnBoss()
else
print("[ArenaSystem] Boss is already active.")
end
return true
end
-- Funkcja wywoływana przy śmierci bossa
function onBossDeath(creature)
print("[ArenaSystem] onBossDeath triggered for:", creature:getName())
-- Najważniejsza poprawka: resetujemy globalStorage do 0
Game.setStorageValue(config.globalStorage, 0)
local damageMap = creature:getDamageMap()
if not damageMap then
print("[ArenaSystem] No damage map found. Possibly TFS version issue or boss not attacked by players.")
return
end
-- Zliczamy łączną liczbę obrażeń
local totalDamage = 0
for _, damage in pairs(damageMap) do
totalDamage = totalDamage + damage
end
print("[ArenaSystem] totalDamage =", totalDamage)
local minDamage = (config.minDamagePercent / 100) * totalDamage
print("[ArenaSystem] minDamage needed =", minDamage)
for attackerId, damage in pairs(damageMap) do
local attacker = Player(attackerId)
if attacker then
print(string.format("[ArenaSystem] Attacker: %s, Damage: %d", attacker:getName(), damage))
if damage >= minDamage then
attacker:setStorageValue(config.playerDamageStorage, 1)
print("[ArenaSystem] ->", attacker:getName(), "dealt enough damage. Storage", config.playerDamageStorage, "set to 1.")
else
print("[ArenaSystem] ->", attacker:getName(), "did NOT deal enough damage.")
end
end
end
end
-- Funkcja wywoływana przez global event co config.checkInterval sek.
function onCheckArena()
print("[ArenaSystem] onCheckArena triggered.")
if isBossAlive(config.bossName) then
if not arePlayersInArea(config.arenaFromPos, config.arenaToPos) then
print("[ArenaSystem] Boss is alive but no players on arena, removing boss.")
removeBoss(config.bossName)
end
else
print("[ArenaSystem] Boss is not alive or not found, nothing to remove.")
end
return true
end
LUA:
function onStepIn(creature, item, position, fromPosition)
if creature:isPlayer() then
onArenaStepIn(creature)
end
return true
end
LUA:
function onDeath(creature, corpse, killer, mostDamageKiller, unjustified)
-- Sprawdzamy nazwę, czy to nasz boss
if creature:getName():lower() == "demon" then
onBossDeath(creature)
end
return true
end
LUA:
local requiredStorage = 41000 -- musi być taki sam, jak w arena_boss_system.lua
function onStepIn(creature, item, position, fromPosition)
if creature:isPlayer() then
local dmgStorage = creature:getStorageValue(requiredStorage)
if dmgStorage ~= 1 then
creature:sendTextMessage(MESSAGE_STATUS_SMALL, "You have not dealt enough damage to the boss to pass.")
creature:teleportTo(fromPosition)
return false
else
-- Opcjonalnie reset storage po przejściu:
-- creature:setStorageValue(requiredStorage, -1)
end
end
return true
end
LUA:
function onThink(interval, lastExecution)
return onCheckArena()
end
