• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

[TFS1.3][TalkActions] War system /war invite, /war accept

biaggio12

Member
Joined
Aug 22, 2009
Messages
63
Reaction score
10
Hello today im struggling with talkaction for creating wars on my server. I'm using ZnoteAAC. I did import schema from ZNOTE repository to my existing database encountered some errors while uploading but managed to create table with name znote_guild_wars with this query
SQL:
CREATE TABLE IF NOT EXISTS `znote_guild_wars` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`limit` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
FOREIGN KEY (`id`) REFERENCES `guild_wars` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB

If i understand correctly SQL, that last 2 lines of code are responsible for "duplicating"(more or less duplicating) records from guild_wars table into znote_guild_wars. But its not working here unfortunately.


Here's the code i got so far.


playerdeath.lua
Lua:
local deathListEnabled = true
local maxDeathRecords = 5

local function sendWarStatus(guildId, enemyGuildId, warId, playerName, killerName)
    local guild, enemyGuild = Guild(guildId), Guild(enemyGuildId)
    if not guild or not enemyGuild then
        return
    end

    local resultId = db.storeQuery("SELECT `guild_wars`.`id`, (SELECT `limit` FROM `znote_guild_wars` WHERE `znote_guild_wars`.`id` = `guild_wars`.`id`) AS `limit`, (SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild1`) guild1_kills, (SELECT COUNT(1) FROM `guildwar_kills` WHERE `guildwar_kills`.`warid` = `guild_wars`.`id` AND `guildwar_kills`.`killerguild` = `guild_wars`.`guild2`) guild2_kills FROM `guild_wars` WHERE (`guild1` = " .. guildId .. " OR `guild2` = " .. guildId .. ") 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 limit = result.getNumber(resultId, "limit")
        result.free(resultId)

        local members = guild:getMembersOnline()
        for i = 1, #members do
            members[i]:sendChannelMessage("", string.format("%s was killed by %s. The new score is %d:%d frags (limit: %d)", playerName, killerName, guild1_kills, guild2_kills, limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
        end

        local enemyMembers = enemyGuild:getMembersOnline()
        for i = 1, #enemyMembers do
            enemyMembers[i]:sendChannelMessage("", string.format("%s was killed by %s. The new score is %d:%d frags (limit: %d)", playerName, killerName, guild1_kills, guild2_kills, limit), TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
        end

        if guild1_kills >= limit or guild2_kills >= 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.", guild:getName(), enemyGuild:getName()), MESSAGE_EVENT_ADVANCE)
        end
    end
end

function onDeath(cid, corpse, killer, mostDamage, unjustified, mostDamage_unjustified)
    local player = Player(cid)

    player:sendTextMessage(MESSAGE_EVENT_ADVANCE, "You are dead.")
    if player:getStorageValue(Storage.SvargrondArena.Pit) > 0 then
        player:setStorageValue(Storage.SvargrondArena.Pit, 0)
    end
    if not deathListEnabled then
        return
    end

    local byPlayer = 0
    local killerCreature = Creature(killer)
    if not killerCreature then
        killerName = "field item"
    else
        if killerCreature:isPlayer() then
            byPlayer = 1
        else
            local master = killerCreature:getMaster()
            if master and master ~= killerCreature and master:isPlayer() then
                killerCreature = master
                byPlayer = 1
            end
        end
        killerName = killerCreature:isMonster() and killerCreature:getType():getNameDescription() or killerCreature:getName()
    end

    local byPlayerMostDamage = 0
    if mostDamage == 0 then
        mostDamageName = "field item"
    else
        local mostDamageKiller = Creature(mostDamage)
        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()
    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) .. ", " .. (mostDamage_unjustified 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

    while deathRecords > maxDeathRecords do
        db.query("DELETE FROM `player_deaths` WHERE `player_id` = " .. playerGuid .. " ORDER BY `time` LIMIT 1")
        deathRecords = deathRecords - 1
    end

    if byPlayer == 1 then
        local targetGuild = player:getGuild()
        targetGuild = targetGuild and targetGuild:getId() or 0
        if targetGuild ~= 0 then
            local killerGuild = killerCreature:getGuild()
            killerGuild = killerGuild and killerGuild:getId() or 0
            if killerGuild ~= 0 and targetGuild ~= killerGuild and isInWar(cid, killerCreature) 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
                    local playerName = player:getName()
                    db.query("INSERT INTO `guildwar_kills` (`killer`, `target`, `killerguild`, `targetguild`, `time`, `warid`) VALUES (" .. db.escapeString(killerName) .. ", " .. db.escapeString(playerName) .. ", " .. killerGuild .. ", " .. targetGuild .. ", " .. os.time() .. ", " .. warId .. ")")
                    addEvent(sendWarStatus, 1000, killerGuild, targetGuild, warId, playerName, killerName)
                end
            end
        end
    end
end

war.lua (talkaction script) it's registered for sure
Lua:
function onSay(cid, words, param)

    local player = Player(cid)
    local guild = player:getGuild()
    if(guild == nil) then
            player:sendCancelMessage("You need to be in a guild in order to execute this talkaction.")
            return false
    end

    local guild = getPlayerGuildId(cid)
    if not guild or (player:getGuildLevel() < 3) then
            player:sendCancelMessage("You cannot execute this talkaction.")
            return false
    end

    local t = string.split(param, ",")
    if(not t[2]) then    
            player:sendChannelMessage("", "Not enough param(s).", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
            return false
    end

    local enemy = getGuildId(t[2])
    if(not enemy) then
            player:sendChannelMessage("", "Guild \"" .. t[2] .. "\" does not exists.", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
            return false
    end

    if(enemy == guild) then
            player:sendChannelMessage("", "You cannot perform war action on your own guild.", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
            return false
    end

    local enemyName, tmp = "", db.storeQuery("SELECT `name` FROM `guilds` WHERE `id` = " .. enemy)
    if tmp ~= false then
            enemyName = result.getDataString(tmp, "name")
            result.free(tmp)
    end

    if(isInArray({"accept", "reject", "cancel"}, t[1])) then
            local query = "`guild1` = " .. enemy .. " AND `guild2` = " .. guild
            if(t[1] == "cancel") then
                    query = "`guild1` = " .. guild .. " AND `guild2` = " .. enemy
            end

            tmp = db.storeQuery("SELECT `id`, `started`, `ended`, `payment` FROM `guild_wars` WHERE " .. query .. " AND `status` = 0")
            if(tmp == false) then
                    player:sendChannelMessage("", "Currently there's no pending invitation for a war with " .. enemyName .. ".", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
                    return false
            end

            if(t[1] == "accept") then
                    local _tmp = db.storeQuery("SELECT `balance` FROM `guilds` WHERE `id` = " .. guild)
                    local state = result.getDataInt(_tmp, "balance") < result.getDataInt(tmp, "payment")

                    result.free(_tmp)
                    if(state) then
                            player:sendChannelMessage("", "Your guild balance is too low to accept this invitation.", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
                            return false
                    end

                    db.query("UPDATE `guilds` SET `balance` = `balance` - " .. result.getDataInt(tmp, "payment") .. " WHERE `id` = " .. guild)
            end

            query = "UPDATE `guild_wars` SET "
            local msg = "accepted " .. enemyName .. " invitation to war."
            if(t[1] == "reject") then
                    query = query .. "`ended` = " .. os.time() .. ", `status` = 2"
                    msg = "rejected " .. enemyName .. " invitation to war."
            elseif(t[1] == "cancel") then
                    query = query .. "`ended` = " .. os.time() .. ", `status` = 3"
                    msg = "canceled invitation to a war with " .. enemyName .. "."
            else
                    query = query .. "`started` = " .. os.time() .. ", `ended` = " .. (result.getDataInt(tmp, "ended") > 0 and (os.time() + ((result.getDataInt(tmp, "started") - result.getDataInt(tmp, "ended")) / 86400)) or 0) .. ", `status` = 1"
            end


            query = query .. " WHERE `id` = " .. result.getDataInt(tmp, "id")
            result.free(tmp)
            db.query(query)
            broadcastMessage(getPlayerGuildName(cid) .. " has " .. msg, MESSAGE_EVENT_ADVANCE)
            return false
    end

    if(t[1] == "invite") then
            local str = ""
            tmp = db.storeQuery("SELECT `guild1`, `status` FROM `guild_wars` WHERE `guild1` IN (" .. guild .. "," .. enemy .. ") AND `guild2` IN (" .. enemy .. "," .. guild .. ") AND `status` IN (0, 1)")
    if(tmp ~= false) then
                 
                    if(result.getDataInt(tmp, "status") == 0) then
                            if(result.getDataInt(tmp, "guild1") == guild) then
                                    str = "You have already invited " .. enemyName .. " to war."
                            else
                                    str = enemyName .. " have already invited you to war."
                            end
                    else
                            str = "You are already on a war with " .. enemyName .. "."
                    end

                    result.free(tmp)
            end

            if(str ~= "") then
                    player:sendChannelMessage("", str, TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
                    return false
            end

            local frags = tonumber(t[3])
            if(frags ~= nil) then
                    frags = math.max(10, math.min(1000, frags))
            else
                    frags = 100
            end

            local payment = tonumber(t[4])
            if(payment ~= nil) then
                    payment = math.floor(payment)+1000
                    tmp = db.storeQuery("SELECT `balance` FROM `guilds` WHERE `id` = " .. guild)

                    local state = result.getDataInt(tmp, "balance") < payment
                    result.free(tmp)
                    if(state) then
                            player:sendChannelMessage("", "Your guild balance is too low for such payment.", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
                            return false
                    end

                    db.query("UPDATE `guilds` SET `balance` = `balance` - " .. payment .. " WHERE `id` = " .. guild)
            else
                    payment = 0
            end

            local begining, ending = os.time(), tonumber(t[5])
            if(ending ~= nil and ending ~= 0) then
                    ending = begining + (ending * 86400)
            else
                    ending = 0
            end

            db.query("INSERT INTO `guild_wars` (`guild1`, `guild2`, `started`, `ended`, `frags`, `payment`) VALUES (" .. guild .. ", " .. enemy .. ", " .. begining .. ", " .. ending .. ", " .. frags .. ", " .. payment .. ");")
           db.query("INSERT INTO `znote_guild_wars` (`limit`) VALUES ("..frags..");") -- this is what is missing tried to add it by this piece of code but no luck yet
            broadcastMessage(getPlayerGuildName(cid) .. " has invited " .. enemyName .. " to war till " .. frags .. " frags.", MESSAGE_EVENT_ADVANCE)
            return false
    end

    if(not isInArray({"end", "finish"}, t[1])) then
            return false
    end

    local status = (t[1] == "end" and 1 or 4)
    tmp = db.storeQuery("SELECT `id` FROM `guild_wars` WHERE `guild1` = " .. guild .. " AND `guild2` = " .. enemy .. " AND `status` = " .. status)
    if(tmp ~= false) then
            local query = "UPDATE `guild_wars` SET `ended` = " .. os.time() .. ", `status` = 5 WHERE `id` = " .. result.getDataInt(tmp, "id")
            result.free(tmp)

            db.query(query)
            broadcastMessage(getPlayerGuildName(cid) .. " has " .. (status == 4 and "mend fences" or "ended up a war") .. " with " .. enemyName .. ".", MESSAGE_EVENT_ADVANCE)
            return false
    end

    if(status == 4) then
            player:sendChannelMessage("", "Currently there's no pending war truce from " .. enemyName .. ".", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
            return false
    end

    tmp = db.storeQuery("SELECT `id`, `ended` FROM `guild_wars` WHERE `guild1` = " .. enemy .. " AND `guild2` = " .. guild .. " AND `status` = 1")
    if(tmp ~= false) then
            if(result.getDataInt(tmp, "ended") > 0) then
                    result.free(tmp)
                    player:sendChannelMessage("", "You cannot request ending for war with " .. enemyName .. ".", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
                    return false
            end

            local query = "UPDATE `guild_wars` SET `status` = 4, `ended` = " .. os.time() .. " WHERE `id` = " .. result.getDataInt(tmp, "id")
            result.free(tmp)

            db.query(query)
            broadcastMessage(getPlayerGuildName(cid) .. " has signed an armstice declaration on a war with " .. enemyName .. ".", MESSAGE_EVENT_ADVANCE)
            return false
    end
 
    player:sendChannelMessage("", "Currently there's no active war with " .. enemyName .. ".", TALKTYPE_CHANNEL_R1, CHANNEL_GUILD)
    return false
end
 

here's the whole script for whomever gonna need it
 
Back
Top