From a063650aed7a4f89dc0d4d8bd64835b3e5573b81 Mon Sep 17 00:00:00 2001 From: Marco Date: Wed, 13 Nov 2024 13:53:48 -0300 Subject: [PATCH] refactor: split player death event handler into smaller functions --- .../scripts/creaturescripts/player_death.lua | 114 ----------- .../creaturescripts/others/player_death.lua | 146 -------------- .../creaturescripts_player_death.lua | 9 + ...ssing_login.lua => adventure_blessing.lua} | 0 data/scripts/creaturescripts/player/death.lua | 179 ++++++++++++++++++ 5 files changed, 188 insertions(+), 260 deletions(-) delete mode 100644 data-canary/scripts/creaturescripts/player_death.lua delete mode 100644 data-otservbr-global/scripts/creaturescripts/others/player_death.lua create mode 100644 data-otservbr-global/scripts/quests/svargrond_arena/creaturescripts_player_death.lua rename data/scripts/creaturescripts/player/{adventure_blessing_login.lua => adventure_blessing.lua} (100%) create mode 100644 data/scripts/creaturescripts/player/death.lua diff --git a/data-canary/scripts/creaturescripts/player_death.lua b/data-canary/scripts/creaturescripts/player_death.lua deleted file mode 100644 index c30e2e98d99..00000000000 --- a/data-canary/scripts/creaturescripts/player_death.lua +++ /dev/null @@ -1,114 +0,0 @@ -local playerDeath = CreatureEvent("PlayerDeath") - -local deathListEnabled = true -local maxDeathRecords = 5 - -function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) - if not deathListEnabled then - return - end - - local byPlayer = 0 - local killerName - if killer then - if killer:isPlayer() then - byPlayer = 1 - else - local master = killer:getMaster() - if master and master ~= killer and master:isPlayer() then - killer = master - byPlayer = 1 - end - end - killerName = killer:getName() - else - killerName = "field item" - end - - local byPlayerMostDamage = 0 - local mostDamageKillerName - if mostDamageKiller then - if mostDamageKiller:isPlayer() then - byPlayerMostDamage = 1 - else - local master = mostDamageKiller:getMaster() - if master and master ~= mostDamageKiller and master:isPlayer() then - mostDamageKiller = master - byPlayerMostDamage = 1 - end - end - mostDamageName = mostDamageKiller:getName() - else - mostDamageName = "field item" - end - - player:takeScreenshot(byPlayer and SCREENSHOT_TYPE_DEATHPVP or SCREENSHOT_TYPE_DEATHPVE) - - if mostDamageKiller and mostDamageKiller:isPlayer() and killer ~= mostDamageKiller then - mostDamageKiller:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) - end - - local playerGuid = player:getGuid() - db.query( - "INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" - .. playerGuid - .. ", " - .. os.time() - .. ", " - .. player:getLevel() - .. ", " - .. db.escapeString(killerName) - .. ", " - .. byPlayer - .. ", " - .. db.escapeString(mostDamageName) - .. ", " - .. byPlayerMostDamage - .. ", " - .. (unjustified and 1 or 0) - .. ", " - .. (mostDamageUnjustified and 1 or 0) - .. ")" - ) - local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid) - - local deathRecords = 0 - local tmpResultId = resultId - while tmpResultId ~= false do - tmpResultId = Result.next(resultId) - deathRecords = deathRecords + 1 - end - - if resultId ~= false then - Result.free(resultId) - end - - local limit = deathRecords - maxDeathRecords - if limit > 0 then - db.asyncQuery("DELETE FROM `player_deaths` WHERE `player_id` = " .. playerGuid .. " ORDER BY `time` LIMIT " .. limit) - end - - if byPlayer == 1 then - killer:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) - local targetGuild = player:getGuild() - targetGuild = targetGuild and targetGuild:getId() or 0 - if targetGuild ~= 0 then - local killerGuild = killer:getGuild() - killerGuild = killerGuild and killerGuild:getId() or 0 - if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(player:getId(), killer:getId()) then - local warId = false - resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND ((`guild1` = " .. killerGuild .. " AND `guild2` = " .. targetGuild .. ") OR (`guild1` = " .. targetGuild .. " AND `guild2` = " .. killerGuild .. "))") - if resultId ~= false then - warId = Result.getNumber(resultId, "id") - Result.free(resultId) - end - - if warId ~= false then - db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(player:getName()) .. ", " .. killerGuild .. ", " .. targetGuild .. ", " .. os.time() .. ", " .. warId .. ")") - end - end - end - end -end - -playerDeath:register() diff --git a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua b/data-otservbr-global/scripts/creaturescripts/others/player_death.lua deleted file mode 100644 index f3a84454cfd..00000000000 --- a/data-otservbr-global/scripts/creaturescripts/others/player_death.lua +++ /dev/null @@ -1,146 +0,0 @@ -local deathListEnabled = true - -local playerDeath = CreatureEvent("PlayerDeath") -function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) - if player:getStorageValue(Storage.Quest.U8_0.BarbarianArena.PitDoor) > 0 then - player:setStorageValue(Storage.Quest.U8_0.BarbarianArena.PitDoor, 0) - end - - if not deathListEnabled then - return - end - - local byPlayer = 0 - local killerName - if killer ~= nil then - if killer:isPlayer() then - byPlayer = 1 - else - local master = killer:getMaster() - if master and master ~= killer and master:isPlayer() then - killer = master - byPlayer = 1 - end - end - killerName = killer:isMonster() and killer:getType():getNameDescription() or killer:getName() - else - killerName = "field item" - end - - local byPlayerMostDamage = 0 - local mostDamageKillerName - if mostDamageKiller ~= nil then - if mostDamageKiller:isPlayer() then - byPlayerMostDamage = 1 - else - local master = mostDamageKiller:getMaster() - if master and master ~= mostDamageKiller and master:isPlayer() then - mostDamageKiller = master - byPlayerMostDamage = 1 - end - end - mostDamageName = mostDamageKiller:isMonster() and mostDamageKiller:getType():getNameDescription() or mostDamageKiller:getName() - else - mostDamageName = "field item" - end - - player:takeScreenshot(byPlayer and SCREENSHOT_TYPE_DEATHPVP or SCREENSHOT_TYPE_DEATHPVE) - - if mostDamageKiller and mostDamageKiller:isPlayer() then - mostDamageKiller:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) - end - - local playerGuid = player:getGuid() - db.query( - "INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (" - .. playerGuid - .. ", " - .. os.time() - .. ", " - .. player:getLevel() - .. ", " - .. db.escapeString(killerName) - .. ", " - .. byPlayer - .. ", " - .. db.escapeString(mostDamageName) - .. ", " - .. byPlayerMostDamage - .. ", " - .. (unjustified and 1 or 0) - .. ", " - .. (mostDamageUnjustified and 1 or 0) - .. ")" - ) - local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid) - -- Start Webhook Player Death - Webhook.sendMessage(":skull_crossbones: " .. player:getMarkdownLink() .. " has died. Killed at level _" .. player:getLevel() .. "_ by **" .. killerName .. "**.", announcementChannels["player-kills"]) - -- End Webhook Player Death - - local deathRecords = 0 - local tmpResultId = resultId - while tmpResultId ~= false do - tmpResultId = Result.next(resultId) - deathRecords = deathRecords + 1 - end - - if resultId ~= false then - Result.free(resultId) - end - - if byPlayer == 1 then - killer:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) - local targetGuild = player:getGuild() - local targetGuildId = targetGuild and targetGuild:getId() or 0 - if targetGuildId ~= 0 then - local killerGuild = killer:getGuild() - local killerGuildId = killerGuild and killerGuild:getId() or 0 - if killerGuildId ~= 0 and targetGuildId ~= killerGuildId and isInWar(player:getId(), killer:getId()) then - local warId = false - resultId = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND \z - ((`guild1` = " .. killerGuildId .. " AND `guild2` = " .. targetGuildId .. ") OR \z - (`guild1` = " .. targetGuildId .. " AND `guild2` = " .. killerGuildId .. "))") - if resultId then - warId = Result.getNumber(resultId, "id") - Result.free(resultId) - end - - if warId then - local playerName = player:getName() - db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) \z - VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(playerName) .. ", " .. killerGuildId .. ", \z - " .. targetGuildId .. ", " .. os.time() .. ", " .. warId .. ")") - - resultId = db.storeQuery("SELECT `guild_wars`.`id`, `guild_wars`.`frags_limit`, (SELECT COUNT(1) FROM `guildwar_kills` \z - WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild1`) AS guild1_kills, \z - (SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild2`) AS guild2_kills \z - FROM `guild_wars` WHERE (`guild1` = " .. killerGuildId .. " OR `guild2` = " .. killerGuildId .. ") AND `status` = 1 AND `id` = " .. warId) - - if resultId then - local guild1_kills = Result.getNumber(resultId, "guild1_kills") - local guild2_kills = Result.getNumber(resultId, "guild2_kills") - local frags_limit = Result.getNumber(resultId, "frags_limit") - Result.free(resultId) - - local members = killerGuild:getMembersOnline() - for i = 1, #members do - members[i]:sendChannelMessage(members[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1_kills, guild2_kills, killerGuild:getName(), frags_limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD) - end - - local enemyMembers = targetGuild:getMembersOnline() - for i = 1, #enemyMembers do - enemyMembers[i]:sendChannelMessage(enemyMembers[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1_kills, guild2_kills, killerGuild:getName(), frags_limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD) - end - - if guild1_kills >= frags_limit or guild2_kills >= frags_limit then - db.query("UPDATE `guild_wars` SET `status` = 4, `ended` = " .. os.time() .. " WHERE `status` = 1 AND `id` = " .. warId) - Game.broadcastMessage(string.format("%s has just won the war against %s.", killerGuild:getName(), targetGuild:getName())) - end - end - end - end - end - end -end - -playerDeath:register() diff --git a/data-otservbr-global/scripts/quests/svargrond_arena/creaturescripts_player_death.lua b/data-otservbr-global/scripts/quests/svargrond_arena/creaturescripts_player_death.lua new file mode 100644 index 00000000000..e1ba265090a --- /dev/null +++ b/data-otservbr-global/scripts/quests/svargrond_arena/creaturescripts_player_death.lua @@ -0,0 +1,9 @@ +local svargrondArenaPlayerDeath = CreatureEvent("SvargrondArenaPlayerDeath") + +function svargrondArenaPlayerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + if player:getStorageValue(Storage.Quest.U8_0.BarbarianArena.PitDoor) > 0 then + player:setStorageValue(Storage.Quest.U8_0.BarbarianArena.PitDoor, 0) + end +end + +svargrondArenaPlayerDeath:register() diff --git a/data/scripts/creaturescripts/player/adventure_blessing_login.lua b/data/scripts/creaturescripts/player/adventure_blessing.lua similarity index 100% rename from data/scripts/creaturescripts/player/adventure_blessing_login.lua rename to data/scripts/creaturescripts/player/adventure_blessing.lua diff --git a/data/scripts/creaturescripts/player/death.lua b/data/scripts/creaturescripts/player/death.lua new file mode 100644 index 00000000000..ca1fccc7f7e --- /dev/null +++ b/data/scripts/creaturescripts/player/death.lua @@ -0,0 +1,179 @@ +local deathListEnabled = true + +local function getKillerInfo(killer) + local byPlayer = 0 + local killerName + + if killer ~= nil then + if killer:isPlayer() then + byPlayer = 1 + else + local master = killer:getMaster() + if master and master ~= killer and master:isPlayer() then + killer = master + byPlayer = 1 + end + end + + killerName = killer:isMonster() and killer:getType():getNameDescription() or killer:getName() + else + killerName = "field item" + end + return killerName, byPlayer +end + +local function getMostDamageInfo(mostDamageKiller) + local byPlayerMostDamage = 0 + local mostDamageName + + if mostDamageKiller ~= nil then + if mostDamageKiller:isPlayer() then + byPlayerMostDamage = 1 + else + local master = mostDamageKiller:getMaster() + if master and master ~= mostDamageKiller and master:isPlayer() then + mostDamageKiller = master + byPlayerMostDamage = 1 + end + end + + mostDamageName = mostDamageKiller:isMonster() and mostDamageKiller:getType():getNameDescription() or mostDamageKiller:getName() + else + mostDamageName = "field item" + end + return mostDamageName, byPlayerMostDamage +end + +local function saveDeathRecord(playerGuid, player, killerName, byPlayer, mostDamageName, byPlayerMostDamage, unjustified, mostDamageUnjustified) + local query = string.format( + "INSERT INTO `player_deaths` (`player_id`, `time`, `level`, `killed_by`, `is_player`, `mostdamage_by`, `mostdamage_is_player`, `unjustified`, `mostdamage_unjustified`) VALUES (%d, %d, %d, '%s', %d, '%s', %d, %d, %d)", + playerGuid, + os.time(), + player:getLevel(), + db.escapeString(killerName), + byPlayer, + db.escapeString(mostDamageName), + byPlayerMostDamage, + unjustified and 1 or 0, + mostDamageUnjustified and 1 or 0 + ) + db.query(query) +end + +local function handleGuildWar(player, killer, mostDamageKiller, killerName, mostDamageName) + local deathRecords = getDeathRecords(player:getGuid()) + + if deathRecords > 0 then + local targetGuildId = player:getGuild() and player:getGuild():getId() or 0 + local killerGuildId = killer:getGuild() and killer:getGuild():getId() or 0 + + if targetGuildId ~= 0 and killerGuildId ~= 0 and targetGuildId ~= killerGuildId then + local warId = checkForGuildWar(targetGuildId, killerGuildId) + if warId then + recordGuildWarKill(killer, player, killerGuildId, targetGuildId, warId) + checkAndUpdateGuildWarScore(warId, targetGuildId, killerGuildId, player:getName(), killerName, mostDamageName) + end + end + end +end + +local function getDeathRecords(playerGuid) + local resultId = db.storeQuery("SELECT `player_id` FROM `player_deaths` WHERE `player_id` = " .. playerGuid) + local deathRecords = 0 + local tmpResultId = resultId + while tmpResultId ~= false do + tmpResultId = Result.next(resultId) + deathRecords = deathRecords + 1 + end + + if resultId ~= false then + Result.free(resultId) + end + return deathRecords +end + +local function checkForGuildWar(targetGuildId, killerGuildId) + local resultId = db.storeQuery(string.format("SELECT `id` FROM `guild_wars` WHERE `status` = 1 AND ((`guild1` = %d AND `guild2` = %d) OR (`guild1` = %d AND `guild2` = %d))", killerGuildId, targetGuildId, targetGuildId, killerGuildId)) + local warId = false + if resultId then + warId = Result.getNumber(resultId, "id") + Result.free(resultId) + end + return warId +end + +local function recordGuildWarKill(killer, player, killerGuildId, targetGuildId, warId) + local playerName = player:getName() + db.asyncQuery(string.format("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) VALUES ('%s', '%s', %d, %d, %d, %d)", db.escapeString(killer:getName()), db.escapeString(playerName), killerGuildId, targetGuildId, os.time(), warId)) +end + +local function checkAndUpdateGuildWarScore(warId, targetGuildId, killerGuildId, playerName, killerName, mostDamageName) + local resultId = db.storeQuery( + string.format( + "SELECT `guild_wars`.`id`, `guild_wars`.`frags_limit`, " + .. "(SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild1`) AS guild1_kills, " + .. "(SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild2`) AS guild2_kills " + .. "FROM `guild_wars` WHERE (`guild1` = %d OR `guild2` = %d) AND `status` = 1 AND `id` = %d", + killerGuildId, + targetGuildId, + warId + ) + ) + + if resultId then + local guild1Kills = Result.getNumber(resultId, "guild1_kills") + local guild2Kills = Result.getNumber(resultId, "guild2_kills") + local fragsLimit = Result.getNumber(resultId, "frags_limit") + Result.free(resultId) + + local killerGuild = killer:getGuild() + local targetGuild = player:getGuild() + + updateGuildWarScore(killerGuild, targetGuild, playerName, killerName, guild1Kills, guild2Kills, fragsLimit) + endGuildWarIfLimitReached(guild1Kills, guild2Kills, fragsLimit, warId, killerGuild, targetGuild) + end +end + +local function updateGuildWarScore(killerGuild, targetGuild, playerName, killerName, guild1Kills, guild2Kills, fragsLimit) + local members = killerGuild:getMembersOnline() + for i = 1, #members do + members[i]:sendChannelMessage(members[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1Kills, guild2Kills, killerGuild:getName(), fragsLimit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD) + end + + local enemyMembers = targetGuild:getMembersOnline() + for i = 1, #enemyMembers do + enemyMembers[i]:sendChannelMessage(enemyMembers[i], string.format("%s was killed by %s. The new score is: %s %d:%d %s (frags limit: %d)", playerName, killerName, targetGuild:getName(), guild1Kills, guild2Kills, killerGuild:getName(), fragsLimit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD) + end +end + +local function endGuildWarIfLimitReached(guild1Kills, guild2Kills, fragsLimit, warId, killerGuild, targetGuild) + if guild1Kills >= fragsLimit or guild2Kills >= fragsLimit then + db.query(string.format("UPDATE `guild_wars` SET `status` = 4, `ended` = %d WHERE `status` = 1 AND `id` = %d", os.time(), warId)) + Game.broadcastMessage(string.format("%s has just won the war against %s.", killerGuild:getName(), targetGuild:getName())) + end +end + +local playerDeath = CreatureEvent("PlayerDeath") + +function playerDeath.onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified) + if not deathListEnabled then + return + end + + local killerName, byPlayer = getKillerInfo(killer) + local mostDamageName, byPlayerMostDamage = getMostDamageInfo(mostDamageKiller) + + player:takeScreenshot(byPlayer and SCREENSHOT_TYPE_DEATHPVP or SCREENSHOT_TYPE_DEATHPVE) + + if mostDamageKiller and mostDamageKiller:isPlayer() then + mostDamageKiller:takeScreenshot(SCREENSHOT_TYPE_PLAYERKILL) + end + + local playerGuid = player:getGuid() + saveDeathRecord(playerGuid, player, killerName, byPlayer, mostDamageName, byPlayerMostDamage, unjustified, mostDamageUnjustified) + + Webhook.sendMessage(":skull_crossbones: " .. player:getMarkdownLink() .. " has died. Killed at level _" .. player:getLevel() .. "_ by **" .. killerName .. "**.", announcementChannels["player-kills"]) + handleGuildWar(player, killer, mostDamageKiller, killerName, mostDamageName) +end + +playerDeath:register()