User:Hadr0
Profile
|
Anti Spawn Kill Bot
This bot enforces Shiven spawnkilling rules. It can detect a spawn switch and gives the withdrawing team time to clear the area. It is meant as an illustration of Lua's power.
Players are punished by removing health. Allies can go through axis spawn in the first map part.. but only while holding a knife. Lua's function et_ClientCommand(cno, cmd) can not be triggered by "+attack" command. So making a no-fire zone was done this way.
It currently only supports the Fuel Dump map. But adding more maps should not be hard. A useful tool for determining box/sphere coordinates is the Radiant map editor. Decompile the maps .bsp first using q3map2.
skbot.lua code:
-----------------------------------------------------------------------------------------------------
-- Lua Guardian
-- Anti Spawn Kill Bot
-- created by Hadro
-- contact adr7777@hotmail.com
-----------------------------------------------------------------------------------------------------
-- many thanks to the regulars from 'shiven.net ** 24/7 action'
-- for putting up with my genocidal beta tests =)
-----------------------------------------------------------------------------------------------------
-- origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3]
-- checks if a player is in a box with lowest coordinates origin[1,2,3] and highest coordinates endpt[1,2,3]
--
-- (ppos[1] - origin[1])^2 + (ppos[2] - origin[2])^2 + (ppos[3] - origin[3])^2 < radius^2
-- checks if a player is in a sphere with center origin[1,2,3] and radius
-- spheres are not used for the fueldump map
-----------------------------------------------------------------------------------------------------
version = "1.0"
samplerate = 500 -- bot will check player positions every x milliseconds
function et_RunFrame(levelTime)
if math.mod(levelTime, samplerate) ~= 0 then return end
if mapname ~= "fueldump" then return end
for cno=0, num_cl-1, 1 do
phealth = et.gentity_get(cno, "health")
if phealth > 0 then
msg = nil
ppos = et.gentity_get(cno,"r.currentOrigin")
teamnum = et.gentity_get(cno, "sess.sessionTeam")
if teamnum == 1 then -- if you are Axis:
if fdspawnswitch == nil then
-- allied spawn hut
origin = { -2864, -9376, 64 }
endpt = { 496, -6192, 1152 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s ^3was ^)wiped out ^3for getting too close to allied spawn"
end
elseif spawnfullyswitched == 1 then -- if spawn as switched and delay has passed:
-- balcony lookout
origin = { -4968, -2066, 792 }
endpt = { -4454, -808, 1024 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s ^3was ^)crushed ^3for entering allied spawn"
end
-- office & balcony over main door
origin = { -5752, -3080, 488 }
endpt = { -5192, -1568, 1024 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s ^3was ^)crushed ^3for entering allied spawn"
end
--lower office
origin = { -5720, -2064, 344 }
endpt = { -4848, -1272, 1024 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s ^3was ^)crushed ^3for entering allied spawn"
end
end
end -- if axis
if teamnum == 2 then -- if you are Allies:
if fdspawnswitch == nil then
-- dont trickjump over axis facade roof in first map part
origin = { -9272, -5328, 608 }
endpt = { -8576, -5028, 792 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^3Please don't do that LAME trickjump now, ^7%s"
end
-- knife only in axis spawn region
if et.gentity_get(cno, "s.weapon") ~= 1 then
-- balcony lookout
origin = { -4968, -2066, 792 }
endpt = { -4454, -808, 1024 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s^3, you can ONLY pass through axis spawn holding a ^7KNIFE"
end
-- office & balcony over main door
origin = { -5752, -3080, 488 }
endpt = { -5192, -1568, 1024 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s^3, you can ONLY pass through axis spawn holding a ^7KNIFE"
end
-- lower office
origin = { -5720, -2064, 344 }
endpt = { -4848, -1272, 1024 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s^3, you can ONLY pass through axis spawn holding a ^7KNIFE"
end
end
else -- if spawn switched
-- axis facade
origin = { -9424, -5600, 440 }
endpt = { -8928, -5160, 600 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s ^3was ^5spanked ^3for entering axis upper spawn"
end
-- axis rear spawn exit
origin = { -9240, -7448, 208 }
endpt = { -8728, -7184, 352 }
if origin[1] < ppos[1] and ppos[1] < endpt[1] and origin[2] < ppos[2] and ppos[2] < endpt[2] and origin[3] < ppos[3] and ppos[3] < endpt[3] then
msg = "^7%s ^3was ^)annihilated ^3for entering axis rear spawn"
end
end
end -- if allies
if msg ~= nil then
et.gentity_set(cno, "health", -511)
msg = string.format(msg, et.Info_ValueForKey(et.trap_GetUserinfo(cno), "name"))
msg = string.format("qsay %s\n", msg)
et.trap_SendConsoleCommand(et.EXEC_APPEND, msg)
et.trap_SendServerCommand(cno, "cp \"^1!! DO NOT SPAWNKILL !!\"\n" )
end
end -- if health > 0
end -- for loop
if fdspawnswitch == 1 and spawnfullyswitched == nil then
if switchcounter == switchtime then
spawnfullyswitched = 1
else
if switchcounter == 0 then
et.trap_SendServerCommand(-1, "cpm \"^6Lua^7: allied spawn will be protected in 45 seconds\"\n")
end
if switchcounter == switchtime - 1 then
et.trap_SendServerCommand(-1, "cpm \"^6Lua^7: allied spawn is now protected\"\n")
end
switchcounter = switchcounter + 1
end
end
end
function et_InitGame(levelTime, randomSeed, restart)
num_cl = et.trap_Cvar_Get("sv_maxclients")
mapname = et.trap_Cvar_Get("mapname")
origin = {}
endpt = {}
switchcounter = 0
switchtime = 45 / samplerate * 1000 -- 45 seconds to spawn protection switch
end
function et_ClientCommand(cno, cmd)
if cmd ~= "say" then return 0 end
if string.lower(et.ConcatArgs(1)) ~= "!luatest" then return 0 end
et.trap_SendConsoleCommand(et.EXEC_APPEND, "qsay \"^3test for ^6Lua ^7Guardian - Anti Spawn Kill Bot\"\n")
if mapname == "fueldump" then
tosend = string.format("qsay \"^3>version ^7%s ^3sampling at ^7%d ^3milliseconds\"\n", version, samplerate)
et.trap_SendConsoleCommand(et.EXEC_APPEND, tosend)
else
tosend = string.format("qsay \"^3>version ^7%s ^3no parameters set for ^7%s ^3map\"\n", version, mapname)
et.trap_SendConsoleCommand(et.EXEC_APPEND, tosend)
end
return 0
end
function et_Print(text)
if text == "Setting Axis autospawn to Axis Fuel Dump\n" then fdspawnswitch = 1 end
end
Note that shiven.net uses a slightly different type of anti spawnkill bot. One that uses 'invincibility zones' for more info see our server rules. The essence however is still the same.
Not much time was spent programming this so feel free to do with it what you please.