Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- General infection settings
- zombie_team = 1 -- 0 is red, 1 is blue
- human_team = 1 - zombie_team
- zombie_speed = 1.5 -- zombie speed
- lastman_speed = 1.4 -- last man speed
- lastman_dmgmodifier = 1.5 -- damage modifier for the last man (on top of human damage)
- lastman_invistime = 10 -- in seconds
- human_speed = 1.0 -- speed when not infected
- zombie_count = 1 -- if value is less than 1 is it used as a percentage, more than or equal to one is absolute count
- last_man_next_zombie = true -- if this value is true the last man standing becomes the next zombie, if not it's random
- max_zombie_count = 2 -- this caps what the zombie count would be w/ ratio (nil is disable)
- lastman_invulnerable = 5 -- time (in seconds) the last man is invulnerable for: replace with nil to disable
- alphazombie_frag_count = 0 -- number of frag nades they spawn with
- alphazombie_plasma_count = 0 -- number of plasma nades they spawn with
- zombie_frag_count = 0 -- number of frag nades they spawn with
- zombie_plasma_count = 0 -- number of plasma nades they spawn with
- alphazombie_clip_count = 0 -- number of shots in clip
- alphazombie_ammo_count = 0 -- backpack ammo they get
- zombie_clip_count = 0 -- number of shots in clip for zombies once there are not only alpha zombies
- zombie_ammo_count = 0 -- backpack ammo zombies once there are not only alpha zombies
- -- Game messages
- zombie_message = "YOU'RE A ZOMBIE. KILL THE HUMANS!"
- human_message = "YOU'RE A HUMAN. SURVIVE."
- rejoin_message = "Please don't leave and rejoin. You've been put back onto your last team."
- infected_message = " has been infected!"
- teamkill_message = "Don't team kill..."
- blockteamchange_message = "You're not allowed to change team."
- zombieinvis_message = "The zombies are invisible for 20 seconds!"
- timer_team_change_msg = "Thank you. The game will now continue"
- -- Don't modify below variables unless you know what you're doing
- cur_zombie_count = 0
- cur_human_count = 0
- alpha_zombie_count = 0
- human_time = {}
- cur_players = 0
- cur_last_man = nil
- last_man_hash = 0
- processid = 0
- game_started = false
- allow_change = false
- new_game_timer = 0
- player_change_timer = 0
- oddball_weap = {}
- balls = {}
- last_hill_time = {}
- hash_table = {}
- inhill_time = {}
- -- This function is required for scripts to run on Phasor (including and after 01.00.03.104)
- -- You should return the minimum required version of Phasor
- -- Official releases:
- -- 01.00.03.104 - 3104
- -- 01.00.10.057 - 10057
- function GetRequiredVersion()
- return 10057
- end
- -- called when the script is loaded
- function OnScriptLoad(process)
- processid = process
- -- assume a game is running
- game_started = true
- humantimer = registertimer(1000, "HumanTimer")
- for i = 0,15 do
- if getplayer(i) ~= nil then
- local m_object = getobject(getplayerobjectid(i))
- if m_object ~= nil then
- local weapID = readdword(m_object, 0x118)
- local weap = getobject(weapID)
- local tagName = getobjecttag(weapID)
- if tagName == "weapons\\ball\\ball" then
- oddball_weap[i] = weapID
- end
- end
- end
- end
- -- recalculate team counters
- cur_zombie_count = getteamsize(zombie_team)
- cur_human_count = getteamsize(human_team)
- cur_players = cur_zombie_count + cur_human_count
- -- recalculate how many "alpha" zombies there are
- alpha_zombie_count = getalphacount()
- -- load the last man hash (if there is one)
- local file = io.open("lasthash_" .. processid .. ".tmp", "r")
- if (file ~= nil) then
- -- read the ip
- last_man_hash = file:read("*line")
- file:close()
- -- delete the file
- os.remove("lasthash_" .. processid .. ".tmp")
- end
- end
- -- called when the script is unloaded
- -- Do not return a value
- function OnScriptUnload()
- end
- function getobjecttag(object)
- local m_object = getobject(object)
- local object_map_id = readdword(m_object, 0x0)
- local map_base = readdword(0x63525c, 0x0)
- local map_tag_count = todec(endian(map_base, 0xC, 0x3))
- local tag_table_base = map_base + 0x28
- local tag_table_size = 0x20
- for i=0,(map_tag_count - 1) do
- local tag_id = todec(endian(tag_table_base, 0xC + (tag_table_size * i), 0x3))
- if tag_id == object_map_id then
- tag_name_address = endian(tag_table_base, 0x10 + (tag_table_size * i), 0x3)
- tag_name = readtagname("0x" .. tag_name_address)
- return tag_name
- end
- end
- end
- function endian(address, offset, length)
- local data_table = {}
- local data = ""
- for i=0,length do
- local hex = string.format("%X", readbyte(address, offset + i))
- if tonumber(hex, 16) < 16 then
- hex = 0 .. hex
- end
- table.insert(data_table, hex)
- end
- for k,v in pairs(data_table) do
- data = v .. data
- end
- return data
- end
- function todec(number)
- return tonumber(number, 16)
- end
- -- called when a game is starting (before any players join)
- -- Do not return a value.
- function OnNewGame(map)
- -- reset our variables
- cur_zombie_count = 0
- cur_human_count = 0
- cur_players = 0
- -- the game hasn't started yet, will once timer runs down
- game_started = false
- new_game_timer = registertimer(2000, "NewGameTimer")
- if map == "putput" or map == "longest" or map == "beavercreek" or map == "chillout" then
- zombie_speed = 1.35
- lastman_speed = 1.2
- if map == "dangercanyon" or map == "gephyrophobia" or map == "timberland" or map == "deathisland" or map == "bloodgulch" then
- zombie_speed = 1.8
- lastman_speed = 1.6
- end
- end
- end
- -- called when a game is ending
- -- Do not return a value.
- function OnGameEnd(mode)
- -- mode 1 = score menu (F1) is being displayed to clients, they are still ingame
- -- mode 2 = post game menu appeared
- -- mode 3 = players can quit via the post game score card
- -- remove the new game timer (if still active)
- if mode == 1 then
- removetimer(new_game_timer)
- removetimer(humantimer)
- end
- end
- -- Called when there is chat within the server
- -- It must return a value which indicates whether or not the chat is sent.
- function OnServerChat(player, chattype, message)
- return 1
- end
- -- Called when a server command is being executed
- -- It must return a value which indicates whether or not the command should be processed
- -- Note: It is only called when an authenticated (and allowed) player attempts to use the command.
- -- player is -1 when being executed via the server console.
- function OnServerCommand(player, command)
- local allow = 1
- local tokencount = getcmdtokencount(command)
- if tokencount > 0 then
- local cmd = getcmdtoken(command, 0)
- if cmd == "sv_changeteam" and tokencount == 2 then
- local player = getcmdtoken(command, 1)
- player = rresolveplayer(player)
- if getplayer(player) ~= nil then
- local cur_team = getteam(player)
- if cur_team == zombie_team then
- makehuman(player, true)
- privatesay(player, human_message)
- elseif cur_team == human_team then
- makezombie(player, true)
- privatesay(player, zombie_message)
- end
- hprintf("The player's team has been changed.")
- else
- hprintf("The specified player is invalid")
- end
- allow = 0
- elseif cmd == "sv_map_reset" then
- for i = 0,15 do
- local m_player = getplayer(i)
- if m_player ~= nil then
- local m_object = getobject(getplayerobjectid(i))
- if m_object ~= nil then
- local team = getteam(i)
- if team == zombie_team then
- -- destroyweaps(i)
- end
- end
- end
- end
- end
- end
- return allow
- end
- -- Called when a player's team is being chosen as the join the server.
- -- It must return a value which indicates the team the player is to be put on.
- -- Note: this function being called doesn't guarantee that the player will be able to successfully join.
- function OnTeamDecision(cur_team)
- local dest_team = zombie_team
- if game_started then
- if cur_players == 0 then -- if no zombies make them human
- dest_team = human_team
- elseif cur_zombie_count > 0 and cur_human_count == 0 then
- dest_team = human_team
- end
- end
- return dest_team
- end
- -- Called when a player joins the server.
- -- Do not return a value.
- function OnPlayerJoin(player, team)
- -- update the player counts
- cur_players = cur_players + 1
- local thisTeamSize = 0 -- used so we don't create empty teams for rejoining players
- if team == zombie_team then
- cur_zombie_count = cur_zombie_count + 1
- thisTeamSize = cur_zombie_count
- else
- cur_human_count = cur_human_count + 1
- thisTeamSize = cur_human_count
- end
- alpha_zombie_count = getalphacount()
- local thisHash = gethash(player)
- local alreadyExists = false
- -- check if the player has joined this game previously
- for k,v in pairs(hash_table) do
- if thisHash == k then
- if thisTeamSize > 1 then
- if v ~= team then changeteam(player, 0) end
- --privatesay(player, rejoin_message)
- team = v
- end
- alreadyExists = true
- break
- end
- end
- -- add team entry for this hash
- if alreadyExists == false then
- hash_table[thisHash] = team
- end
- if game_started == true then
- -- check if the player is a zombie
- if team == zombie_team then
- makezombie(player, false)
- privatesay(player, zombie_message)
- else
- -- if we're at last man, make this player a zombie
- if cur_last_man ~= nil then
- makezombie(player, true)
- privatesay(player, zombie_message)
- else
- makehuman(player, false)
- privatesay(player, human_message)
- end
- end
- privatesay(i, "Welcome to Wizard's Zombie Server!")
- privatesay(i, "The hill is a safe-zone! Use it for quick getaways!")
- checkgamestate(-1)
- else
- registertimer(10000, "MsgTimer", player)
- end
- end
- function MsgTimer(id, count, player)
- privatesay(player, "Welcome to SPN zombies!")
- privatesay(player, "Have fun!")
- return 0
- end
- -- Called when a player the server.
- -- Do not return a value.
- function OnPlayerLeave(player, team)
- if team == zombie_team then
- local m_object = getobject(getplayerobjectid(player))
- if m_object ~= nil then
- for i = 0,3 do
- local weapID = readdword(m_object, 0x2F8 + i*4)
- local weap = getobject(weapID)
- if weap ~= nil then
- registertimer(0, "destroyweaps", weapID)
- end
- end
- end
- cur_zombie_count = cur_zombie_count - 1
- elseif team == human_team then
- cur_human_count = cur_human_count - 1
- end
- -- if last man is leaving, reset it
- if cur_last_man == player then
- cur_last_man = nil
- end
- cur_players = cur_players - 1
- checkgamestate(-1)
- -- update team within table
- local thisHash = gethash(player)
- hash_table[thisHash] = team
- end
- -- called when a player kills another, 'killer' is the index of the killing player, 'victim' is the index of the dead player
- -- Do not return a value.
- function OnPlayerKill(killer, victim, mode)
- local v_team = getteam(victim)
- if v_team == zombie_team then
- local m_victim = getplayer(victim)
- local v_objId = readdword(m_victim, 0x34)
- local v_object = getobject(v_objId)
- for i = 0,3 do
- local m_weapId = readdword(v_object, 0x2F8 + i * 4)
- local m_weapon = getobject(m_weapId)
- defaultammo(m_weapId)
- end
- end
- if game_started then
- local team = getteam(victim)
- if mode == 0 then -- server kill
- elseif mode == 1 then -- fall damage
- if team ~= zombie_team then
- local name = getname(victim)
- say(name .. infected_message)
- makezombie(victim, false)
- end
- elseif mode == 2 then -- killed by guardians
- elseif mode == 3 then -- killed by vehicle
- elseif mode == 4 then -- killed by another player
- local killer_team = getteam(killer)
- -- check to see if a zombie killed them
- if killer_team == zombie_team and team == human_team then
- name = getname(victim)
- say(name .. infected_message)
- makezombie(victim, false)
- --privatesay(victim, zombie_message)
- end
- elseif mode == 5 then -- betrayed
- elseif mode == 6 then -- suicide
- -- if they're human, make them zombies
- if team == human_team then
- name = getname(victim)
- say(name .. infected_message)
- makezombie(victim, false)
- end
- end
- end
- end
- function defaultammo(m_weapId)
- local tagType, tagName = getobjecttag(m_weapId)
- local m_weapon = getobject(m_weapId)
- say(tagName)
- if tagName == "weapons\\assault rifle\\assault rifle" then
- writeword(m_weapon, 0x2B6, 180)
- writeword(m_weapon, 0x2B8, 60)
- elseif tagName == "weapons\\pistol\\pistol" then
- writeword(m_weapon, 0x2B6, 48)
- writeword(m_weapon, 0x2B8, 12)
- elseif tagName == "weapons\\shotgun\\shotgun" then
- writeword(m_weapon, 0x2B6, 12)
- writeword(m_weapon, 0x2B8, 12)
- elseif tagName == "weapons\\sniper rifle\\sniper rifle" then
- writeword(m_weapon, 0x2B6, 8)
- writeword(m_weapon, 0x2B8, 4)
- end
- updateammo(m_weapId)
- end
- -- called when a player gets a double kill, killing spree etc
- -- see Phasor documentation for multiplier values
- function OnKillMultiplier(player, multiplier)
- end
- -- Called when a player s (after object is created, before players are notified)
- -- Do not return a value
- function OnPlayerSpawn(player, m_objectId)
- local team = getteam(player)
- if team == zombie_team then
- local m_objectId = getplayerobjectid(player)
- local m_object = getobject(m_objectId)
- if m_object ~= nil then
- -- set nade counts
- writebyte(m_object, 0x31E, zombie_frag_count)
- writebyte(m_object, 0x31F, zombie_plasma_count)
- -- set the ammo
- local clipcount = alphazombie_clip_count
- local ammocount = alphazombie_ammo_count
- -- set ammo counts for zombies when others have been infected
- if cur_zombie_count > alpha_zombie_count then
- clipcount = zombie_clip_count
- ammocount = zombie_ammo_count
- else -- set alpha nades
- writebyte(m_object, 0x31E, alphazombie_frag_count)
- writebyte(m_object, 0x31F, alphazombie_plasma_count)
- end
- local bool = false
- for i=0,3 do
- local m_weaponId = readdword(m_object, 0x2F8 + (i*4))
- if bool == false and getobject(m_weaponId) ~= nil then
- local tagName = getobjecttag(m_weaponId)
- if tagName == "weapons\\ball\\ball" then
- oddball_weap[player] = m_weaponId
- bool = true
- end
- end
- if m_weaponId ~= 0xffffffff then
- local m_weapon = getobject(m_weaponId)
- if m_weapon ~= nil then
- -- set the ammo
- writeword(m_weapon, 0x2B6, ammocount)
- writeword(m_weapon, 0x2B8, clipcount)
- writefloat(m_weapon, 0x240, 1)
- -- force it to sync
- updateammo(m_weaponId)
- end
- end
- end
- end
- end
- end
- -- Called after clients have been notified of a player spawn
- -- Do not return a value
- function OnPlayerSpawnEnd(player, m_objectId)
- end
- -- Called when a player is attempting to .
- -- A value must be returned. The return value indicates whether or not the player is allowed the change team.
- -- Notes: If relevant is 1 the return value is considered, if it's 0 then the return value is ignored.
- function OnTeamChange(relevant, player, team, dest_team)
- if relevant == 1 then
- if allow_change == false then
- privatesay(player, blockteamchange_message)
- elseif dest_team == zombie_team then
- -- this is so memory is updated for processing
- -- when relevant is 0 OnTeamChange is called once the changes
- -- have been committed
- changeteam(player, 1)
- end
- -- we don't let people change team
- return 0
- elseif dest_team ~= team then -- we can't stop the person changing teams, bein done by an admin
- -- update team counts
- if dest_team == zombie_team then
- cur_human_count = cur_human_count - 1
- cur_zombie_count = cur_zombie_count + 1
- elseif dest_team == human_team then
- cur_human_count = cur_human_count + 1
- cur_zombie_count = cur_zombie_count - 1
- end
- -- they're allowed to change if the timer is active, if it is disable it
- if allow_change == true and dest_team == zombie_team then
- allow_change = false
- -- remove change timer
- removetimer(player_change_timer)
- player_change_timer = 0
- say(timer_team_change_msg)
- end
- -- check if the game has started yet
- if game_started == true then
- -- set attributes
- if dest_team == zombie_team then
- makezombie(player, false)
- elseif dest_team == human_team then
- makehuman(player, false)
- end
- checkgamestate(player)
- end
- -- update team withf
- local thisHash = gethash(player)
- hash_table[thisHash] = dest_team
- end
- return 1
- end
- function OnClientUpdate(player, m_objectId)
- local m_player = getplayer(player)
- local m_object = getobject(m_objectId)
- local hash = gethash(player)
- if m_object ~= nil then
- local team = readbyte(m_player, 0x20)
- if team == zombie_team then
- local obj_crouch = readbyte(m_object, 0x2A0)
- if obj_crouch == 3 then
- applycamo(player, 5)
- end
- --[[local shooting = readbit(m_object, 0x209, 4)
- local nading2 = readbit(m_object, 0x209, 2)
- local nading = readbit(m_object, 0x209, 3)
- if shooting == 1 or nading == 1 then
- local weapID = readdword(m_object, 0x2FC)
- local weap = getobject(weapID)
- if weap ~= nil then
- weapID = oddball_weap[player]
- local m_player = getplayer(player)
- if m_player ~= nil then
- if weapID == nil then
- oddball_weap[player] = createobject("weap", "weapons\\ball\\ball", 0, 0, false, 5, 5, 2)
- assignweapon(player, oddball_weap[player])
- else
- if getobject(weapID) ~= nil then
- if IsBall(weapID) then
- assignweapon(player, weapID)
- else
- oddball_weap[player] = createobject("weap", "weapons\\ball\\ball", 0, 0, false, 5, 5, 2)
- assignweapon(player, oddball_weap[player])
- end
- else
- oddball_weap[player] = createobject("weap", "weapons\\ball\\ball", 0, 0, false, 5, 5, 2)
- assignweapon(player, oddball_weap[player])
- end
- end
- end
- end
- end--]]
- end
- if tonumber(human_time[hash]) ~= nil then
- local hill_time = readword(m_player, 0xC4)
- if tonumber(hill_time) ~= nil then
- writeword(m_player, 0xC4, tonumber(human_time[hash])*30)
- end
- else
- human_time[hash] = 0
- end
- end
- writedword(0x639BD0, 0x0, 0)
- writedword(0x639BD0, 0x1, 0)
- end
- function IsBall(weapID)
- for i = 1,#balls do
- if balls[i] == weapID then
- return true
- end
- end
- end
- --[[function GiveOddball(id, count, player, weapID)
- local m_player = getplayer(player)
- if m_player ~= nil then
- if weapID == nil then
- oddball_weap[player] = createobject("weap", "weapons\\ball\\ball", 0, 0, false, 5, 5, 2)
- assignweapon(player, oddball_weap[player])
- return 0
- else
- local m_object = getobject(getplayerobjectid(player))
- if m_object ~= nil then
- if getobject(weapID) ~= nil then
- local tagName = getobjecttag(weapID)
- if tagName == "weapons\\ball\\ball" then
- assignweapon(player, weapID)
- else
- oddball_weap[player] = createobject("weap", "weapons\\ball\\ball", 0, 0, false, 5, 5, 2)
- assignweapon(player, oddball_weap[player])
- end
- else
- oddball_weap[player] = createobject("weap", "weapons\\ball\\ball", 0, 0, false, 5, 5, 2)
- assignweapon(player, oddball_weap[player])
- end
- end
- return 0
- end
- end
- return 0
- end--]]
- -- Called when a player interacts with an object
- -- It can be called while attempting to pick the object up
- -- It is also called when standing above an object so can be called various times quickly
- function OnObjectInteraction(player, m_ObjectId, tagType, tagName)
- local response = 1
- if game_started == true then
- -- regardless of the team, stop people taking the flag
- if tagType == "weap" then
- if tagName == "weapons\\flag\\flag" then
- response = 0
- elseif tagName == "weapons\\ball\\ball" then
- local team = getteam(player)
- if team == zombie_team then
- return 1
- else
- return 0
- end
- end
- end
- if response == 1 then
- local team = getteam(player)
- if team == zombie_team then
- -- we want to stop zombies picking up weapons
- if tagType == "weap" then
- response = 0
- elseif tagType == "eqip" then
- if tagName == "weapons\\frag grenade\\frag grenade" or tagName == "weapons\\plasma grenade\\plasma grenade" then
- response = 0 -- don't let them pick the nades
- elseif tagName == "powerups\\active camouflage" then
- -- check if the picking player is already invisible
- local m_player = getplayer(player)
- if m_player ~= nil then
- local m_playerObjId = readdword(m_player, 0x34)
- local m_object = getobject(m_playerObjId)
- if m_object ~= nil then
- local camoFlag = readdword(m_object, 0x204)
- if camoFlag ~= 0x51 then
- -- check if zombies are to be made invisible
- local doInvis = getrandomnumber(1, 10)
- if doInvis > 5 then
- -- make the whole zombie team invis for 20 seconds
- for x = 0,15 do
- local team = getteam(x)
- if team == zombie_team and x ~= player then
- --hprintf("applying camo to player " .. x)
- applycamo(x, 30.00)
- end
- end
- say(zombieinvis_message)
- end
- end
- end
- end
- end
- end
- end
- end
- end
- return response
- end
- -- Called when a player attempts to reload their weapon.
- -- A value must be returned. The return value indicates whether or not the player is allowed to reload.
- -- Notes: If player is -1 then the weapon being reload wasn't located (it could be a vehicle's weapon)
- function OnWeaponReload(player, weapon)
- return 1
- end
- -- Called when a player attempts to enter a vehicle.
- -- A value must be returned. The return value indicates whether or not the player is allowed to enter.
- function OnVehicleEntry(relevant, player, vehicleId, vehicle_tag, seat)
- local response = 1
- if game_started and relevant == 1 then
- local team = getteam(player)
- if team == zombie_team then
- response = 0
- end
- end
- return response
- end
- function OnVehicleEject(player, forceEject)
- return 1
- end
- -- Called when damage is being done to an object.
- -- This doesn't always need to be a player.
- -- Do not return a value
- function OnDamageLookup(receiving_obj, causing_obj, tagdata, tagname)
- -- Resolve the object ids into player ids
- -- Remember, the damage doesn't always need to be done by a player.
- local receiver = objecttoplayer(receiving_obj)
- local causer = objecttoplayer(causing_obj)
- -- We want to amplify human damage, so make sure the causer is human
- if causer ~= nil then
- local c_team = getteam(causer)
- -- Make sure the team was found
- if c_team ~= nil then
- -- Check if it's a human causing the damage
- if c_team == human_team then
- -- It's human damage, read the current damage the weapon has
- local min_dmg = readfloat(tagdata, 0x1D0)
- local max_dmg_min = readfloat(tagdata, 0x1D4)
- local max_dmg_max = readfloat(tagdata, 0x1D8)
- -- This is used to increase human damage (for last man)
- local modifier = 1.0
- -- Check if we're up to last man
- if cur_last_man ~= nil then
- -- Change the damage modifier to the last man's
- modifier = lastman_dmgmodifier
- end
- -- Change the damage that will be done
- writefloat(tagdata, 0x1D0, min_dmg * 2 * modifier)
- writefloat(tagdata, 0x1D4, max_dmg_min * 2 * modifier)
- writefloat(tagdata, 0x1D8, max_dmg_max * 2 * modifier)
- -- It's a zombie causing the damage
- elseif c_team == zombie_team then
- -- check if it is melee damage, if so increase it to instant kill
- local found = string.find(tagname, "melee", -5)
- -- We only want to increase zombie's melee damage
- if found ~= nil then
- -- make melee instant kill
- writefloat(tagdata, 0x1D0, 500)
- writefloat(tagdata, 0x1D4, 500)
- writefloat(tagdata, 0x1D8, 500)
- end
- end
- end
- end
- end
- -- Called when a player is being assigned a weapon (usually when they spawn)
- -- A value must be returned. The return value is the id of the weapon they're to spawn with. Return zero if the weapon shouldn't change.
- -- Notes: This is called for all weapon spawns the player has
- -- This is also called with player 255 when vehicles are being assigned weapons.
- -- This is only considered if in gametype, the weapon set is 'generic' if not this has no effect.
- function OnWeaponAssignment(player, object, count, tag)
- local actualWeapon = 0
- local team = getteam(player)
- local weapons = {"weapons\\assault rifle\\assault rifle", "weapons\\shotgun\\shotgun", "weapons\\pistol\\pistol", "weapons\\sniper rifle\\sniper rifle"}
- if team == zombie_team then
- local rand = getrandomnumber(1, #weapons + 1)
- actualWeapon = lookuptag("weap", weapons[rand])
- end
- return actualWeapon
- end
- function readtagname(address)
- local char_table = {}
- local i = 0
- local string = ""
- while readbyte(address, i) ~= 0 do
- table.insert(char_table, string.char(readbyte(address, i)))
- i = i + 1
- end
- for k,v in pairs(char_table) do
- string = string .. v
- end
- return string
- end
- -- Called when an object is created
- -- Do not return a value.
- function OnObjectCreation(m_objectId, player_owner, tag)
- if tag == "weapons\\ball\\ball" then
- table.insert(balls, m_objectId)
- elseif tag == "weapons\\rocket launcher\\rocket launcher" or tag == "weapons\\plasma_cannon\\plasma_cannon" or tag == "weapons\\flamethrower\\flamethrower" then
- registertimer(10, "DeleteHeavies", m_objectId)
- end
- end
- function DeleteHeavies(id, count, m_objId)
- destroyobject(m_objId)
- return 0
- end
- -- The below functions are used internally within the Lua script
- function NewGameTimer(id, count)
- if count == 5 then
- say("The game is starting...")
- if cur_players ~= 0 then
- local newgame_zombie_count = 0
- -- by default make all players human
- for x=0,15 do
- local thisTeam = getteam(x)
- local hash = gethash(x)
- if thisTeam ~= nil then
- if thisTeam == zombie_team then
- changeteam(x, 0)
- end
- human_time[hash] = 0
- end
- end
- local possible_count = cur_players
- -- make players zombie until the count has been met
- local finalZombies = 0
- if zombie_count >= 1 then
- finalZombies = zombie_count
- else
- finalZombies = round((possible_count * zombie_count) + 0.5)
- end
- -- make last man zombie
- local last_man_index = -1
- -- check if the last man is to be made a zombie
- -- if so find who was last man
- if last_man_next_zombie == true and cur_players > 1 then
- -- loop through all hashes and check if any match the last man
- for i=0,15 do
- local hash = gethash(i)
- if getplayer(i) ~= nil then
- if last_man_hash == hash then
- -- make them a zombie and save their info
- makezombie(i, true)
- newgame_zombie_count = 1
- last_man_index = i
- break
- end
- end
- end
- end
- -- reset last man
- last_man_hash = 0
- --hprintf("Expecting " .. finalZombies .. " zombies. Cur players " .. cur_players .. " possibles " .. possible_count)
- if finalZombies == cur_players then -- if 0 players they will be human
- finalZombies = finalZombies - 1
- elseif finalZombies > possible_count then -- fix the count
- finalZombies = possible_count
- elseif max_zombie_count ~= nil and finalZombies > max_zombie_count then -- cap the zombie count
- finalZombies = max_zombie_count
- elseif finalZombies < 0 then
- finalZombies = 0
- end
- -- set counters such that changeteam wont end the game
- cur_zombie_count = 16
- cur_human_count = 16
- --hprintf("Expecting " .. finalZombies .. " zombies. Cur players " .. cur_players .. " possibles " .. possible_count)
- -- loop through the players, randomly selecting ones to become
- -- zombies
- while (newgame_zombie_count < finalZombies) do
- -- randomly choose a player
- local newzomb = ChooseRandomPlayer(zombie_team)
- if newzomb == nil then
- break
- elseif newzomb ~= last_man_index then
- makezombie(newzomb, true)
- newgame_zombie_count = newgame_zombie_count + 1
- end
- end
- -- fix the team counters
- cur_zombie_count = newgame_zombie_count
- cur_human_count = cur_players - finalZombies
- -- reset the map
- svcmd("sv_map_reset")
- -- loop through and tell players which team they're on
- for i=0,15 do
- local pteam = getteam(i)
- if pteam ~= nil then
- -- check if they're a zombie
- if pteam == zombie_team then
- privatesay(i, zombie_message)
- else
- privatesay(i, human_message)
- end
- end
- end
- end
- game_started = true
- return 0 -- remove timer
- else
- say("The game will start in " .. 10 - 2*count .. " seconds.")
- return 1 -- keep timer
- end
- end
- function PlayerChangeTimer(id, count)
- if count ~= 10 then
- local zombsize = cur_zombie_count
- if allow_change == false or zombsize > 0 then
- allow_change = false
- say("Thank you, the game can continue.")
- return 0
- end
- say("In " .. 10 - count .. " seconds a player will be forced to become a zombie.")
- return 1
- else -- timer up, force team change
- allow_change = false
- -- pick a human and make them zombie.
- local newZomb = ChooseRandomPlayer(zombie_team)
- if newZomb ~= nil then
- makezombie(newZomb, true)
- privatesay(player, zombie_message)
- end
- return 0
- end
- end
- -- this function searches through current players and selects a random one
- function ChooseRandomPlayer(excludeTeam)
- local t = {}
- -- loop through all 16 possible spots and add to table
- for i=0,15 do
- -- check if the player exists
- local team = getteam(i)
- if team ~= nil and team ~= excludeTeam then
- table.insert(t, i)
- end
- end
- if #t > 0 then
- -- generate a random number that we will use to select a player
- local tableCount = table.getn(t)
- local r = getrandomnumber(1, tableCount+1)
- return t[r]
- else
- return nil
- end
- end
- function RemoveLastmanProtection(id, count, m_object)
- writebit(m_object, 0x10, 7, 0)
- return 0
- end
- -- there are no zombies left
- function noZombiesLeft()
- allow_change = true
- say("There are no zombies left. Someone needs to change team, otherwise a random player will be forced to.")
- player_change_timer = registertimer(1000, "PlayerChangeTimer")
- end
- -- called when its the last man
- function onlastman()
- -- lookup the last man
- for x=0,15 do
- local team = getteam(x)
- if team == human_team then
- cur_last_man = x
- -- give the last man speed and extra ammo
- setspeed(x, lastman_speed)
- -- find the last man's weapons
- local m_player = getplayer(x)
- if m_player ~= nil then
- local m_ObjId = readdword(m_player, 0x34)
- -- find the player's object
- local m_object = getobject(m_ObjId)
- if m_object ~= nil then
- if lastman_invulnerable ~= nil and lastman_invulnerable > 0 then
- -- setup the invulnerable timer
- writebit(m_object, 0x10, 7, 1)
- registertimer(lastman_invulnerable * 1000, "RemoveLastmanProtection", m_object)
- end
- -- give all weapons 600 ammo
- for i=0,3 do
- local m_weaponId = readdword(m_object, 0x2F8 + (i*4))
- if m_weaponId ~= 0xffffffff then
- -- get the weapons memory address
- local m_weapon = getobject(m_weaponId)
- if m_weapon ~= nil then
- -- set the ammo
- writeword(m_weapon, 0x2B6, 600)
- end
- end
- end
- end
- end
- end
- end
- if cur_last_man ~= nil then
- local lastman_name = getname(cur_last_man)
- local msg = string.format("%s is the last man alive and is invisible for %.0f seconds!", lastman_name, lastman_invistime)
- say(msg)
- applycamo(cur_last_man, lastman_invistime)
- end
- end
- -- checks the game state, for last man, all zombies etc
- -- called onteamchange, player join and leave
- function checkgamestate(player)
- -- check if the game has started yet
- if game_started == true then
- local zombie_count = cur_zombie_count
- local human_count = cur_human_count
- --hprintf("zombie count " .. zombie_count)
- --hprintf("human count " .. human_count)
- -- if no humans, but there are zombies, end the game
- if human_count == 0 and zombie_count > 0 then
- all_players_zombies(player)
- elseif human_count > 1 and zombie_count == 0 then
- noZombiesLeft()
- elseif human_count == 1 and zombie_count > 0 and cur_last_man == nil then
- onlastman()
- elseif cur_last_man ~= nil and zombie_count == 0 then
- makehuman(cur_last_man, false)
- cur_last_man = nil
- end
- end
- end
- -- called when all players are zombies (no shit)
- function all_players_zombies(player)
- -- if there is a last man, store their hash
- if player ~= -1 then
- last_man_hash = gethash(player)
- -- write the hash to file
- local file = io.open("lasthash_" .. processid .. ".tmp", "w")
- if (file ~= nil) then
- file:write(last_man_hash)
- file:close()
- end
- end
- -- move onto the next map
- svcmd("sv_map_next")
- end
- function makezombie(player, forcekill)
- -- change the player's speed
- setspeed(player, zombie_speed)
- local team = getteam(player)
- if team == human_team then
- changeteam(player, forcekill)
- end
- end
- function makehuman(player, forcekill)
- -- change the player's speed
- setspeed(player, human_speed)
- local team = getteam(player)
- if team == zombie_team then
- changeteam(player, forcekill)
- end
- end
- function getalphacount()
- -- recalculate how many "alpha" zombies there are
- if zombie_count < 1 then
- alpha_zombie_count = round((cur_players * zombie_count) + 0.5)
- else
- alpha_zombie_count = zombie_count
- end
- if alpha_zombie_count > max_zombie_count then
- alpha_zombie_count = max_zombie_count
- end
- return alpha_zombie_count
- end
- function round(num)
- under = math.floor(num)
- upper = math.floor(num) + 1
- underV = -(under - num)
- upperV = upper - num
- if (upperV > underV) then
- return under
- else
- return upper
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement