View Issue Details

IDProjectCategoryView StatusLast Update
0000096WolfAdminCommandspublic2020-04-14 21:52
Reporterharlekin Assigned To 
PrioritynormalSeverityfeatureReproducibilityhave not tried
Status newResolutionopen 
Summary0000096: Dynamite counter
Descriptionadd dynamite counter to wolfadmin. To have a all in one system, instead of many tiny scripts loaded

lua attached
Tagsdynamite
ModN/A
Mod version
Standaloneyes

Activities

harlekin

2019-01-27 09:21

reporter  

dyna.lua (8,396 bytes)   
--------------------------------------------------------------------------
-- dynamite.lua - a server side dynamite timer script                    -
--------------------------------------------------------------------------
--
-- $Date: 2007-02-18 20:00:45 +0100 (So, 18 Feb 2007) $
-- $Revision: 93 $
local version = "1.4"

-- Benny: 
-- Config:
-- where to place the timer message, see
--   http://wolfwiki.anime.net/index.php/SendServerCommand#Printing 
-- for valid locations
-- local announce_pos   = "b 128"


local announce_pos   = "b 8"
local pattern = "^etpro%s+popup:%s+(%w+)%s+(%w+)%s+\"(.+)\""

-- mod selection harle rip off
gamename = et.trap_Cvar_Get("gamename")
if (gamename == "noquarter" or gamename == "nq")  then
  announce_pos   = "chat"
  pattern = "^nq%s+popup:%s+(%w+)%s+(%w+)%s+\"(.+)\""
end

gamename = et.trap_Cvar_Get("gamename")
if (gamename == "etpub")  then
  announce_pos   = "chat"
  pattern = "^etpub%s+popup:%s+(%w+)%s+(%w+)%s+\"(.+)\""
end
-- mod selection harle rip off

-- print "Dynamite planted at LOCATION"? This only affects this message,
-- not the countdown messages
local announce_plant = true

-- enable timer for all on default or just the clients who did a 
-- 'setu v_dynatimer 1'?
local cl_default = true

-- for 20, 10, 5, 3, 2, 1, NOW use:
-- local steps = { -- [step] = { next step, diff to next step }
--                [20]   =  { 10,        10 }, 
--                [10]   =  {  5,         5 }, 
--                 [5]   =  {  3,         2 }, 
--                 [3]   =  {  2,         1 }, 
--                 [2]   =  {  1,         1 }, 
--                 [1]   =  {  0,         1 },
--                 [0]   =  {  0,         0 } -- delete if diff to next == 0
--            }
----------------------------------------------------------------------------
-- [!!!] Hirnlos settings:
   local steps = { -- [step] = { next step, diff to next step }
                     [20]   =  { 10,        10 }, 
                     [10]   =  {  5,         5 }, 
                      [5]   =  {  2,         3 },
                      [2]   =  {  0,         0 } -- no BOOM
                }
----------------------------------------------------------------------------
-- -- for 25, 15, 5, 3, 2, 1 use:
-- local steps = {
--                 [25]={15,10},
--                 [15]={5,10},
--                  [5]={3,2},
--                  [3]={2,1}, 
--                  [2]={1,1}, 
--                  [1]={0,0} -- no "Dynamite at %s exploding now" message
--               }
-- -- I think you got the idea now ...oh setting first_step = 30 will print
-- -- everything one (server) frame too late ... FIXED: all messages moved
-- -- one frame earlier ;-)
-- END Config


local timers     = {}
local client_msg = {}
local levelTime
local sv_maxclients
local sv_fps
local first_step 

local ST_NEXT = 1
local ST_DIFF = 2

local T_TIME     = 1
local T_STEP     = 2
local T_LOCATION = 3

-- called when game inits
function et_InitGame(levelTime, randomSeed, restart)
    et.RegisterModname("dynamite.lua" .. version .. " " .. et.FindSelf())
    sv_maxclients = tonumber(et.trap_Cvar_Get("sv_maxclients"))
    sv_fps        = tonumber(et.trap_Cvar_Get("sv_fps"))
    local i = 0
    for i=0, sv_maxclients do
        -- set to false, clients will change it, as soon as they enter the world
        table.insert(client_msg, i, false) 
    end
    first_step = 0
    table.foreach(steps,
        function(i, data) if i > first_step then first_step = i end end
    )
    et.G_Print("Vetinari's dynamite.lua version "..version.." activated...\n")
end

