mirror of
https://github.com/ErikasKontenis/SabrehavenServer.git
synced 2025-12-10 04:10:45 +01:00
finish guildwar system
This commit is contained in:
@@ -2,96 +2,85 @@ local deathListEnabled = true
|
||||
local maxDeathRecords = 50
|
||||
|
||||
function onDeath(player, corpse, killer, mostDamageKiller, unjustified, mostDamageUnjustified)
|
||||
local playerId = player:getId()
|
||||
local playerId = player:getId()
|
||||
if nextUseStaminaTime[playerId] then
|
||||
nextUseStaminaTime[playerId] = nil
|
||||
end
|
||||
|
||||
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
|
||||
|
||||
-- restart blessings values
|
||||
player:setStorageValue(101,0)
|
||||
player:setStorageValue(102,0)
|
||||
player:setStorageValue(103,0)
|
||||
player:setStorageValue(104,0)
|
||||
player:setStorageValue(105,0)
|
||||
|
||||
if not deathListEnabled then
|
||||
return
|
||||
end
|
||||
player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
|
||||
|
||||
-- restart blessings values
|
||||
player:setStorageValue(101,0)
|
||||
player:setStorageValue(102,0)
|
||||
player:setStorageValue(103,0)
|
||||
player:setStorageValue(104,0)
|
||||
player:setStorageValue(105,0)
|
||||
|
||||
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:getName()
|
||||
else
|
||||
killerName = "field item"
|
||||
end
|
||||
local byPlayer = false
|
||||
local killerName
|
||||
if killer ~= nil then
|
||||
if killer:isPlayer() then
|
||||
byPlayer = true
|
||||
else
|
||||
local master = killer:getMaster()
|
||||
if master and master ~= killer and master:isPlayer() then
|
||||
killer = master
|
||||
byPlayer = true
|
||||
end
|
||||
end
|
||||
killerName = 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:getName()
|
||||
else
|
||||
mostDamageName = "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:getName()
|
||||
else
|
||||
mostDamageName = "field item"
|
||||
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 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 and 1 or 0) .. ", " .. 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
|
||||
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 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
|
||||
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
|
||||
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(playerId, 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.getDataInt(resultId, "id")
|
||||
result.free(resultId)
|
||||
end
|
||||
if not byPlayer then
|
||||
return
|
||||
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
|
||||
local warId = guildwars:isInWar(killer, player)
|
||||
if warId ~= 0 then
|
||||
guildwars:processKill(warId, killer, player)
|
||||
end
|
||||
|
||||
end
|
||||
@@ -48,4 +48,35 @@ end
|
||||
|
||||
if not nextUseStaminaTime then
|
||||
nextUseStaminaTime = {}
|
||||
end
|
||||
|
||||
function isInArray(array, value, isCaseSensitive)
|
||||
local compareLowerCase = false
|
||||
if value ~= nil and type(value) == "string" and not isCaseSensitive then
|
||||
value = string.lower(value)
|
||||
compareLowerCase = true
|
||||
end
|
||||
if array == nil or value == nil then
|
||||
return (array == value), nil
|
||||
end
|
||||
local t = type(array)
|
||||
if t ~= "table" then
|
||||
if compareLowerCase and t == "string" then
|
||||
return (string.lower(array) == string.lower(value)), nil
|
||||
else
|
||||
return (array == value), nil
|
||||
end
|
||||
end
|
||||
for k,v in pairs(array) do
|
||||
local newV
|
||||
if compareLowerCase and type(v) == "string" then
|
||||
newV = string.lower(v)
|
||||
else
|
||||
newV = v
|
||||
end
|
||||
if newV == value then
|
||||
return true, k
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
@@ -9,4 +9,5 @@ dofile('data/lib/core/player.lua')
|
||||
dofile('data/lib/core/position.lua')
|
||||
dofile('data/lib/core/teleport.lua')
|
||||
dofile('data/lib/core/tile.lua')
|
||||
dofile('data/lib/core/vocation.lua')
|
||||
dofile('data/lib/core/vocation.lua')
|
||||
dofile('data/lib/core/guildwars.lua')
|
||||
199
data/lib/core/guildwars.lua
Normal file
199
data/lib/core/guildwars.lua
Normal file
@@ -0,0 +1,199 @@
|
||||
guildwars = {}
|
||||
|
||||
guildwars.__index = guildwars
|
||||
|
||||
function guildwars:isInWar(player1, player2)
|
||||
if not player1:getGuild() or not player2:getGuild() then
|
||||
return 0
|
||||
end
|
||||
|
||||
if player1:getGuild():getId() == 0 or player2:getGuild():getId() == 0 then
|
||||
return 0
|
||||
end
|
||||
|
||||
if player1:getGuild():getId() == player2:getGuild():getId() then
|
||||
return 0
|
||||
end
|
||||
|
||||
return isInWar(player1:getId(), player2:getId())
|
||||
end
|
||||
|
||||
function guildwars:processKill(warId, killer, player)
|
||||
local fragLimit = self:getFragLimit(warId)
|
||||
|
||||
local killerFrags = self:getKills(warId, killer:getGuild():getId()) + 1
|
||||
local deadFrags = self:getKills(warId, player:getGuild():getId())
|
||||
|
||||
local killerMsg = "Opponent " .. player:getName() .. " of the " .. player:getGuild():getName() .. " was killed by " .. killer:getName() .. ". The new score is " .. killerFrags .. ":" .. deadFrags .. " frags (limit " .. fragLimit .. ")."
|
||||
sendGuildChannelMessage(killer:getGuild():getId(), TALKTYPE_CHANNEL_O, killerMsg)
|
||||
|
||||
local deadMsg = "Guild member " .. player:getName() .. " was killed by " .. killer:getName() .. " of the " .. killer:getGuild():getName() .. ". The new score is " .. deadFrags .. ":" .. killerFrags .. " frags (limit " .. fragLimit .. ")."
|
||||
sendGuildChannelMessage(player:getGuild():getId(), TALKTYPE_CHANNEL_O, deadMsg)
|
||||
|
||||
self:insertKill(warId, killer, player)
|
||||
|
||||
if killerFrags >= fragLimit then
|
||||
self:endWar(warId, killer, player, killerFrags)
|
||||
end
|
||||
end
|
||||
|
||||
function guildwars:getFragLimit(warId)
|
||||
local resultId = db.storeQuery("SELECT `frag_limit` FROM `guild_wars` WHERE `id` = " .. warId)
|
||||
if resultId ~= false then
|
||||
local frag_limit = result.getDataInt(resultId, "frag_limit")
|
||||
result.free(resultId)
|
||||
return frag_limit
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function guildwars:getBounty(warId)
|
||||
local resultId = db.storeQuery("SELECT `bounty` FROM `guild_wars` WHERE `id` = " .. warId)
|
||||
if resultId ~= false then
|
||||
local bounty = result.getDataInt(resultId, "bounty")
|
||||
result.free(resultId)
|
||||
return bounty
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function guildwars:getKills(warId, guildId)
|
||||
local resultId = db.storeQuery("SELECT COUNT(*) as frags FROM `guildwar_kills` WHERE `warid` = " .. warId .. " and `killerguild` = " .. guildId)
|
||||
if resultId ~= false then
|
||||
local frags = result.getDataInt(resultId, "frags")
|
||||
result.free(resultId)
|
||||
return frags
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function guildwars:insertKill(warId, killer, target)
|
||||
db.asyncQuery("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `warid`, `time`) VALUES (" .. db.escapeString(killer:getName()) .. ", " .. db.escapeString(target:getName()) .. ", " .. killer:getGuild():getId() .. ", " .. target:getGuild():getId() .. ", " .. warId .. ", " .. os.time() .. ")")
|
||||
end
|
||||
|
||||
function guildwars:endWar(warId, killer, player, frags)
|
||||
local winGuildInternalMessage = "Congratulations! You have won the war against " .. player:getGuild():getName() .. " with " .. frags .. " frags."
|
||||
sendGuildChannelMessage(killer:getGuild():getId(), TALKTYPE_CHANNEL_O, winGuildInternalMessage)
|
||||
|
||||
local loseGuildInternalMessage = "You have lost the war against " .. killer:getGuild():getName() .. ". They have reached the limit of " .. frags .. " frags."
|
||||
sendGuildChannelMessage(player:getGuild():getId(), TALKTYPE_CHANNEL_O, loseGuildInternalMessage)
|
||||
|
||||
broadcastMessage(killer:getGuild():getName() .. " have won the war against " .. player:getGuild():getName() .. " with " .. frags .. " frags.", MESSAGE_EVENT_ADVANCE)
|
||||
|
||||
self:updateState(warId, 5)
|
||||
|
||||
self:setWarEmblem(killer:getGuild(), player:getGuild())
|
||||
|
||||
local bounty = self:getBounty(warId)
|
||||
if bounty > 0 then
|
||||
killer:getGuild():increaseBankBalance(bounty * 2)
|
||||
end
|
||||
end
|
||||
|
||||
function guildwars:setWarEmblem(guild1, guild2)
|
||||
guild1:setGuildWarEmblem(guild2)
|
||||
end
|
||||
|
||||
function guildwars:updateState(warId, status)
|
||||
db.query("UPDATE `guild_wars` SET `status` = " .. status .. " WHERE `id` = " .. warId)
|
||||
end
|
||||
|
||||
function guildwars:getPendingInvitation(guild1, guild2)
|
||||
local resultId = db.storeQuery("SELECT `id`, `bounty` FROM `guild_wars` WHERE `guild1` = " .. guild1 .. " AND `guild2` = " .. guild2 .. " AND `status` = 0")
|
||||
|
||||
if resultId then
|
||||
local id = result.getDataInt(resultId, "id")
|
||||
local bounty = result.getDataInt(resultId, "bounty")
|
||||
result.free(resultId)
|
||||
|
||||
return id, bounty
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function guildwars:startWar(player, warId, guild1, guild2, bounty)
|
||||
if bounty > 0 then
|
||||
local guildBalance = guild1:getBankBalance()
|
||||
if guildBalance < bounty then
|
||||
player:sendCancelMessage("Your guild does not have that much money in the bank account balance to accept this war with the bounty of " .. bounty .. " gold.")
|
||||
return true
|
||||
end
|
||||
|
||||
if not guild1:decreaseBankBalance(bounty) then
|
||||
player:sendCancelMessage("Your guild does not have that much money in the bank account balance to accept this war with the bounty of " .. bounty .. " gold.")
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
self:updateState(warId, 1)
|
||||
|
||||
self:setWarEmblem(guild1, guild2)
|
||||
|
||||
broadcastMessage(guild1:getName() .. " has accepted " .. guild2:getName() .. " invitation to war.", MESSAGE_EVENT_ADVANCE)
|
||||
end
|
||||
|
||||
function guildwars:rejectWar(warId, guild1, guild2, bounty)
|
||||
self:updateState(warId, 2)
|
||||
broadcastMessage(guild1:getName() .. " has rejected " .. guild2:getName() .. " invitation to war.", MESSAGE_EVENT_ADVANCE)
|
||||
|
||||
if bounty > 0 then
|
||||
guild2:increaseBankBalance(bounty)
|
||||
end
|
||||
end
|
||||
|
||||
function guildwars:cancelWar(warId, guild1, guild2, bounty)
|
||||
self:updateState(warId, 3)
|
||||
broadcastMessage(guild1:getName() .. " has canceled invitation to a war with " .. guild2:getName() .. ".", MESSAGE_EVENT_ADVANCE)
|
||||
|
||||
if bounty > 0 then
|
||||
guild1:increaseBankBalance(bounty)
|
||||
end
|
||||
end
|
||||
|
||||
function guildwars:invite(player, guild1, guild2, frags, bounty)
|
||||
local str = ""
|
||||
local tmpQuery = db.storeQuery("SELECT `guild1`, `status` FROM `guild_wars` WHERE `guild1` IN (" .. guild1:getId() .. "," .. guild2:getId() .. ") AND `guild2` IN (" .. guild2:getId() .. "," .. guild1:getId() .. ") AND `status` IN (0, 1)")
|
||||
if tmpQuery then
|
||||
if result.getDataInt(tmpQuery, "status") == 0 then
|
||||
if result.getDataInt(tmpQuery, "guild1") == guild1:getId() then
|
||||
str = "You have already invited " .. guild2:getName() .. " to war."
|
||||
else
|
||||
str = guild2:getName() .. " have already invited you to war."
|
||||
end
|
||||
else
|
||||
str = "You are already on a war with " .. guild2:getName() .. "."
|
||||
end
|
||||
|
||||
result.free(tmpQuery)
|
||||
end
|
||||
|
||||
if str ~= "" then
|
||||
player:sendCancelMessage(str)
|
||||
return true
|
||||
end
|
||||
|
||||
frags = math.max(10, math.min(500, frags))
|
||||
bounty = math.max(0, math.min(10000000, bounty))
|
||||
|
||||
if bounty > 0 then
|
||||
local guildBalance = guild1:getBankBalance()
|
||||
if guildBalance < bounty then
|
||||
player:sendCancelMessage("Your guild does not have that much money in the bank account balance to set this bounty.")
|
||||
return true
|
||||
end
|
||||
|
||||
if not guild1:decreaseBankBalance(bounty) then
|
||||
player:sendCancelMessage("Your guild does not have that much money in the bank account balance to set this bounty.")
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
db.asyncQuery("INSERT INTO `guild_wars` (`guild1`, `guild2`, `frag_limit`, `bounty`) VALUES (" .. guild1:getId() .. ", " .. guild2:getId() .. ", " .. frags .. ", " .. bounty .. ");")
|
||||
|
||||
local message = guild1:getName() .. " has invited " .. guild2:getName() .. " to war for " .. frags .. " frags."
|
||||
if bounty > 0 then
|
||||
message = message .. " The bounty reward is set to " .. bounty .. " gold."
|
||||
end
|
||||
broadcastMessage(message, MESSAGE_EVENT_ADVANCE)
|
||||
end
|
||||
60
data/talkactions/scripts/war.lua
Normal file
60
data/talkactions/scripts/war.lua
Normal file
@@ -0,0 +1,60 @@
|
||||
function onSay(player, words, param)
|
||||
if not player:getGuild() or player:getGuildLevel() < 3 then
|
||||
player:sendCancelMessage("You cannot execute this talkaction.")
|
||||
return true
|
||||
end
|
||||
|
||||
local t = param:split(",")
|
||||
|
||||
if not t[2] then
|
||||
player:sendCancelMessage("Not enough param(s).")
|
||||
return true
|
||||
end
|
||||
|
||||
local enemyGuildName = string.trim(t[2])
|
||||
|
||||
local enemyGuild = Guild(getGuildId(enemyGuildName))
|
||||
if not enemyGuild then
|
||||
player:sendCancelMessage("Guild \"" .. enemyGuildName .. "\" does not exists or nobody is online from the guild.")
|
||||
return true
|
||||
end
|
||||
|
||||
if enemyGuild:getId() == player:getGuild():getId() then
|
||||
player:sendCancelMessage("You cannot perform war action on your own guild.")
|
||||
return true
|
||||
end
|
||||
|
||||
local warCommand = string.trim(t[1])
|
||||
|
||||
if isInArray({"accept", "reject", "cancel"}, warCommand) then
|
||||
local pendingWarId, bounty = 0
|
||||
|
||||
if warCommand == "cancel" then
|
||||
pendingWarId, bounty = guildwars:getPendingInvitation(player:getGuild():getId(), enemyGuild:getId())
|
||||
else
|
||||
pendingWarId, bounty = guildwars:getPendingInvitation(enemyGuild:getId(), player:getGuild():getId())
|
||||
end
|
||||
|
||||
if pendingWarId == 0 then
|
||||
player:sendCancelMessage("Currently there's no pending invitation for a war with " .. enemyGuild:getName() .. ".")
|
||||
return true
|
||||
end
|
||||
|
||||
if warCommand == "reject" then
|
||||
guildwars:rejectWar(pendingWarId, player:getGuild(), enemyGuild, bounty)
|
||||
elseif warCommand == "cancel" then
|
||||
guildwars:cancelWar(pendingWarId, player:getGuild(), enemyGuild, bounty)
|
||||
else
|
||||
guildwars:startWar(player, pendingWarId, player:getGuild(), enemyGuild, bounty)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
if warCommand == "invite" then
|
||||
guildwars:invite(player, player:getGuild(), enemyGuild, tonumber(t[3] and string.trim(t[3]) or 100), tonumber(t[4] and string.trim(t[4]) or 0))
|
||||
return true
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
@@ -57,6 +57,7 @@
|
||||
<talkaction words="!share" script="experienceshare.lua"/>
|
||||
<talkaction words="!shop" script="znoteshop.lua"/>
|
||||
<talkaction words="!physicaldamage" separator=" " script="physical_damage.lua"/>
|
||||
<talkaction words="!war" separator=" " script="war.lua"/>
|
||||
<talkaction words="469" script="469.lua"/>
|
||||
|
||||
<!-- test talkactions -->
|
||||
|
||||
Reference in New Issue
Block a user