--- [[[ Zombie Zone Script ]]] ------ [[ Map Of Stored Stats ]] ----- 0 - Zombie Kills-- 1 - Marine Kills-- 2 - Zombie Deaths-- 3 - Zombie Kill Record-- 4 - Marine Kill Record-- 5 - Zombie Death Record-- 6 - Teamkills-- 7 - Turrets Built-- 8 - Turrets Destroyed--- [[ Map Of User Stats ]] ----- 0 - Zombie kills - The amount of zombies that the player has killed as a marine-- 1 - Marine kills - The amount of marines player has killed as a zombie-- 2 - Zombie Deaths - The amount of deaths that the player has suffered as a zombie-- 3 - Ammo Used - The amount of ammo the player has used up-- 4 - Teamkills - The amount of teamkills the marine has 'achieved' :)-- 5 - Corsplosions - The amount of corpses the zombie has nuked-- 6 - Medicated - How many medikits has the marine had?-- 7 - Ammo Scavenged - How much ammo has the marine scavenged?-- 8 - Resurrections - How many resurrections has the player made?-- 9 - Picked? - Has the marine already been picked for a group?-- 10 - Turrets Built - The amount of turrets built by the engineer-- 11 - Walls Built - The amount of walls built by the engineer-- 12 - Turrets Destroyed - The amount of turrets the zombie has killed-- == Freeze/Phase stats-- 50 - Previous Type - The type of zombie that they were previously--- [[ Constants ]] ------gc_startingammo = 250 -- The amount of ammo the marine starts withgc_mapcenterx = 5032 -- The center of the map along the x axisgc_mapcentery = 2280 -- The center of the map along the y axis--- [[ Globals ]] --------g_state = nil -- The global GameState classg_arena = nil -- The global arena class, to avoid having to pass it around functionsg_bGameRunning = false -- Is the game running?g_winner = nil -- The player who wong_winnerevent = 0 -- The eventid for the repeating winner eventg_supplyevent = 0 -- The eventid for dropping suppliesg_roundnum = 0 -- The round we are currently on (Defined by supply drops)g_groupsize = 0 -- The amount of people per marine groupg_lastworthy = nil -- The last marine to die who was worthy of a win--- [[ Other Functions ]] ----- SupplySpawn = For creating a supply drop at a random location on the mapfunction SupplySpawn(ev) -- Get a hold on the marines team local marineteam = team_fromname(g_arena, "Marines") if (marineteam:exists() == false) then -- Forget it return end -- Increase the round g_roundnum = g_roundnum + 1 -- Calculate the random coordinates to spawn the supplies local randx = gc_mapcenterx + math.random(-gc_mapcenterx, gc_mapcenterx) local randy = gc_mapcentery + math.random(-gc_mapcentery, gc_mapcentery) -- Create some ammo based on how many marines are left local ammoamount = (marineteam:num() + 1) * gc_startingammo -- Spawn it at the location g_arena:item_create("Ammo", ammoamount, randx, randy) -- Create a medikit for each marine local medikitamount = marineteam:num() g_arena:item_create("Medikit", medikitamount, randx + 50, randy) -- Give 'em a plasma turret and some walls too g_arena:item_create("Plasma Turret Kit", 1, randx + 100, randy) g_arena:item_create("Wall Kit", 10, randx + 150, randy) -- Convert the coordinates local lettercoord = "A" randx = math.floor((randx / 80) / 16) randy = ((randy / 80) / 16) + 1 if (randx == 0) then lettercoord = "A" elseif (randx == 1) then lettercoord = "B" elseif (randx == 2) then lettercoord = "C" elseif (randx == 3) then lettercoord = "D" elseif (randx == 4) then lettercoord = "E" else lettercoord = "F" end -- Inform the players g_arena:message("!There has been a supply drop at " .. lettercoord .. math.floor(randy) .. "!")end-- SetupEngineer = Give the engineer his suppliesfunction SetupEngineer(engy) -- Determine the type of items he should have local turrettype = "Plasma Turret Kit" local walltype = "Wall Kit" -- If he has the Skilled Constructor skill if (engy:skill_find(45) == true) then -- Upgrade his stuff turrettype = "Improved Plasma Turret Kit" walltype = "Enhanced Wall Kit" end -- Give him a few turrets to place engy:inventory_modify(turrettype, 2) -- If he's got the Agoraphobic skill, give him a few extra walls local Agoraphobic = 0 if (engy:skill_find(40) == true) then Agoraphobic = 10 end engy:inventory_modify(walltype, 10 + Agoraphobic)end-- ChooseZombie = For randomly choosing a zombie type function ChooseZombie(zombie) -- We want to randomly choose a zombie type to use local rand = math.random(1, 112) if (rand < 32) then zombie:setVehicle(100) -- Normal Zombie elseif (rand < 54) then zombie:setVehicle(103) -- Alien Zombie elseif (rand < 75) then zombie:setVehicle(102) -- Flesh Zombie elseif (rand < 87) then zombie:setVehicle(101) -- Assassin Zombie elseif (rand < 95) then zombie:setVehicle(105) -- Devourer Zombie elseif (rand < 105) then zombie:inventory_modify("Crystals", 100) zombie:setVehicle(110) -- Wraith Zombie else -- Tell arena! Tough zombie g_arena:message(zombie.m_name .. " has spawned as a super-zombie!") zombie:setVehicle(104) -- Tough Zombie endend-- Conviscate = Conviscates all illegal starting items from the marinefunction Conviscate(marine) marine:inventory_modify("Improved Plasma Turret Kit", -1000) marine:inventory_modify("Enhanced Wall Kit", -1000) marine:inventory_modify("Plasma Turret Kit", -1000) marine:inventory_modify("Wall Kit", -1000) marine:inventory_modify("Laboratory Kit", -1000) marine:inventory_modify("Ammo", -30000) marine:inventory_modify("Ammo", gc_startingammo) marine:inventory_modify("Medikit", -30000) marine:inventory_modify("Zombie Parts", -30000) marine:inventory_modify("Marine Parts", -30000) marine:inventory_modify("Invite", -1000) marine:inventory_modify("Crystals", -1000) -- Prized weaponry marine:inventory_modify("Incinerator", -100)end-- ChooseMarine = Sets the appropriate class for the marinefunction ChooseMarine(marine) -- Differ our actions depending on what class the marine is -- Remove any illegal items and reset their ammo Conviscate(marine) -- If he's sensible, give him his kit if (marine:skill_find(44) == true) then marine:inventory_modify("Medikit", 1) end -- Find out how experienced he is local vehicletype = 10 if (marine:skill_find(13) == true) then vehicletype = 13 elseif (marine:skill_find(12) == true) then vehicletype = 12 elseif (marine:skill_find(11) == true) then vehicletype = 11 end -- Make him a marine marine:team_change("Marines", "") marine:setVehicle(vehicletype)end-- Fireworks = For creating celebration explosions around the player :Dfunction Fireworks(eventid) -- Create an explosion randomly around the player local c = g_winner:coords() g_arena:explosion_create("GG Explode", c.x + math.random(-60, 60), c.y + math.random(-60, 60), c.rotation)end-- CalculateReward = Calculates the reward for the specified playerfunction CalculateReward(marine) -- Start calculating! local reward = 0 -- Players should get exponentially more for their kills reward = reward + (math.pow(marine:getstat(0), 2) * 15) -- Zombie kills reward = reward + (math.pow(marine:getstat(1), 2) * 20) -- Marine kills reward = reward + (math.pow(marine:getstat(2), 2) * 2) -- Zombie Deaths reward = reward + (marine:getstat(8) * 75) -- Resurrections reward = reward + math.pow(marine:getstat(5), 2.5) -- Corsplosions -- Engineers should get rewards for building stuff reward = reward + (marine:getstat(10) * 25) -- 25 exp for each turret reward = reward + (marine:getstat(11) * 3) -- 3 exp for each wall -- Zombies should get rewards for killing stuff reward = reward + (math.pow(marine:getstat(12), 2) * 15) -- Was he the winner? if (g_winner ~= nil) then if (marine == g_winner) then -- Add to his reward based on the people playing reward = reward + (g_arena:numplaying() * 15) end end -- Adjust the reward for the arena size reward = reward * (g_arena:numplaying() / 50) -- Round it off return math.floor(reward)end-- ReportStats = For reporting the end-game statisticsfunction ReportStats() -- Gather and report statistics if (g_winner ~= nil) then if (g_winner:valid() == true) then g_arena:message("!Victory: " .. g_winner.m_name) else g_arena:message("!Victory: Nobody!") end else g_arena:message("!Victory: Nobody!") end -- Award local variables local stubplayer = g_arena:get(1) -- Grab the first player for initial comparisons if (stubplayer:spectator() == true) then -- If he's in spec, we don't want him to win anything stubplayer:clearstats() end local awd_zombiekills = stubplayer local awd_marinekills = stubplayer local awd_zombiedeaths = stubplayer local awd_ammoused = stubplayer local awd_teamkills = stubplayer local awd_corsplosions = stubplayer local awd_medicated = stubplayer local awd_resurrect = stubplayer local awd_razed = stubplayer -- Iterate through players and report personal statistics for x = 1, g_arena:num() do local plyr = g_arena:get(x) -- Only take into account players that aren't spectating if (plyr:spectator() == false) then -- Compare zombie kills if (plyr:getstat(0) > awd_zombiekills:getstat(0)) then awd_zombiekills = plyr end -- Compare marine kills if (plyr:getstat(1) > awd_marinekills:getstat(1)) then awd_marinekills = plyr end -- Compare zombie deaths if (plyr:getstat(2) > awd_zombiedeaths:getstat(2)) then awd_zombiedeaths = plyr end -- Calculate ammo used plyr:setstat(3, plyr:getstat(3) - plyr:inventory_find("Ammo")) if (plyr:getstat(3) > awd_ammoused:getstat(3)) then awd_ammoused = plyr end -- Compare teamkills if (plyr:getstat(4) > awd_teamkills:getstat(4)) then awd_teamkills = plyr end -- Compare corsplosions! :D if (plyr:getstat(5) > awd_corsplosions:getstat(5)) then awd_corsplosions = plyr end -- Calculate/Compare medication plyr:setstat(6, plyr:getstat(6) - plyr:inventory_find("Medikit")) if (plyr:getstat(6) > awd_corsplosions:getstat(6)) then awd_medicated = plyr end -- Compare players resurrected if (plyr:getstat(8) > awd_resurrect:getstat(8)) then awd_resurrect = plyr end -- Compare razings if (plyr:getstat(12) > awd_razed:getstat(12)) then awd_razed = plyr end -- Show player his personal stats plyr:message("@PERSONAL STATS: Zombie Kills=" .. plyr:getstat(0) .. " Marine Kills=" .. plyr:getstat(1) .. " Zombie Deaths=" .. plyr:getstat(2)) plyr:message("@PERSONAL STATS: Ammo Spent=" .. plyr:getstat(3) .. " Teamkills=" .. plyr:getstat(4) .. " Corsplosions!=" .. plyr:getstat(5)) plyr:message("@PERSONAL STATS: Medication Used=" .. plyr:getstat(6) .. " Resurrections Made=" .. plyr:getstat(8) .. " Structures Demolished=" .. plyr:getstat(12)) -- Calculate the player's reward local reward = CalculateReward(plyr) plyr:message("&PERSONAL REWARD: Points=" .. (reward * 2) .. " Cash=" .. (reward * 2) .. " Experience=" .. reward) plyr:modpoints(reward * 2) plyr:modcash(reward * 2) plyr:modexperience(reward) -- Update the player's stored statistics plyr:setpersiststat(0, plyr:getpersiststat(0) + plyr:getstat(0)) plyr:setpersiststat(1, plyr:getpersiststat(1) + plyr:getstat(1)) plyr:setpersiststat(2, plyr:getpersiststat(2) + plyr:getstat(2)) if (plyr:getpersiststat(3) < plyr:getstat(0)) then plyr:setpersiststat(3, plyr:getstat(0)) end if (plyr:getpersiststat(4) < plyr:getstat(1)) then plyr:setpersiststat(4, plyr:getstat(1)) end if (plyr:getpersiststat(5) < plyr:getstat(2)) then plyr:setpersiststat(5, plyr:getstat(2)) end plyr:setpersiststat(6, plyr:getpersiststat(6) + plyr:getstat(4)) plyr:setpersiststat(7, plyr:getpersiststat(7) + plyr:getstat(10)) plyr:setpersiststat(8, plyr:getpersiststat(8) + plyr:getstat(12)) end end -- Then report the awards g_arena:message("&Awards:") g_arena:message("~- Zombie Kills (" .. awd_zombiekills:getstat(0) .. "): " .. awd_zombiekills.m_name) g_arena:message("~- Marine Kills (" .. awd_marinekills:getstat(1) .. "): " .. awd_marinekills.m_name) g_arena:message("~- Most Suicidal Zombie (" .. awd_zombiedeaths:getstat(2) .. "): " .. awd_zombiedeaths.m_name) g_arena:message("~- Trigger Happy (" .. awd_ammoused:getstat(3) .. "): " .. awd_ammoused.m_name) g_arena:message("~- Teamkills (" .. awd_teamkills:getstat(4) .. "): " .. awd_teamkills.m_name) g_arena:message("~- Most Corsplosions (" .. awd_corsplosions:getstat(5) .. "): " .. awd_corsplosions.m_name) g_arena:message("~- Most High (" .. awd_medicated:getstat(6) .. "): " .. awd_medicated.m_name) g_arena:message("~- Resurrections (" .. awd_resurrect:getstat(8) .. "): " .. awd_resurrect.m_name) g_arena:message("~- Structures razed (" .. awd_razed:getstat(12) .. "): " .. awd_razed.m_name)end---------------------------------------------------------------------------------------------------------------------------------------------------------------------- [[ Event Functions ]] -----------------------------------------------------------------------------------------------function Laboratory_Produce(lab, chemist, menuitem) -- Action taken differs on what the player is trying to do -- Scavenge Ammo = Attempts to create some ammo if (menuitem == 0) then -- Check if he's waited long enough to create more ammo if (chemist:getstat(7) >= g_roundnum) then chemist:message("You look around, but don't see any spare parts available.") return false end -- Increase his 'attempt' count chemist:setstat(7, chemist:getstat(7) + 1) -- He may randomly fail if (math.random(0, 100) > 50) then chemist:message("Due to your inept handling you fail to create ammo and mess up the spare parts.") return false else -- Give the guy some ammo chemist:message("You have successfully created some ammo!") chemist:inventory_modify("Ammo", 25) return false end end return trueendfunction Vehicle_OnProduce(producer, user, menuitem) -- Divert to the appropriate function depending on what's producing -- Laboratory? if (producer:vehicletypeid() == 400) then local retval = Laboratory_Produce(producer, user, menuitem) return retval end return trueendfunction Vehicle_OnDeath(victim, killer, itemid) local vid = victim:vehicletypeid() -- Check if the dead vehicle is a corpse if (vid == 300) then -- Reward the killer with a corsplosion! if (killer:valid() == true) then killer:setstat(5, killer:getstat(5) + 1) end -- Check if the itemid is the ressurection item if (itemid == 2016) then -- We get to resurrect the player! :) -- Attempt to find the player that the corpse references local repplayer = victim:getvar("Represents") local deadplayer = g_arena:getPlayer(repplayer) local oldvehicle = victim:getvarint("OldVehicle") -- Check to see if he exists if (deadplayer:valid() == false) then -- If he doesn't, give the chemist his kit back killer:inventory_modify("Resurrection Kit", 1) -- Tell him killer:message("The corpse has degraded too far to be revived.") killer:message("You gather your kit back and move on.") else -- Change him back into a marine! deadplayer:team_change("Marines", "") deadplayer:setVehicle(oldvehicle) -- warp him to the corpse's location local corpseloc = victim:coords() deadplayer:resurrect_warp(corpseloc.x, corpseloc.y, 0) -- Notify him deadplayer:message("&You have been revived by " .. killer.m_name .. "!") -- Give the player a resurrection stat killer:setstat(8, killer:getstat(8) + 1) end end -- Is it a turret? elseif (vid == 108) or (vid == 201) or (vid == 300) then -- If he's a zombie (prevent abuse) if (killer:getVehicle():vehicletypeid() < 30) then -- Increase his turret kills killer:setstat(12, killer:getstat(12) + 1) end endendfunction Item_OnPickUp(looter, loot, loot_type, amounttopickup) -- If he picked up an engineer kit if (loot_type.m_name == "Engineer Kit") then -- Player needs to be a marine, and only picking up one kit if (amounttopickup > 1) then looter:message("You are only allowed one engineer kit.") return false elseif (looter:getVehicle():vehicletypeid() >= 15) then looter:message("You need to be a marine to become an engineer.") return false end -- Find out how experienced he is local vehicletype = 15 if (looter:skill_find(13) == true) then vehicletype = 18 elseif (looter:skill_find(12) == true) then vehicletype = 17 elseif (looter:skill_find(11) == true) then vehicletype = 16 end -- Otherwise, we want to make him an engineer. :) looter:setVehicle(vehicletype) -- Gear him up SetupEngineer(looter) -- Now we want to destroy the item local itmstruct = loot:get_struct() if (itmstruct.amount == 1) then loot:destroy() else itmstruct.amount = itmstruct.amount - 1 loot:update() end return false ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Heavy Marine Kit") then -- Player needs to be a marine, and only picking up one kit if (amounttopickup > 1) then looter:message("You are only allowed one heavy marine kit.") return false elseif (looter:getVehicle():vehicletypeid() >= 15) then looter:message("You need to be a marine to become a heavy marine.") return false end -- Find out how experienced he is local vehicletype = 20 if (looter:skill_find(13) == true) then vehicletype = 23 elseif (looter:skill_find(12) == true) then vehicletype = 22 elseif (looter:skill_find(11) == true) then vehicletype = 21 end -- Otherwise, we want to make him a heavy. :) looter:setVehicle(vehicletype) -- Now we want to destroy the item local itmstruct = loot:get_struct() if (itmstruct.amount == 1) then loot:destroy() else itmstruct.amount = itmstruct.amount - 1 loot:update() end return false ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Chemist Kit") then -- Player needs to be a marine, and only picking up one kit if (amounttopickup > 1) then looter:message("You are only allowed one chemist kit.") return false elseif (looter:getVehicle():vehicletypeid() >= 15) then looter:message("You need to be a marine to become a chemist.") return false end -- Give him a laboratory kit looter:inventory_modify("Laboratory Kit", 1) -- How prepared is he? if (looter:skill_find(48) == true) then -- Give him a marine part looter:inventory_modify("Marine Parts", 1) end if (looter:skill_find(47) == true) then -- Give him some zombie parts looter:inventory_modify("Zombie Parts", 3) end -- Is he a lifesaver? if (looter:skill_find(49) == true) then -- Give him a resurrection kit looter:inventory_modify("Resurrection Kit", 1) end -- Find out how experienced he is local vehicletype = 25 if (looter:skill_find(13) == true) then vehicletype = 28 elseif (looter:skill_find(12) == true) then vehicletype = 27 elseif (looter:skill_find(11) == true) then vehicletype = 26 end -- Otherwise, we want to make him a chemist. :) looter:setVehicle(vehicletype) -- Now we want to destroy the item local itmstruct = loot:get_struct() if (itmstruct.amount == 1) then loot:destroy() else itmstruct.amount = itmstruct.amount - 1 loot:update() end return false ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Ammo") then -- Don't let zombies pick up ammo if (looter:getVehicle():vehicletypeid() >= 100) then looter:message("Zombies have no use for ammo.") return false end -- Constrict the amount of ammo you can pick up local amountpermitted = gc_startingammo - looter:inventory_find("Ammo") if (amounttopickup > amountpermitted) then looter:message("You can't eat the ammo.") return false end -- Add to the player's ammo count looter:setstat(3, looter:getstat(3) + amounttopickup) ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Medikit") then -- Don't let zombies pick up medikits if (looter:getVehicle():vehicletypeid() >= 100) then looter:message("Thief. That's for the marines.") return false end -- Has the player had enough medication for now? if (looter:getstat(6) < g_roundnum + 1) then -- Give this man his kit! -- .. if he's not being greedy if (amounttopickup > 1) then -- Tell him and refuse the request looter:message("You can only grab one medikit at a time.") return false end -- Increase his medication looter:setstat(6, looter:getstat(6) + 1) return true else -- He's not allowed anymore until the next supply drop looter:message("You've had your medication for this drop!") return false end ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Plasma Turret Kit") or (loot_type.m_name == "Wall Kit") then -- Check to see if he's an engineer local vehicletypeid = looter:getVehicle():vehicletypeid() if (vehicletypeid < 15) or (vehicletypeid > 18) then looter:message("You can't use that.") return false end ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Improved Plasma Turret Kit") or (loot_type.m_name == "Enhanced Wall Kit") then -- Check to see if he's an engineer local vehicletypeid = looter:getVehicle():vehicletypeid() if (vehicletypeid < 15) or (vehicletypeid > 18) then looter:message("You can't use that.") return false end ----------------------------------------------------------------------------------- elseif (loot_type.m_name == "Zombie Parts") or (loot_type.m_name == "Marine Parts") then local vehicletypeid = looter:getVehicle():vehicletypeid() if (vehicletypeid < 25) or (vehicletypeid > 28) then looter:message("You should leave these for chemists.") return false end end return trueendfunction Arena_OnCreate(arena) -- Set our global value g_arena = arena -- Initialize random math.randomseed(os.time()) -- Use our own game dynamic local cfg = GameSettings() cfg.minplayers = 6 cfg.gamedelay = 40 cfg.str_pregame = "Game starting in " cfg.str_noplayers = "Not Enough Zombiefood" cfg.bDesertedGameEnd = false cfg.bIngameTicker = true cfg.tckrUpdateSpacing = 10000 g_state = g_arena:Takeover_State(cfg)endfunction Arena_OnGameStart() -- Destroy the celebration event and all phase events, etc event_flush(g_arena) g_winner = nil -- Set the supply event in motion g_supplyevent = event_create(SupplySpawn, -60000, g_arena) -- Every 1.5 minutes -- Set variables g_bGameRunning = true g_roundnum = 0 -- Turn everyone into marines for x = 1, g_arena:num() do local marine = g_arena:get(x) -- If they're not in spec if marine:spectator() == false then -- Set him up ChooseMarine(marine) end end -- Perform some calculations for the type of game we want local arenaplaying = g_arena:numplaying() local amount = math.floor(math.max((arenaplaying / 5), 1)) -- First, search for professional zombies for x = 1, g_arena:num() do local marine = g_arena:get(x) -- Reset their stats while we're walking through the playerlist marine:clearstats() marine:setstat(3, gc_startingammo) -- Are they a Professional Zombie? (And not in spec) if (marine:skill_find(200) == true) and (marine:spectator() == false) then -- Turn him! marine:team_change("Zombie Horde", "") ChooseZombie(marine) -- Warp zombies anywhere marine:warp(gc_mapcenterx, gc_mapcentery, gc_mapcentery*2) -- Decrease the number of zombies we need amount = amount - 1 -- He has been picked marine:setstat(9, 1) -- Check to see if we have enough if (amount <= 0) then break end end end -- Locate the player ids which we will turn to zombies local numplayers = g_arena:num() for x = 1, amount do local zombie = g_arena:get(math.random(1, numplayers)) -- If he's not in spec and not already a zombie if (zombie:spectator() == false) and (zombie:getVehicle():vehicletypeid() < 100) then -- Turn him zombie:team_change("Zombie Horde", "") ChooseZombie(zombie) -- He has been picked zombie:setstat(9, 1) -- Warp zombies anywhere zombie:warp(gc_mapcenterx, gc_mapcentery, gc_mapcentery*2) else -- We'll have to try again x = x - 1 end end -- Start putting together the marine team local marineteam = team_fromname(g_arena, "Marines") if (marineteam:exists() == false) then return end -- Calculate how many groups we want local marinesinplay = marineteam:numplaying() if (marinesinplay < 5) then g_arena:message("&Not enough players (6) to commence a full game."); return end g_groupsize = 5 local numgroups = math.floor(marinesinplay / g_groupsize) local leftover = math.mod(marinesinplay, numgroups) local leftOversPerGroup = math.floor(leftover / numgroups) -- Start creating the groups.. for x = 1, numgroups do -- Pick x random marines to add to the group local teammarines = {} local teamsize = 0 for i = 1, g_groupsize do -- Randomly pick a marine local marine = marineteam:get(math.random(1, marineteam:num())) -- If he's in spec or already picked, we'll have to try picking again if (marine:spectator() == true) or (marine:getstat(9) ~= 0) then -- We'll have to try again i = i - 1 else -- Otherwise, he'll do. Add him to the array teammarines[i] = marine teamsize = teamsize + 1 -- Flag him as picked marine:setstat(9, 1) end end -- Deal with the leftover players for n = 1, leftOversPerGroup do -- Randomly pick a marine local marine = marineteam:get(math.random(1, marineteam:num())) -- If he's in spec or already picked, we'll have to try picking again if (marine:spectator() == true) or (marine:getstat(9) ~= 0) then -- We'll have to try again i = i - 1 else -- Otherwise, he'll do. Add him to the array teammarines[teamsize + 1] = marine teamsize = teamsize + 1 -- Flag him as picked marine:setstat(9, 1) end end -- If this is the last group to be created.. if (x == numgroups) then -- We want to make sure that no leftovers are left for x = 1, g_arena:num() do local marine = g_arena:get(x) -- If he is an eligible leftover.. if (marine:spectator() == false) and (marine:getstat(9) == 0) then -- Add him to the list too teammarines[teamsize + 1] = marine teamsize = teamsize + 1 end end end -- Calculate the random coordinates to spawn the marine group local randx = gc_mapcenterx + math.random(-gc_mapcenterx, gc_mapcenterx) local randy = gc_mapcentery + math.random(-gc_mapcentery, gc_mapcentery) while (g_arena:IsClear(randx, randy, 18) == false) do randx = gc_mapcenterx + math.random(-gc_mapcenterx, gc_mapcenterx) randy = gc_mapcentery + math.random(-gc_mapcentery, gc_mapcentery) end -- Spawn the marines local t = 1 while teammarines[t] do -- Set him up ChooseMarine(teammarines[t]) -- Warp them all to the starting point teammarines[t]:warp(randx, randy, 200) t = t + 1 end -- Now that the group is sorted, spawn their gear -- Create the initial defensive turret g_arena:vehicle_create(200, randx, randy, 0) -- Give them some kits -- Spawn a heavy marine kit for newbies to play with local itemrandx = math.random(-100, 100) local itemrandy = math.random(-100, 100) g_arena:item_create("Heavy Marine Kit", 1, randx + itemrandx, randy + itemrandy) -- .. and a chemist kit itemrandx = math.random(-100, 100) itemrandy = math.random(-100, 100) g_arena:item_create("Chemist Kit", 1, randx + itemrandx, randy + itemrandy) -- .. and an engineer kit itemrandx = math.random(-100, 100) itemrandy = math.random(-100, 100) g_arena:item_create("Engineer Kit", 1, randx + itemrandx, randy + itemrandy) -- Throw them a res kit too itemrandx = math.random(-100, 100) itemrandy = math.random(-100, 100) g_arena:item_create("Resurrection Kit", 1, randx + itemrandx, randy + itemrandy) -- If they're lucky, a freeze local chance = math.random(0, 100) if (chance > 70) then itemrandx = math.random(-100, 100) itemrandy = math.random(-100, 100) g_arena:item_create("Freeze", 1, randx + itemrandx, randy + itemrandy) end endendfunction Arena_OnGameEnd() -- Kill the supply event (and all others) event_flush(g_arena) -- Tell people to join the arena g_arena:message("Game is about to start. Enter the game now to play.") g_bGameRunning = false -- Show endgame stats ReportStats()endfunction Player_OnDeath(killer, victim) -- If the game isn't running, we don't want to do any of the other dynamics if g_bGameRunning == false then return end -- Check if the victim is a marine (isn't a zombie) if (victim:getVehicle():vehicletypeid() < 30) then -- Has there been a teamkill!? if (killer:getVehicle():vehicletypeid() < 30) then -- The killer is a marine too! Teamkill! killer:setstat(4, killer:getstat(4) + 1) elseif (killer:getVehicle():vehicletypeid() >= 100) then -- Otherwise, the killer is a zombie and we need to up his marine kills killer:setstat(1, killer:getstat(1) + 1) end -- Check if he has a preservation kit local pos = victim:coords() if (victim:inventory_find("Preservation Kit") >= 1) then -- Take his kit and res him victim:inventory_modify("Preservation Kit", -1) victim:resurrect() -- Make a nice res cloud on him g_arena:explosion_create("Resurrection Cloud", pos.x, pos.y, 0) return end -- First, we'll stick a corpse on top of him local corpse = g_arena:vehicle_create(300, pos.x, pos.y, pos.rotation) -- Issue details to the corpse corpse:setvar("Represents", victim.m_name) corpse:setvarint("OldVehicle", victim:getVehicle():vehicletypeid()) -- .. and marine parts g_arena:item_create("Marine Parts", 1, pos.x, pos.y) -- If he has the Bloody Mess skill make him explode if (victim:skill_find(41) == true) then g_arena:explosion_create("Super Body Explosion (M)", pos.x, pos.y, 0) end -- Remove any engineer items victim:inventory_modify("Plasma Turret Kit", -1000) victim:inventory_modify("Wall Kit", -1000) -- We want to turn the player into a zombie victim:team_change("Zombie Horde", "") ChooseZombie(victim) -- Check to see if the player is worthy if (victim:getstat(0) < 3) then g_lastworthy = victim end -- Are we down to one marine yet? local marineteam = team_fromname(g_arena, "Marines") if (marineteam:exists() == true) then -- Look to see how many players are actually left playing local nummarines = 0 local winner= nil for x = 1, marineteam:num() do if marineteam:get(x):spectator() == false then nummarines = nummarines + 1 winner = marineteam:get(x) end end -- If there is only one surviving marine if (nummarines == 1) then -- Does he qualify as a winner? if (winner:getstat(0) < 3) then g_arena:message(winner.m_name .. " was disqualified as winner for not killing enough zombies!") g_arena:message(g_lastworthy.m_name .. " takes his place!") -- Replace the winner and stick him on the marine team winner = g_lastworthy winner:team_change("Marines", "") end if (winner ~= nil) and (winner:valid() == true) then g_winner = winner -- Let him celebrate :) winner:setVehicle(50) winner:inventory_modify("Invite", 1) g_winnerevent = event_create(Fireworks, -750, g_arena) -- Break the news! g_arena:message(winner.m_name .. " was the last marine standing! Celebrate!") end -- End the game! g_state:Endgame() -- Grab the party animals local zombieteam = team_fromname(g_arena, "Zombie Horde") -- Look for party animals if (zombieteam:exists() == true) then for x = 1, zombieteam:num() do local zombie = zombieteam:get(x) -- You animal? if (zombie:skill_find(201) == true) then zombie:team_change("Marines", "") zombie:setVehicle(51) -- Animal vehicle end end end end end -- If the victim is a zombie elseif (victim:getVehicle():vehicletypeid() >= 100) then -- Check to see if he has the Detachable Head skill (and not already a head) if (victim:skill_find(82) == true) and (victim:getVehicle():vehicletypeid() ~= 109) then -- Roll the dice local chance = math.random(0, 100) if (chance > 70) then -- Turn him into a head victim:setVehicle(109) victim:resurrect() -- Make him spew zombie fx local pos = victim:coords() g_arena:explosion_create("Child - Zombie Roar", pos.x, pos.y, 0) end return end -- Make him a random class ChooseZombie(victim) -- Add one to his zombie deaths victim:setstat(2, victim:getstat(2) + 1) -- Spawn some zombie parts on his death-bed local pos = victim:coords() g_arena:item_create("Zombie Parts", 1, pos.x, pos.y) -- If the killer is a marine.. if (killer:getVehicle():vehicletypeid() < 15) then -- Get his zombie kills local zombiekills = killer:getstat(0) local zombievehicle = killer:getVehicle():vehicletypeid() zombiekills = zombiekills + 1 -- Is he ready for an upgrade? if (zombiekills == 2) and (zombievehicle == 10) then killer:setVehicle(11) elseif (zombiekills == 4) and (zombievehicle == 11) then killer:setVehicle(12) elseif (zombiekills == 6) and (Zombievehicle == 12) then killer:setVehicle(13) end killer:setstat(0, zombiekills) -- .. an engineer? elseif (killer:getVehicle():vehicletypeid() < 20) then -- Get his zombie kills local zombiekills = killer:getstat(0) local zombievehicle = killer:getVehicle():vehicletypeid() zombiekills = zombiekills + 1 -- Is he ready for an upgrade? if (zombiekills == 2) and (zombievehicle == 15) then killer:setVehicle(16) elseif (zombiekills == 4) and (zombievehicle == 16) then killer:setVehicle(17) elseif (zombiekills == 6) and (Zombievehicle == 17) then killer:setVehicle(18) end killer:setstat(0, zombiekills) -- .. a heavy? elseif (killer:getVehicle():vehicletypeid() < 25) then -- Get his zombie kills local zombiekills = killer:getstat(0) local zombievehicle = killer:getVehicle():vehicletypeid() zombiekills = zombiekills + 1 -- Is he ready for an upgrade? if (zombiekills == 2) and (zombievehicle == 20) then killer:setVehicle(21) elseif (zombiekills == 4) and (zombievehicle == 21) then killer:setVehicle(22) elseif (zombiekills == 6) and (Zombievehicle == 22) then killer:setVehicle(23) end killer:setstat(0, zombiekills) -- .. a chemist? elseif (killer:getVehicle():vehicletypeid() < 30) then -- Get his zombie kills local zombiekills = killer:getstat(0) local zombievehicle = killer:getVehicle():vehicletypeid() zombiekills = zombiekills + 1 -- Is he ready for an upgrade? if (zombiekills == 2) and (zombievehicle == 25) then killer:setVehicle(26) elseif (zombiekills == 4) and (zombievehicle == 26) then killer:setVehicle(27) elseif (zombiekills == 6) and (Zombievehicle == 27) then killer:setVehicle(28) end killer:setstat(0, zombiekills) end endendfunction Player_OnJoin(visitor) -- Give him information! :) visitor:message("&Note: This zone is essentially just a test of the server's new scripting capabilities.")endfunction Player_OnUnspec(visitor) -- Check if the game is in progress if (g_bGameRunning == true) then -- Remove illegal items Conviscate(visitor) -- Reset all his stats visitor:clearstats() visitor:setstat(3, gc_startingammo) -- We want to unspec the player into the zombie team visitor:unspec("Zombie Horde", "") ChooseZombie(visitor) -- Warp him anywhere visitor:warp(gc_mapcenterx, gc_mapcentery, gc_mapcenterx*2) -- Tell him why he spawned as a zombie visitor:message("&The game is already in progress so you have been spawned as a zombie.") -- Don't allow the typical game logic to take effect return false end -- Process as per normal return trueendfunction PhaseBack(playerbase) -- Obtain the player who needs to phase back local phased = player_frombase(playerbase) if (phased:valid() == true) then if (phased:getVehicle():vehicletypeid() == 111) then -- Make a phase explosion local c = phased:coords() g_arena:explosion_create("Child - Phase Out", c.x, c.y, 0) -- Phase him back phased:setVehicle(110) end endendfunction Unfreeze(playerbase) -- Obtain the player who needs to thaw local frozen = player_frombase(playerbase) if (frozen:valid() == true) then local vid = frozen:getstat(50) if (vid ~= 0) and (frozen:getVehicle():vehicletypeid() == 107) then -- Turn him back frozen:setVehicle(frozen:getstat(50)) frozen:setstat(50, 0) end endendfunction Player_OnWarpItem(user, itemid, target) ------------------------------------------------- Invite if (itemid == 24) then if (target:valid() == false) then user:message("Please select a valid player to invite.") user:inventory_modify("Invite", 1) return false end -- Make him a 'winner', he will be automatically warped to the user target:setVehicle(50) target:team_change("Marines", "") return true ------------------------------------------------- Phase elseif (itemid == 27) then -- Make a phase explosion local c = user:coords() g_arena:explosion_create("Child - Phase Out", c.x, c.y, 0) -- Change him to the phased vehicle user:setVehicle(111) -- Create an event to phase him back event_createarg(PhaseBack, 9000, g_arena, user.m_base) return false ------------------------------------------------- Freeze elseif (itemid == 30) then local players = {} local instigatorc = user:coords() -- Boom! g_arena:explosion_create("Child - Freezekill", instigatorc.x, instigatorc.y, 0) -- Get all the players around the user local numplayers = g_arena:GetPlayersInArea(players, instigatorc.x, instigatorc.y, 50) if (numplayers == 0) then return false end for i = 1, numplayers do local plyr = players[i] local vid = plyr:getVehicle():vehicletypeid() local health = plyr:health() -- Is the player an alive zombie? if (vid >= 100) and (vid ~= 107) and (health ~= 0) then -- Store his stats plyr:setstat(50, vid) -- Turn him into a frozen zombie plyr:setVehicle(107) -- Booom! local c = plyr:coords() g_arena:explosion_create("Child - Frozen", c.x, c.y, 0) -- Set an event for him event_createarg(Unfreeze, 8000, g_arena, plyr.m_base) end end return false ------------------------------------------------- Turret kits elseif (itemid == 11) or (itemid == 8) then -- Increase his turrets built stat user:setstat(10, user:getstat(10) + 1) return true ------------------------------------------------- Wall kits elseif (itemid == 13) or (itemid == 17) then -- Increase his turrets built stat user:setstat(11, user:getstat(11) + 1) return true end return trueendfunction Arena_TickerUpdate() -- Keep track of the most rewarded player local bestreward = 0 local rewardowner = nil -- For every player.. for x = 1, g_arena:num() do local plyr = g_arena:get(x) -- If he's not in spec.. if (plyr:spectator() == false) then -- Calculate and show his reward local reward = CalculateReward(plyr) plyr:setticker(1, "Your reward=" .. reward) -- Keep tabs on the best reward if (reward > bestreward) or (bestreward == 0) then bestreward = reward rewardowner = plyr end end end -- Show the best player g_state:SetNotice(0, "Best Player=" .. rewardowner.m_name .. " (" .. bestreward .. ")")end