-- the dynamite planted/defused messages... grab them and start / stop the
-- timer
function et_Print(text)
    -- etpro popup: allies planted "the Old City Wall"
    -- etpro popup: axis defused "the Old City Wall"
    local junk1,junk2,team,action,location = string.find(text, pattern)
    if team ~= nil and action ~= nil and location ~= nil then
        if action == "planted" then
            if announce_plant then
                sayClients(announce_pos, 
                    string.format("Dynamite planted at ^8%s^7", location))
            end
            addTimer(location)
        end
        if action == "defused" then
            sayClients(announce_pos, 
                string.format("Dynamite defused at ^8%s^7", location))
            removeTimer(location)
        end
    end

    if text == "Exit: Timelimit hit.\n" or text == "Exit: Wolf EndRound.\n" then
        -- stop countdowns on intermission
        timers = {}
    end
end

-- check if we have to print the countdown messages
function et_RunFrame(lvltime)
    levelTime = lvltime
    table.foreach(timers, -- usually this is empty, so nothing is done
        function(i, timer)
            if timer[T_TIME] <= levelTime then 
                printTimer(timer[T_STEP], timer[T_LOCATION])
                local step = steps[timer[T_STEP]]
                if step[ST_DIFF] == 0 then
                    removeTimer(timer[T_LOCATION])
                else
                    timer[T_STEP] = step[ST_NEXT]
                    timer[T_TIME] = levelTime + (step[ST_DIFF] * 1000)
                end
            end
        end
    )
end

-- \dynatimer client command, switch on/off, get status about the setting
-- The client setting (and server's default, if unset on client) are now
-- stored in a userinfo var. This keeps the setting across map changes.
function et_ClientCommand(id, command)
    if string.lower(et.trap_Argv(0)) == "dynatimer" then
        local arg = et.trap_Argv(1)
        if arg == "" then
            local status = "^8on^7"
            if client_msg[id] == false then
                status = "^8off^7"
            end
            et.trap_SendServerCommand(id, 
                    string.format("b 8 \"^#(dynatimer):^7 Dynatimer is %s\"", 
                            status))
        elseif tonumber(arg) == 0 then
            setTimerMessages(id, false)
            et.trap_SendServerCommand(id,
                    "b 8 \"^#(dynatimer):^7 Dynatimer is now ^8off^7\"")
        else
            setTimerMessages(id, true)
            et.trap_SendServerCommand(id, 
                    "b 8 \"^#(dynatimer):^7 Dynatimer is now ^8on^7\"")
        end
        return(1)
    end
    return(0)
end

-- print messages... just to the clients, who want them
function sayClients(pos, msg) 
    local message = string.format("%s \"%s^7\"", pos, msg)
    table.foreach(client_msg,
        function(id, timer_wanted)
            if timer_wanted then
                et.trap_SendServerCommand(id, message)
            end
        end
    )
end

function printTimer(seconds, loc) 
    local when = string.format("in ^8%d^7 seconds", seconds)
    if seconds == 0 then
        when = "^8now^7"
    elseif seconds == 1 then
        when = "in ^81^7 second"
    end
    sayClients(announce_pos, 
            string.format("Dynamite at ^8%s^7 exploding %s", loc, when))
end

function addTimer(location) 
    -- local diff = (30 - first_step) * 1000
    -- move one server frame earlier
    local diff = ((30 - first_step) * 1000) - math.floor(1000 / sv_fps)
    table.insert(timers, { levelTime + diff, first_step, location })
end

function removeTimer(location) 
    local delete = table.foreach(timers,
        function(i, timer) 
            -- problem with 2 or more planted dynas at one location
            -- ... remove the one which was planted first
            if timer[T_LOCATION] == location then
                return(i)
            end
        end
    )
    if delete ~= nil then
        table.remove(timers, delete)
    end
end

function setTimerMessages(id, value) 
    client_msg[id] = value
    if value then
        value = "1"
    else
        value = "0"
    end
    et.trap_SetUserinfo(id, 
        et.Info_SetValueForKey(et.trap_GetUserinfo(id), "v_dynatimer", value)
    )
end

function updateUInfoStatus(id) 
    local timer = et.Info_ValueForKey(et.trap_GetUserinfo(id), "v_dynatimer")
    if timer == "" then
        setTimerMessages(id, cl_default)
    elseif tonumber(timer) == 0 then
        client_msg[id] = false
    else
        client_msg[id] = true 
    end
end

function et_ClientBegin(id)
    updateUInfoStatus(id) 
end

function et_UserinfoChanged(id) 
    updateUInfoStatus(id) 
end

function et_ClientDisconnect(id) 
    client_msg[id] = false
end

-- vim: ts=4 sw=4 expandtab syn=lua
dyna.lua (8,396 bytes)   

harlekin

2019-05-10 14:33

reporter   ~0000127

not fully working version of dyna counter.
dyna-2.lua (8,232 bytes)   
--------------------------------------------------------------------------
-- dynamite.lua - a server side dynamite timer script                    -
--------------------------------------------------------------------------
--
-- $Date: 2007-02-18 20:00:45 +0100 (So, 18 Feb 2007) $
-- $Revision: 93 $
local version = "1.4"

-- Benny: 
-- Config:
-- where to place the timer message, see
--   http://wolfwiki.anime.net/index.php/SendServerCommand#Printing 
-- for valid locations
-- local announce_pos   = "b 128"


local announce_pos   = "chat"
local pattern = "^legacy%s+popup:%s+%^7(%w+)%^7%s+(%w+)%s+\"(.+)\""
-- local pattern = "^legacy%s+popup:%s+%^7(%w*)%^7%s+(%w+)%s+"(.+)""
-- print "Dynamite planted at LOCATION"? This only affects this message,
-- not the countdown messages
local announce_plant = true

-- enable timer for all on default or just the clients who did a 
-- 'setu v_dynatimer 1'?
local cl_default = true

-- for 20, 10, 5, 3, 2, 1, NOW use:
-- local steps = { -- [step] = { next step, diff to next step }
--                [20]   =  { 10,        10 }, 
--                [10]   =  {  5,         5 }, 
--                 [5]   =  {  3,         2 }, 
--                 [3]   =  {  2,         1 }, 
--                 [2]   =  {  1,         1 }, 
--                 [1]   =  {  0,         1 },
--                 [0]   =  {  0,         0 } -- delete if diff to next == 0
--            }
----------------------------------------------------------------------------
-- [!!!] Hirnlos settings:
   local steps = { -- [step] = { next step, diff to next step }
                     [20]   =  { 10,        10 }, 
                     [10]   =  {  5,         5 }, 
                      [5]   =  {  2,         3 },
                      [2]   =  {  0,         0 } -- no BOOM
                }
----------------------------------------------------------------------------
-- -- for 25, 15, 5, 3, 2, 1 use:
-- local steps = {
--                 [25]={15,10},
--                 [15]={5,10},
--                  [5]={3,2},
--                  [3]={2,1}, 
--                  [2]={1,1}, 
--                  [1]={0,0} -- no "Dynamite at %s exploding now" message
--               }
-- -- I think you got the idea now ...oh setting first_step = 30 will print
-- -- everything one (server) frame too late ... FIXED: all messages moved
-- -- one frame earlier ;-)
-- END Config


