etlegacy-lua-scripts/dynamite/dynamite.lua

243 lines
7.9 KiB
Lua

--------------------------------------------------------------------------
-- dynamite.lua - a server side dynamite timer script -
--------------------------------------------------------------------------
-- 1.42:
-- - made the script Lua 5.2.3 compatible
-- 1.41:
-- - pheno: made the script ETpub (and other mod?) compatible
-- - pheno: made the script Lua 5.2 compatible
--
-- 1.4:
-- - first release
--------------------------------------------------------------------------
local version = "1.42"
-- 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 announce_pos = "cpm"
-- 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")) + 1
sv_fps = tonumber(et.trap_Cvar_Get("sv_fps"))
local i = 0
for i=1, 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
for i, data in pairs(steps) do
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 pattern = "^" .. et.trap_Cvar_Get("gamename") .. "%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
-- check if we have to print the countdown messages
function et_RunFrame(lvltime)
levelTime = lvltime
for i, timer in pairs(timers) do
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 + 1] == false then
status = "^8off^7"
end
et.trap_SendServerCommand(id, string.format("%s \"^#(dynatimer):^7 Dynatimer is %s\"", announce_pos, status))
elseif tonumber(arg) == 0 then
setTimerMessages(id, false)
et.trap_SendServerCommand(id,
string.format("%s \"^#(dynatimer):^7 Dynatimer is now ^8off^7\"", announce_pos))
else
setTimerMessages(id, true)
et.trap_SendServerCommand(id,
string.format("%s \"^#(dynatimer):^7 Dynatimer is now ^8on^7\"", announce_pos))
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)
for id, timer_wanted in pairs(client_msg) do
if timer_wanted then
et.trap_SendServerCommand(id - 1, 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)
for i, timer in pairs(timers) do
-- problem with 2 or more planted dynas at one location
-- ... remove the one which was planted first
if timer[T_LOCATION] == location then
table.remove(timers, i)
end
end
end
function setTimerMessages(id, value)
client_msg[id + 1] = 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 + 1] = false
else
client_msg[id + 1] = true
end
end
function et_ClientBegin(id)
updateUInfoStatus(id)
end
function et_UserinfoChanged(id)
updateUInfoStatus(id)
end
function et_ClientDisconnect(id)
client_msg[id + 1] = false
end
-- vim: ts=4 sw=4 expandtab syn=lua