From 963e55eea20aad122df87c684b169cd21ccaeb03 Mon Sep 17 00:00:00 2001 From: Manmadedrummer <140130825+Manmadedrummer@users.noreply.github.com> Date: Sat, 13 Dec 2025 17:31:34 -0500 Subject: [PATCH] Update FighterGuildServer.lua --- AIO/FighterGuildServer.lua | 180 +++++++++++++++++++++++++++++-------- 1 file changed, 141 insertions(+), 39 deletions(-) diff --git a/AIO/FighterGuildServer.lua b/AIO/FighterGuildServer.lua index 8e5e488..1e08393 100644 --- a/AIO/FighterGuildServer.lua +++ b/AIO/FighterGuildServer.lua @@ -93,42 +93,78 @@ local bosses = { {id = 700836, name = "Imonar the Soulhunter", level = 85, points = 75, difficulty = "Challenging"}, } --- Arena coordinates +-- Arena coordinates (using YOUR new location) local mapId = 1 local playerSpawnX, playerSpawnY, playerSpawnZ, playerOrientation = 2172.05, -4789.88, 55, 1.32696 local bossSpawnX, bossSpawnY, bossSpawnZ, bossOrientation = 2176, -4766, 55, 1.3 local rewardX, rewardY, rewardZ, rewardOrientation = 2204.453125, -4794.402344, 64.998360, 1.033404 --- Queue and arena state variables -local arenaOccupied = false -local queue = {} +-- BRAWL SYSTEM INTEGRATION: Queue and timer variables +local queue = {} -- Queue of waiting players +local maxTime = 120000 -- 2 minutes in milliseconds +local timerAura = 707474 -- Timer visual aura +local currentFighter = nil -- Currently fighting player +local currentBoss = nil -- Currently spawned boss +local PlayerDeathEvent = nil -- Event ID for tracking --- Function to add player to the queue -local function AddToQueue(player, bossId) - table.insert(queue, {player = player, bossId = bossId}) - local position = #queue - player:SendBroadcastMessage("Arena is currently occupied. You are #" .. position .. " in the queue for boss ID: " .. bossId) -end - --- Function to start the next player in the queue +-- Function to get the next player in queue local function StartNextInQueue() if #queue > 0 then local nextInQueue = table.remove(queue, 1) FighterGuildHandlers.StartFight(nextInQueue.player, nextInQueue.bossId) + + -- Update queue positions for remaining players + for i, entry in ipairs(queue) do + if entry.player and entry.player:IsInWorld() then + entry.player:SendBroadcastMessage("|TInterface/ICONS/exclam:35:35|t Your place in line is: " .. i) + entry.player:SendAreaTriggerMessage("|TInterface/ICONS/exclam:35:35|t Your place in line is: " .. i) + end + end + else + -- Arena is now free + currentFighter = nil + currentBoss = nil end end --- Modified StartFight function to check for arena status +-- BRAWL SYSTEM: Player took too long (timeout) +local function TookTooLong(eventId, delay, calls, player) + if player and player:IsInWorld() then + player:SendBroadcastMessage("Time's up! You took too long to defeat the boss.") + player:Teleport(mapId, rewardX, rewardY, rewardZ, rewardOrientation) + player:RemoveAura(timerAura) + + -- Clean up boss if still alive + if currentBoss and currentBoss:IsInWorld() then + currentBoss:DespawnOrUnsummon(1000) + end + + -- Move to next player + player:RegisterEvent(StartNextInQueue, 10000, 1) + end +end + +-- Modified StartFight function with queue and timer system function FighterGuildHandlers.StartFight(player, bossId) - if arenaOccupied then - -- Arena is occupied, add player to the queue - AddToQueue(player, bossId) + -- Check if arena is occupied + if currentFighter ~= nil and currentFighter:IsInWorld() then + -- Arena is occupied, add player to queue + table.insert(queue, {player = player, bossId = bossId}) + local position = #queue + player:SendBroadcastMessage("Arena is currently occupied. You are #" .. position .. " in the queue.") + player:SendAreaTriggerMessage("|TInterface/ICONS/exclam:35:35|t Queue Position: " .. position) return end -- Arena is free, start fight immediately + currentFighter = player player:Teleport(mapId, playerSpawnX, playerSpawnY, playerSpawnZ, playerOrientation) - arenaOccupied = true + + -- Apply timer aura + player:AddAura(timerAura, player) + + player:SendBroadcastMessage("|TInterface/ICONS/Exc:35:35|t You're up! Fight begins now!|TInterface/ICONS/Exc:35:35|t") + player:SendAreaTriggerMessage("|TInterface/ICONS/Exc:35:35|t You're up!|TInterface/ICONS/Exc:35:35|t") local bossInfo for _, boss in ipairs(bosses) do @@ -140,60 +176,126 @@ function FighterGuildHandlers.StartFight(player, bossId) -- Spawn the boss at the designated location if bossInfo then - local spawnedBoss = player:SpawnCreature(bossInfo.id, bossSpawnX, bossSpawnY, bossSpawnZ, bossOrientation, 6, 10000) - if spawnedBoss then - spawnedBoss:SetLevel(bossInfo.level or 80) - player:SendBroadcastMessage("Boss spawned successfully: " .. bossInfo.name) + currentBoss = player:SpawnCreature(bossInfo.id, bossSpawnX, bossSpawnY, bossSpawnZ, bossOrientation, 2, maxTime) + if currentBoss then + currentBoss:SetLevel(bossInfo.level or 80) + player:SendBroadcastMessage("Boss spawned: " .. bossInfo.name .. " - You have 2 minutes!") + + -- Register timeout event (2 minutes) + PlayerDeathEvent = player:RegisterEvent(TookTooLong, maxTime, 1) else player:SendBroadcastMessage("Failed to spawn boss. NPC ID: " .. bossInfo.id) + currentFighter = nil + StartNextInQueue() end else player:SendBroadcastMessage("Invalid boss selected.") + currentFighter = nil + StartNextInQueue() end end --- Function to handle boss defeat and reward arena points +-- Function to handle PLAYER death (player lost) +local function OnPlayerDeath(event, creature, victim) + if victim and victim:IsPlayer() and victim == currentFighter then + -- Remove timeout event + if PlayerDeathEvent then + victim:RemoveEventById(PlayerDeathEvent) + PlayerDeathEvent = nil + end + + victim:RemoveAura(timerAura) + victim:SendBroadcastMessage("You were defeated! Better luck next time.") + + -- Despawn boss + if currentBoss and currentBoss:IsInWorld() then + currentBoss:DespawnOrUnsummon(3000) + end + + -- Teleport to reward area (no rewards though) + victim:Teleport(mapId, rewardX, rewardY, rewardZ, rewardOrientation) + + -- Move to next player after delay + victim:RegisterEvent(StartNextInQueue, 10000, 1) + end +end + +-- Function to handle BOSS defeat and reward arena points local function OnBossDefeated(event, creature, killer) - if killer:IsPlayer() then - local player = killer + if killer and killer:IsPlayer() and killer == currentFighter then local bossName = creature:GetName() - -- Find the boss info by its name + -- Find the boss info by its ID local bossInfo for _, boss in ipairs(bosses) do - if boss.name == bossName then + if boss.id == creature:GetEntry() then bossInfo = boss break end end + -- Remove timeout event + if PlayerDeathEvent then + killer:RemoveEventById(PlayerDeathEvent) + PlayerDeathEvent = nil + end + + killer:RemoveAura(timerAura) + -- Teleport the player back to the reward location if bossInfo then - player:Teleport(mapId, rewardX, rewardY, rewardZ, rewardOrientation) - player:SendBroadcastMessage("Teleporting to reward location...") + killer:Teleport(mapId, rewardX, rewardY, rewardZ, rewardOrientation) -- Announce the winner - creature:SendUnitYell("And our winner is " .. player:GetName() .. "! They have beaten " .. bossName .. ". Look at all that carnage!", 0) + creature:SendUnitYell("And our winner is " .. killer:GetName() .. "! They have beaten " .. bossName .. ". Look at all that carnage!", 0) -- Award arena points local points = bossInfo.points or 0 - player:ModifyArenaPoints(points) - player:SendBroadcastMessage("You earned " .. points .. " Arena Points for defeating " .. bossName .. "!") + killer:ModifyArenaPoints(points) + killer:SendBroadcastMessage("You earned " .. points .. " Arena Points for defeating " .. bossName .. "!") else - player:SendBroadcastMessage("Could not find boss information after defeat.") + killer:SendBroadcastMessage("Could not find boss information after defeat.") end - -- Free the arena and advance the queue after delay - arenaOccupied = false - CreateLuaEvent(StartNextInQueue, 15000, 1) -- 15-second delay before the next player + -- Move to next player after delay + killer:RegisterEvent(StartNextInQueue, 15000, 1) end end --- Register the death event for all bosses -for _, boss in ipairs(bosses) do - RegisterCreatureEvent(boss.id, 4, OnBossDefeated) +-- Function to handle player logout/disconnect during fight +local function OnPlayerLogout(event, player) + if player == currentFighter then + if PlayerDeathEvent then + player:RemoveEventById(PlayerDeathEvent) + PlayerDeathEvent = nil + end + + -- Clean up boss + if currentBoss and currentBoss:IsInWorld() then + currentBoss:DespawnOrUnsummon(1000) + end + + -- Update character position in database to prevent getting stuck + local guid = tostring(player:GetGUID()) + CharDBQuery("UPDATE `characters` SET `position_x` = (" .. rewardX .. ") WHERE `guid` = " .. guid .. ";") + CharDBQuery("UPDATE `characters` SET `position_y` = (" .. rewardY .. ") WHERE `guid` = " .. guid .. ";") + CharDBQuery("UPDATE `characters` SET `position_z` = (" .. rewardZ .. ") WHERE `guid` = " .. guid .. ";") + CharDBQuery("UPDATE `characters` SET `map` = (" .. mapId .. ") WHERE `guid` = " .. guid .. ";") + + -- Start next player + CreateLuaEvent(StartNextInQueue, 5000, 1) + end end +-- Register death events for all bosses +for _, boss in ipairs(bosses) do + RegisterCreatureEvent(boss.id, 4, OnBossDefeated) -- Boss death + RegisterCreatureEvent(boss.id, 3, OnPlayerDeath) -- Player death by boss +end + +-- Register player logout event +RegisterPlayerEvent(4, OnPlayerLogout) + -- NPC Interaction Logic: Show the AIO Boss Selection Frame local function ArenaMaster_OnGossipHello(event, player, creature) AIO.Handle(player, "FighterGuildClient", "ShowBossSelectionFrame") @@ -201,4 +303,4 @@ local function ArenaMaster_OnGossipHello(event, player, creature) end -- Register the NPC gossip event (NPC ID: 18268) -RegisterCreatureGossipEvent(18268, 1, ArenaMaster_OnGossipHello) +RegisterCreatureGossipEvent(18268, 1, ArenaMaster_OnGossipHello) \ No newline at end of file