local timers     = {}
local client_msg = {}
local levelTime
local sv_maxclients
local sv_fps
local first_step 

local ST_NEXT = 1
local ST_DIFF = 2

local T_TIME     = 1
local T_STEP     = 2
local T_LOCATION = 3

-- called when game inits
function et_InitGame(levelTime, randomSeed, restart)
    et.RegisterModname("dynamite.lua" .. version .. " " .. et.FindSelf())
    sv_maxclients = tonumber(et.trap_Cvar_Get("sv_maxclients"))
    sv_fps        = tonumber(et.trap_Cvar_Get("sv_fps"))
    local i = 0
    for i=0, sv_maxclients do
        -- set to false, clients will change it, as soon as they enter the world
        client_msg[i] = false
    end
    first_step = 0
    table.foreach(steps,
        function(i, data) if i > first_step then first_step = i end end
    )
    et.G_Print("Vetinari's dynamite.lua version "..version.." activated...\n")
end

-- the dynamite planted/defused messages... grab them and start / stop the
-- timer
function et_Print(text)
    -- etpro popup: allies planted "the Old City Wall"
    -- etpro popup: axis defused "the Old City Wall"
    local junk1,junk2,team,action,location = string.find(text, pattern)
    if team ~= nil and action ~= nil and location ~= nil then
        if action == "planted" then
            if announce_plant then
                sayClients(announce_pos, 
                    string.format("Dynamite planted at ^8%s^7", location))
            end
            addTimer(location)
        end
        if action == "defused" then
            sayClients(announce_pos, 
                string.format("Dynamite defused at ^8%s^7", location))
            removeTimer(location)
        end
    end

    if text == "Exit: Timelimit hit.\n" or text == "Exit: Wolf EndRound.\n" then
        -- stop countdowns on intermission
        timers = {}
    end
end

