File content:

  1. --------------------------------------------------------------------------
  2. -- dynamite.lua - a server side dynamit timer script -
  3. --------------------------------------------------------------------------
  4. --
  5. -- $Date: 2007-02-12 14:13:10 +0100 (Mon, 12 Feb 2007) $
  6. -- $Revision: 69 $
  7. local version = "1.1"
  8.  
  9. --------------------------------------------------------------------------
  10. -- README:
  11. -- This is a server side dynamite timer script. The messages will be sent
  12. -- to all clients who enabled the messages. Th default of sending / not
  13. -- sending the timer messages are set by the server admin, see the
  14. -- 'cl_default' setting below.
  15. --
  16. -- A client can set it's default (on/off) by setting '+setu dynatimer 1'
  17. -- or '+setu dynatimer 0' as command line argument for et.
  18. --
  19. -- Timers can be enabled for the current map with the client command
  20. -- '\cmd dynatimer 1' or disabled with '\cmd dynatimer 0'. Note that the
  21. -- map starts (again), after the warmup ends...
  22. -- The 'cmd' is necessary if the client set the user var dynatimer...
  23. --------------------------------------------------------------------------
  24.  
  25. -- Config:
  26. -- where to place the timer message, see
  27. -- http://wolfwiki.anime.net/index.php/SendServerCommand#Printing
  28. -- for valid locations
  29. -- local announce_pos = "b 128"
  30. local announce_pos = "b 8"
  31.  
  32. -- print "Dynamite planted at LOCATION"? This only affects this message,
  33. -- not the countdown messages
  34. local announce_plant = true
  35.  
  36. -- enable timer for all on default or just the clients who 'setu dynatimer 1'?
  37. local cl_default = false
  38.  
  39. -- for 20, 10, 5, 3, 2, 1, NOW use:
  40. local first_step = 20
  41. local steps = { -- [step] = { next step, diff to next step }
  42. [20] = { 10, 10 },
  43. [10] = { 5, 5 },
  44. [5] = { 3, 2 },
  45. [3] = { 2, 1 },
  46. [2] = { 1, 1 },
  47. [1] = { 0, 1 },
  48. [0] = { 0, 0 } -- delete if diff to next == 0
  49. }
  50. -- -- for 25, 15, 5, 3, 2, 1 use:
  51. -- local first_step = 25
  52. -- local steps = {
  53. -- [25]={15,10},
  54. -- [15]={5,10},
  55. -- [5]={3,2},
  56. -- [3]={2,1},
  57. -- [2]={1,1},
  58. -- [1]={0,0} -- no "Dynamite at %s exploding now" message
  59. -- }
  60. -- -- I think you got the idea now ...oh setting first_step = 30 will print
  61. -- -- everything one (server) frame too late ;-)
  62. -- END Config
  63.  
  64.  
  65. local timers = {}
  66. local client_msg = {}
  67. local levelTime
  68.  
  69. local ST_NEXT = 1
  70. local ST_DIFF = 2
  71.  
  72. local T_TIME = 1
  73. local T_STEP = 2
  74. local T_LOCATION = 3
  75.  
  76.  
  77. -- called when game inits
  78. function et_InitGame(levelTime, randomSeed, restart)
  79. et.RegisterModname("dynamite.lua" .. version .. " " .. et.FindSelf())
  80. sv_maxclients = tonumber(et.trap_Cvar_Get("sv_maxclients"))
  81. local i = 0
  82. for i=0, sv_maxclients do
  83. -- set to false, clients will change it, as soon as they enter the world
  84. table.insert(client_msg, i, false)
  85. end
  86. et.G_Print("Vetinari's dynamite.lua version "..version.." activated...\n")
  87. end
  88.  
  89. function sayClients(pos, msg)
  90. table.foreach(client_msg,
  91. function(id, timer_wanted)
  92. if timer_wanted then
  93. et.trap_SendServerCommand(id,
  94. string.format("%s \"%s^7\"", pos, msg))
  95. end
  96. end
  97. )
  98. end
  99.  
  100. function et_Print(text)
  101. -- etpro popup: allies planted "the Old City Wall"
  102. -- etpro popup: axis defused "the Old City Wall"
  103. local pattern = "^etpro%s+popup:%s+(%w+)%s+(%w+)%s+\"(.+)\""
  104. local junk1,junk2,team,action,location = string.find(text, pattern)
  105. if team ~= nil and action ~= nil and location ~= nil then
  106. if action == "planted" then
  107. if announce_plant then
  108. sayClients(announce_pos,
  109. string.format("Dynamite planted at ^8%s^7", location))
  110. end
  111. addTimer(location)
  112. end
  113. if action == "defused" then
  114. sayClients(announce_pos,
  115. string.format("Dynamite defused at ^8%s^7", location))
  116. removeTimer(location)
  117. end
  118. end
  119.  
  120. if text == "Exit: Timelimit hit.\n" or text == "Exit: Wolf EndRound.\n" then
  121. -- stop countdowns on intermission
  122. timers = {}
  123. end
  124. end
  125.  
  126. function printTimer(seconds, loc)
  127. local when = string.format("in ^8%d^7 seconds", seconds)
  128. if seconds == 0 then
  129. when = "^8now^7"
  130. elseif seconds == 1 then
  131. when = "in ^81^7 second"
  132. end
  133. sayClients(announce_pos,
  134. string.format("Dynamite at ^8%s^7 exploding %s", loc, when))
  135. end
  136.  
  137. function addTimer(location)
  138. -- local diff = ((30 - first_step) * 1000) - 25 -- move one frame earlier
  139. local diff = (30 - first_step) * 1000
  140. table.insert(timers, { levelTime + diff, first_step, location })
  141. end
  142.  
  143. function removeTimer(location)
  144. local delete = table.foreach(timers,
  145. function(i, timer)
  146. -- problem with 2 or more planted dynas at one location
  147. -- ... remove the one which was planted first
  148. if timer[T_LOCATION] == location then
  149. return(i)
  150. end
  151. end
  152. )
  153. if delete ~= nil then
  154. table.remove(timers, delete)
  155. end
  156. end
  157.  
  158. function et_RunFrame(lvltime)
  159. levelTime = lvltime
  160. table.foreach(timers,
  161. function(i, timer)
  162. if timer[T_TIME] <= levelTime then
  163. printTimer(timer[T_STEP], timer[T_LOCATION])
  164. local step = steps[timer[T_STEP]]
  165. if step[ST_DIFF] == 0 then
  166. removeTimer(timer[T_LOCATION])
  167. else
  168. timer[T_STEP] = step[ST_NEXT]
  169. timer[T_TIME] = levelTime + (step[ST_DIFF] * 1000)
  170. end
  171. end
  172. end
  173. )
  174. end
  175.  
  176. function et_ClientDisconnect(id)
  177. client_msg[id] = false
  178. end
  179.  
  180. function sendStatus(id)
  181. local status
  182. if client_msg[id] == false then
  183. status = "^8off^7"
  184. else
  185. status = "^8on^7"
  186. end
  187. et.trap_SendServerCommand(id,
  188. string.format("b 8 \"^#(dynatimer):^7 Dynatimer is %s\"", status))
  189. end
  190.  
  191. function updateUInfoStatus(id)
  192. local dt = et.Info_ValueForKey(et.trap_GetUserinfo(id), "dynatimer")
  193. if dt == "" then
  194. client_msg[id] = cl_default
  195. elseif tonumber(dt) == 0 then
  196. client_msg[id] = false
  197. else
  198. client_msg[id] = true
  199. end
  200. end
  201.  
  202. function et_ClientBegin(id)
  203. updateUInfoStatus(id)
  204. end
  205.  
  206. function et_UserinfoChanged(id)
  207. updateUInfoStatus(id)
  208. end
  209.  
  210. function et_ClientCommand(id, command)
  211. if et.trap_Argv(0) == "dynatimer" then
  212. local arg = et.trap_Argv(1)
  213. if arg == "" then
  214. sendStatus(id)
  215. elseif tonumber(arg) == 0 then
  216. client_msg[id] = false
  217. et.trap_SendServerCommand(id,
  218. "b 8 \"^#(dynatimer):^7 Dynatimer is now ^8off^7\"")
  219. else
  220. client_msg[id] = true
  221. et.trap_SendServerCommand(id,
  222. "b 8 \"^#(dynatimer):^7 Dynatimer is now ^8on^7\"")
  223. end
  224. return(1)
  225. end
  226. return(0)
  227. end
  228.  
  229. -- vim: ts=4 sw=4 expandtab syn=lua
  230.