--------------------------------------------------------------------------
-- dynamite.lua - a server side dynamit timer script -
--------------------------------------------------------------------------
--
-- $Date: 2007-02-12 14:13:10 +0100 (Mon, 12 Feb 2007) $
-- $Revision: 69 $
local version = "1.1"
--------------------------------------------------------------------------
-- README:
-- This is a server side dynamite timer script. The messages will be sent
-- to all clients who enabled the messages. Th default of sending / not
-- sending the timer messages are set by the server admin, see the
-- 'cl_default' setting below.
--
-- A client can set it's default (on/off) by setting '+setu dynatimer 1'
-- or '+setu dynatimer 0' as command line argument for et.
--
-- Timers can be enabled for the current map with the client command
-- '\cmd dynatimer 1' or disabled with '\cmd dynatimer 0'. Note that the
-- map starts (again), after the warmup ends...
-- The 'cmd' is necessary if the client set the user var dynatimer...
--------------------------------------------------------------------------
-- 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"
-- 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 'setu dynatimer 1'?
local cl_default = false
-- for 20, 10, 5, 3, 2, 1, NOW use:
local first_step = 20
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
}
-- -- for 25, 15, 5, 3, 2, 1 use:
-- local first_step = 25
-- 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 ;-)
-- END Config
local timers = {}
local client_msg = {}
local levelTime
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"))
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
et.G_Print("Vetinari's dynamite.lua version "..version.." activated...\n")
end
function sayClients(pos, msg)
table.foreach(client_msg,
function(id, timer_wanted)
if timer_wanted then
et.trap_SendServerCommand(id,
string.format("%s \"%s^7\"", pos, msg))
end
end
)
end
function et_Print(text)
-- etpro popup: allies planted "the Old City Wall"
-- etpro popup: axis defused "the Old City Wall"
local pattern = "^etpro%s+popup:%s+(%w+)%s+(%w+)%s+\"(.+)\""
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
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) - 25 -- move one frame earlier
local diff = (30 - first_step) * 1000
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 et_RunFrame(lvltime)
levelTime = lvltime
table.foreach(timers,
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
function et_ClientDisconnect(id)
client_msg[id] = false
end
function sendStatus(id)
local status
if client_msg[id] == false then
status = "^8off^7"
else
status = "^8on^7"
end
et.trap_SendServerCommand(id,
string.format("b 8 \"^#(dynatimer):^7 Dynatimer is %s\"", status))
end
function updateUInfoStatus(id)
local dt = et.Info_ValueForKey(et.trap_GetUserinfo(id), "dynatimer")
if dt == "" then
client_msg[id] = cl_default
elseif tonumber(dt) == 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_ClientCommand(id, command)
if et.trap_Argv(0) == "dynatimer" then
local arg = et.trap_Argv(1)
if arg == "" then
sendStatus(id)
elseif tonumber(arg) == 0 then
client_msg[id] = false
et.trap_SendServerCommand(id,
"b 8 \"^#(dynatimer):^7 Dynatimer is now ^8off^7\"")
else
client_msg[id] = true
et.trap_SendServerCommand(id,
"b 8 \"^#(dynatimer):^7 Dynatimer is now ^8on^7\"")
end
return(1)
end
return(0)
end
-- vim: ts=4 sw=4 expandtab syn=lua