-- check if we have to print the countdown messages
function et_RunFrame(lvltime)
    levelTime = lvltime
    table.foreach(timers, -- usually this is empty, so nothing is done
        function(i, timer)
            if timer[T_TIME] <= levelTime then 
                printTimer(timer[T_STEP], timer[T_LOCATION])
                local step = steps[timer[T_STEP]]
                if step[ST_DIFF] == 0 then
                    removeTimer(timer[T_LOCATION])
                else
                    timer[T_STEP] = step[ST_NEXT]
                    timer[T_TIME] = levelTime + (step[ST_DIFF] * 1000)
                end
            end
        end
    )
end

-- \dynatimer client command, switch on/off, get status about the setting
-- The client setting (and server's default, if unset on client) are now
-- stored in a userinfo var. This keeps the setting across map changes.
function et_ClientCommand(id, command)
    if string.lower(et.trap_Argv(0)) == "dynatimer" then
        local arg = et.trap_Argv(1)
        if arg == "" then
            local status = "^8on^7"
            if client_msg[id] == false then
                status = "^8off^7"
            end
            et.trap_SendServerCommand(id, 
                    string.format("chat \"^#(dynatimer):^7 Dynatimer is %s\"", 
                            status))
        elseif tonumber(arg) == 0 then
            setTimerMessages(id, false)
            et.trap_SendServerCommand(id,
                    "chat \"^#(dynatimer):^7 Dynatimer is now ^8off^7\"")
        else
            setTimerMessages(id, true)
            et.trap_SendServerCommand(id, 
                    "chat \"^#(dynatimer):^7 Dynatimer is now ^8on^7\"")
        end
        return(1)
    end
    return(0)
end

-- print messages... just to the clients, who want them
function sayClients(pos, msg) 
    local message = string.format("%s \"%s^7\"", pos, msg)
    table.foreach(client_msg,
        function(id, timer_wanted)
            if timer_wanted then
                et.trap_SendServerCommand(id, message)
            end
        end
    )
end

function printTimer(seconds, loc) 
    local when = string.format("in ^8%d^7 seconds", seconds)
    if seconds == 0 then
        when = "^8now^7"
    elseif seconds == 1 then
        when = "in ^81^7 second"
    end
    sayClients(announce_pos, 
            string.format("Dynamite at ^8%s^7 exploding %s", loc, when))
end

function addTimer(location) 
    -- local diff = (30 - first_step) * 1000
    -- move one server frame earlier
    local diff = ((30 - first_step) * 1000) - math.floor(1000 / sv_fps)
    table.insert(timers, { levelTime + diff, first_step, location })
end

function removeTimer(location) 
    local delete = table.foreach(timers,
        function(i, timer) 
            -- problem with 2 or more planted dynas at one location
            -- ... remove the one which was planted first
            if timer[T_LOCATION] == location then
                return(i)
            end
        end
    )
    if delete ~= nil then
        table.remove(timers, delete)
    end
end

function setTimerMessages(id, value) 
    client_msg[id] = value
    if value then
        value = "1"
    else
        value = "0"
    end
    et.trap_SetUserinfo(id, 
        et.Info_SetValueForKey(et.trap_GetUserinfo(id), "v_dynatimer", value)
    )
end

function updateUInfoStatus(id) 
    local timer = et.Info_ValueForKey(et.trap_GetUserinfo(id), "v_dynatimer")
    if timer == "" then
        setTimerMessages(id, cl_default)
    elseif tonumber(timer) == 0 then
        client_msg[id] = false
    else
        client_msg[id] = true 
    end
end

function et_ClientBegin(id)
    updateUInfoStatus(id) 
end

function et_UserinfoChanged(id) 
    updateUInfoStatus(id) 
end

function et_ClientDisconnect(id) 
    client_msg[id] = false
end

table.foreach = function(items, callback)
	for key, value in pairs(items) do
		local result = callback(key, value)
		if result ~= nil then
			return result
		end
	end
end

-- vim: ts=4 sw=4 expandtab syn=lua
dyna-2.lua (8,232 bytes)   

Issue History

Date Modified Username Field Change
2019-01-27 09:21 harlekin New Issue
2019-01-27 09:21 harlekin Tag Attached: dynamite
2019-01-27 09:21 harlekin Tag Attached: lua
2019-01-27 09:21 harlekin File Added: dyna.lua
2019-01-28 13:53 Timo Tag Detached: lua
2019-01-28 15:32 Timo Target Version => 1.3.0
2019-01-28 15:32 Timo Description Updated
2019-01-28 15:32 Timo Mod Legacy => N/A
2019-01-28 15:32 Timo Standalone no => yes
2019-05-10 14:33 harlekin File Added: dyna-2.lua
2019-05-10 14:33 harlekin Note Added: 0000127
2020-04-14 21:52 Timo Target Version 1.3.0 =>