fortressforever-scripts/maps/includes/base_fortball.lua
2014-11-11 18:32:26 -08:00

689 lines
21 KiB
Lua

-- base_fortball.lua
-- if you want base fortball with the default setup,
-- include base_fortball_default.lua in your map's lua file
-- and then include base_fortball.lua
-- precache (sounds)
function precache()
PrecacheSound("misc.bizwarn")
PrecacheSound("misc.bloop")
PrecacheSound("misc.buzwarn")
PrecacheSound("misc.dadeda")
PrecacheSound("misc.deeoo")
PrecacheSound("misc.doop")
PrecacheSound("misc.woop")
PrecacheSound("otherteam.flagstolen")
PrecacheSound("yourteam.flagcap")
PrecacheSound("otherteam.flagcap")
-- Unagi Power! Unagi!
PrecacheSound("misc.unagi_spatial")
-- goalie sounds
--PrecacheSound( goalie_sound_loop )
--PrecacheSound( goalie_sound_idle )
--PrecacheSound( goalie_sound_pain )
--PrecacheSound( goalie_sound_kill )
end
function startup()
SetGameDescription( "Fortball" )
-- disable certain teams
for i,v in pairs(disabled_teams) do
SetPlayerLimit( v, -1 )
end
-- set up team limits
for i1,v1 in pairs(teams) do
local team = GetTeam(v1)
for i2,v2 in ipairs(team_info[team:GetTeamId()].class_limits) do
team:SetClassLimit( i2, v2 )
end
end
local ball = GetEntityByName( "ball" )
for i,v in pairs(teams) do
objective_entities[v] = ball
end
the_wall_reset()
end
function the_wall_reset()
OutputEvent( "the_wall", "Enable" )
OutputEvent( "the_wall_laser_blue", "TurnOn" )
OutputEvent( "the_wall_laser_red", "TurnOn" )
AddSchedule("the_wall_disable", THE_WALL_TIMER_DISABLE, the_wall_disable )
AddSchedule("the_wall_10secwarn", THE_WALL_TIMER_WARN, the_wall_10secwarn )
end
function the_wall_disable()
OutputEvent( "the_wall", "Disable" )
OutputEvent( "the_wall_laser_blue", "TurnOff" )
OutputEvent( "the_wall_laser_red", "TurnOff" )
BroadCastMessage("#FF_ROUND_STARTED")
BroadCastSound("otherteam.flagstolen")
end
function the_wall_10secwarn()
BroadCastMessage("#FF_MAP_10SECWARN")
AddSchedule("the_wall_9secwarn", 1, the_wall_9secwarn )
end
function the_wall_9secwarn()
BroadCastMessage("#FF_MAP_9SECWARN")
AddSchedule("the_wall_8secwarn", 1, the_wall_8secwarn )
end
function the_wall_8secwarn()
BroadCastMessage("#FF_MAP_8SECWARN")
AddSchedule("the_wall_7secwarn", 1, the_wall_7secwarn )
end
function the_wall_7secwarn()
BroadCastMessage("#FF_MAP_7SECWARN")
AddSchedule("the_wall_6secwarn", 1, the_wall_6secwarn )
end
function the_wall_6secwarn()
BroadCastMessage("#FF_MAP_6SECWARN")
AddSchedule("the_wall_5secwarn", 1, the_wall_5secwarn )
end
function the_wall_5secwarn()
BroadCastMessage("#FF_MAP_5SECWARN")
SpeakAll( "AD_5SEC" )
AddSchedule("the_wall_4secwarn", 1, the_wall_4secwarn )
end
function the_wall_4secwarn()
BroadCastMessage("#FF_MAP_4SECWARN")
SpeakAll( "AD_4SEC" )
AddSchedule("the_wall_3secwarn", 1, the_wall_3secwarn )
end
function the_wall_3secwarn()
BroadCastMessage("#FF_MAP_3SECWARN")
SpeakAll( "AD_3SEC" )
AddSchedule("the_wall_2secwarn", 1, the_wall_2secwarn )
end
function the_wall_2secwarn()
BroadCastMessage("#FF_MAP_2SECWARN")
SpeakAll( "AD_2SEC" )
AddSchedule("the_wall_1secwarn", 1, the_wall_1secwarn )
end
function the_wall_1secwarn()
BroadCastMessage("#FF_MAP_1SECWARN")
SpeakAll( "AD_1SEC" )
end
function goalie_bounds_notification(player)
BroadCastSoundToPlayer( player, "misc.buzwarn" )
BroadCastMessageToPlayer(player, "#FF_WATERPOLO_GOALIE_BOUNDS")
end
function reset_ball_carrier()
if ball_carrier ~= nil and IsPlayer( ball_carrier ) then
local player = CastToPlayer(ball_carrier)
UpdateObjectiveIcon( player, objective_entities[player:GetTeamId()] )
if not BALL_ALWAYS_ENEMY_OBJECTIVE then
local enemy_team = team_info[player:GetTeamId()].enemy_team
objective_entities[enemy_team] = GetEntityByName( "ball" )
UpdateTeamObjectiveIcon( GetTeam(enemy_team), objective_entities[enemy_team] )
end
end
ball_carrier = nil
end
-- Give everyone a full resupply, but strip grenades
function player_spawn( player_entity )
local player = CastToPlayer( player_entity )
player:AddHealth( 100 )
player:AddArmor( 300 )
player:AddAmmo( Ammo.kNails, 400 )
player:AddAmmo( Ammo.kShells, 400 )
player:AddAmmo( Ammo.kRockets, 400 )
player:AddAmmo( Ammo.kCells, 400 )
-- god damn right
player:RemoveAmmo( Ammo.kDetpack, 1 )
player:RemoveAmmo( Ammo.kManCannon, 1 )
player:RemoveAmmo( Ammo.kGren1, 4 )
player:RemoveAmmo( Ammo.kGren2, 4 )
-- goalies run fast
if player:GetClass() ~= Player.kCivilian then
player:RemoveEffect( EF.kSpeedlua1 )
else
player:AddEffect( EF.kSpeedlua1, -1, 0, GOALIE_SPEED )
-- stop the goalie loop sound
--player:StopSound( goalie_sound_loop )
-- play the goalie loop sound
--player:EmitSound( goalie_sound_loop )
end
-- objective
UpdateObjectiveIcon( player, objective_entities[player:GetTeamId()] )
end
function player_onkill( player )
-- stop the goalie loop sound
--if player:GetClass() == Player.kCivilian then
--player:StopSound( goalie_sound_loop )
--end
return true
end
function player_killed( player )
-- stop the goalie loop sound
--if player:GetClass() == Player.kCivilian then
--player:StopSound( goalie_sound_loop )
--end
end
function player_switchteam( player, currentteam, desiredteam )
-- stop the goalie loop sound
--if player:GetClass() == Player.kCivilian then
--player:StopSound( goalie_sound_loop )
--end
return true
end
function player_disconnected( player )
if ball_carrier ~= nil then
if ball_carrier:GetId() == player:GetId() then
reset_ball_carrier()
end
end
-- stop the goalie loop sound
--if player:GetClass() == Player.kCivilian then
--player:StopSound( goalie_sound_loop )
--end
end
function remove_hud_items(ball, player)
RemoveHudItem( player, ball:GetName() )
local team = player:GetTeamId()
if (team == TEAM1) then
RemoveHudItemFromAll( "ball-icon-blue" )
elseif (team == TEAM2) then
RemoveHudItemFromAll( "ball-icon-red" )
end
end
function player_ondamage( player, damageinfo )
-- goalies have "UNAGI POWER, UNAGI!"
local attacker = damageinfo:GetAttacker()
if IsPlayer( attacker ) then
attacker = CastToPlayer( attacker )
if attacker:GetClass() == Player.kCivilian and attacker:GetTeamId() ~= player:GetTeamId() then
ConsoleToAll( "Goalie, " .. attacker:GetName() .. ", has UNAGI POWER, UNAGI!" )
--attacker:EmitSound("misc.unagi_spatial")
attacker:AddFortPoints( POINTS_PER_GOALIE_ATTACK, "#FF_FORTPOINTS_GOALIE_ATTACK" )
damageinfo:ScaleDamage(69)
--attacker:EmitSound( goalie_sound_kill )
elseif attacker:GetClass() == Player.kSniper and player:GetClass() ~= Player.kCivilian then
-- snipers do less damage to non-goalies
damageinfo:ScaleDamage(0.1)
end
end
if player:GetClass() == Player.kCivilian then
if player:GetTeamId() == player:GetLocationTeam() then
-- goalies are invincible in their team's locations
damageinfo:ScaleDamage(0)
--player:EmitSound( goalie_sound_idle )
else
-- goalies take more damage outside their team's locations
damageinfo:ScaleDamage(3)
--player:EmitSound( goalie_sound_pain )
end
end
end
-----------------------------------------------------------------------------
-- ball information
-- status: 0 = home, 1 = carried, 2 = dropped
-----------------------------------------------------------------------------
base_ball = info_ff_script:new({
name = "base ball",
team = Team.kUnassigned,
model = "models/items/ball/ball.mdl",
modelskin = 0,
tosssound = "Flag.toss",
dropnotouchtime = 0,
capnotouchtime = 2,
hudicon = "hud_ball",
hudx = 5,
hudy = 210,
hudwidth = 48,
hudheight = 48,
hudalign = 1,
hudstatusiconbluex = 60,
hudstatusiconbluey = 5,
hudstatusiconredx = 60,
hudstatusiconredy = 5,
hudstatusiconblue = "hud_ball.vtf",
hudstatusiconred = "hud_ball.vtf",
hudstatusiconw = 15,
hudstatusiconh = 15,
hudstatusiconbluealign = 2,
hudstatusiconredalign = 3,
touchflags = {AllowFlags.kOnlyPlayers,AllowFlags.kBlue, AllowFlags.kRed},
botgoaltype = Bot.kFlag,
status = 0
})
function base_ball:hasanimation() return false end
function base_ball:usephysics() return true end
function base_ball:touch( touch_entity )
if IsPlayer( touch_entity ) then
local player = CastToPlayer( touch_entity )
if self.notouch[player:GetId()] then return end
local ball = CastToInfoScript( entity )
if player:GetClass() ~= Player.kCivilian then
-- if the player is a spy, then force him to lose his disguise
player:SetDisguisable( false )
player:SetCloakable( false )
ConsoleToAll( player:GetName() .. " has the ball!" )
--SmartSound( player, "misc.bloop", "misc.bloop", "misc.bloop" )
SmartSound(player, "yourteam.flagstolen", "yourteam.flagstolen", "otherteam.flagstolen")
SmartSpeak(player, "CTF_YOUHAVEBALL", "CTF_TEAMHASBALL", "CTF_ENEMYHASBALL")
SmartMessage( player, "#FF_WATERPOLO_YOU_PICKUP", "#FF_WATERPOLO_TEAM_PICKUP", "#FF_WATERPOLO_ENEMY_PICKUP", Color.kGreen, Color.kGreen, Color.kRed )
ball:Pickup( player )
AddHudIcon( player, self.hudicon, ball:GetName(), self.hudx, self.hudy, self.hudwidth, self.hudheight, self.hudalign )
local team = player:GetTeamId()
if (team == TEAM1) then
AddHudIconToAll( self.hudstatusiconblue, "ball-icon-blue", self.hudstatusiconbluex, self.hudstatusiconbluey, self.hudstatusiconw, self.hudstatusiconh, self.hudstatusiconbluealign )
elseif (team == TEAM2) then
AddHudIconToAll( self.hudstatusiconred, "ball-icon-red", self.hudstatusiconredx, self.hudstatusiconredy, self.hudstatusiconw, self.hudstatusiconh, self.hudstatusiconredalign )
end
-- 100 points for initial touch on ball
if self.status == 0 then player:AddFortPoints(POINTS_PER_INITIALTOUCH, "#FF_FORTPOINTS_INITIALTOUCH") end
self.status = 1
UpdateObjectiveIcon( player, goal_entities[player:GetTeamId()] )
ball_carrier = player
if not BALL_ALWAYS_ENEMY_OBJECTIVE then
local enemy_team = team_info[player:GetTeamId()].enemy_team
objective_entities[enemy_team] = nil
UpdateTeamObjectiveIcon( GetTeam(enemy_team), objective_entities[enemy_team] )
end
-- goalies return the ball
else
if ball:IsDropped() then
-- if pressing +use
if player:IsInUse() then
ConsoleToAll( "Goalie, " .. player:GetName() .. ", returned the ball!" )
SmartSound( player, "misc.deeoo", "misc.deeoo", "misc.deeoo" )
SmartMessage( player, "#FF_WATERPOLO_YOU_RETURN", "#FF_WATERPOLO_TEAM_GOALIE_RETURN", "#FF_WATERPOLO_ENEMY_GOALIE_RETURN" )
player:AddFortPoints( POINTS_PER_GOALIE_RETURN, "#FF_FORTPOINTS_GOALIE_RETURN" )
ball:Return()
self.status = 0
else
BroadCastMessageToPlayer(player, "#FF_WATERPOLO_USE_RETURN")
end
end
end
end
end
function base_ball:onownerdie( owner_entity )
if IsPlayer( owner_entity ) then
local player = CastToPlayer( owner_entity )
-- drop the ball
ConsoleToAll( player:GetName() .. " died and dropped the ball!" )
local ball = CastToInfoScript( entity )
ball:Drop(BALL_RETURN_TIME, 0.0)
remove_hud_items(ball, player)
self.status = 2
reset_ball_carrier()
end
end
function base_ball:ownercloak( owner_entity )
if IsPlayer( owner_entity ) then
local player = CastToPlayer( owner_entity )
-- drop the ball
ConsoleToAll( player:GetName() .. " cloaked and dropped the ball!" )
local ball = CastToInfoScript( entity )
ball:Drop(BALL_RETURN_TIME, 0.0)
remove_hud_items(ball, player)
self.status = 2
reset_ball_carrier()
end
end
function base_ball:ownerfeign( owner_entity )
if IsPlayer( owner_entity ) then
local player = CastToPlayer( owner_entity )
-- drop the ball
ConsoleToAll( player:GetName() .. " feigned and dropped the ball!" )
local ball = CastToInfoScript( entity )
ball:Drop(BALL_RETURN_TIME, 0.0)
remove_hud_items(ball, player)
self.status = 2
reset_ball_carrier()
end
end
function base_ball:dropitemcmd( drop_entity )
if IsPlayer( drop_entity ) then
-- throw the ball
local ball = CastToInfoScript( entity )
local player = CastToPlayer( drop_entity )
if not player:IsInUse() then
ball:Drop(BALL_RETURN_TIME, BALL_THROW_SPEED)
else
ball:Drop(BALL_RETURN_TIME, BALL_THROW_SPEED * 0.333)
end
ConsoleToAll( player:GetName() .. " passed the ball!" )
remove_hud_items(ball, player)
self.status = 2
reset_ball_carrier()
SmartSound( player, "misc.woop", "misc.woop", "misc.woop" )
-- Make it so the player can't touch the ball for 1 second
-- (so it can't be thrown and not stick to the player)
self:addnotouch(player:GetId(), 1)
end
end
function base_ball:ondrop( owner_entity )
if IsPlayer( owner_entity ) then
local player = CastToPlayer( owner_entity )
-- let the teams know that the flag was dropped
SmartSound(player, "yourteam.drop", "yourteam.drop", "otherteam.drop")
SmartMessage(player, "#FF_YOUBALLDROP", "#FF_TEAMBALLDROP", "#FF_ENEMYBALLDROP", Color.kYellow, Color.kYellow, Color.kYellow)
end
local ball = CastToInfoScript(entity)
ball:EmitSound(self.tosssound)
end
function base_ball:onloseitem( owner_entity )
if IsPlayer( owner_entity ) then
-- let the player that lost the ball put on a disguise
local player = CastToPlayer( owner_entity )
player:SetDisguisable(true)
player:SetCloakable( true )
self:addnotouch(player:GetId(), self.capnotouchtime)
end
end
function base_ball:spawn()
self.notouch = { }
info_ff_script.spawn(self)
self.status = 0
end
function base_ball:addnotouch( player_id, duration )
self.notouch[player_id] = duration
AddSchedule(self.name .. "-" .. player_id, duration, self.removenotouch, self, player_id)
end
function base_ball.removenotouch(self, player_id)
self.notouch[player_id] = nil
end
-- For when this object is carried, these offsets are used to place
-- the info_ff_script relative to the players feet
function base_ball:attachoffset()
-- x = forward/backward
-- y = left/right
-- z = up/down
local offset = Vector( 32, 0, 0 )
return offset
end
function base_ball:precache()
PrecacheSound(self.tosssound)
info_ff_script.precache(self)
end
function base_ball:onreturn()
ConsoleToAll( "The ball has returned!" )
SpeakAll ( "CTF_BALLRETURN" )
BroadCastMessage( "#FF_WATERPOLO_BALL_RETURN", Color.kYellow )
self.status = 0
reset_ball_carrier()
end
ball = base_ball:new({
touchflags = {AllowFlags.kOnlyPlayers,AllowFlags.kBlue, AllowFlags.kRed},
botgoaltype = Bot.kFlag
})
-- generic goal
base_goal = trigger_ff_script:new({
health = 100,
armor = 300,
grenades = 200,
nails = 200,
shells = 200,
rockets = 200,
cells = 200,
detpacks = 0,
mancannons = 0,
gren1 = 0,
gren2 = 0,
item = "",
team = 0,
botgoaltype = Bot.kFlagCap
})
function base_goal:spawn()
if self.team ~= Team.kUnassigned then
goal_entities[self.team] = entity
end
end
function base_goal:allowed ( allowed_entity )
if IsPlayer( allowed_entity ) then
-- player has to be carrying the item
local player = CastToPlayer( allowed_entity )
return player:HasItem( self.item )
end
return EVENT_DISALLOWED
end
function base_goal:ontrigger ( trigger_entity )
if IsPlayer( trigger_entity ) then
-- player should capture now
local player = CastToPlayer( trigger_entity )
if player:HasItem( self.item ) then
local team = GetTeam( self.team )
team:AddScore( POINTS_PER_CAPTURE )
ConsoleToAll( team:GetName() .. " team scores!" )
local ball = GetInfoScriptByName( self.item )
ball:Return()
remove_hud_items(ball, player)
if player:GetTeamId() == self.team then
ConsoleToAll( player:GetName() .. " scored a goal!" )
-- show on the deathnotice board
ObjectiveNotice( player, "scored a goal" )
SmartSound(player, "yourteam.flagcap", "yourteam.flagcap", "otherteam.flagcap")
SmartSpeak(player, "CTF_YOUSCORE", "CTF_TEAMSCORE", "CTF_THEYSCORE")
SmartMessage( player, "#FF_WATERPOLO_YOU_GOAL", "#FF_WATERPOLO_TEAM_GOAL", "#FF_WATERPOLO_ENEMY_GOAL", Color.kGreen, Color.kGreen, Color.kRed)
player:AddFortPoints( POINTS_PER_CAPTURE * 100, "#FF_FORTPOINTS_GOAL" )
else
ConsoleToAll( player:GetName() .. " scored an own goal!\nWait, what?! Kill him like that Columbian a few years ago! OWN GOAL! OWN GOAL!" )
-- show on the deathnotice board
ObjectiveNotice( player, "scored an own goal" )
SmartSound(player, "otherteam.flagcap", "otherteam.flagcap", "yourteam.flagcap")
SmartSpeak(player, "CTF_THEYSCORE", "CTF_THEYSCORE", "CTF_TEAMSCORE")
SmartMessage( player, "#FF_WATERPOLO_YOU_OWN_GOAL", "#FF_WATERPOLO_TEAM_OWN_GOAL", "#FF_WATERPOLO_ENEMY_OWN_GOAL", Color.kRed, Color.kRed, Color.kGreen)
player:AddFortPoints( -POINTS_PER_CAPTURE * 100, "#FF_FORTPOINTS_OWN_GOAL" )
end
ApplyToAll({ AT.kRespawnPlayers, AT.kReloadClips })
the_wall_reset()
end
end
end
-- on blue's side of map, but points go to red
blue_goal = base_goal:new({ item = "ball", team = TEAM2 })
-- on red's side of map, but points go to blue
red_goal = base_goal:new({ item = "ball", team = TEAM1 })
-- respawns a goalie
base_goalie_respawner = trigger_ff_script:new({ team = Team.kUnassigned })
function base_goalie_respawner:ontouch( trigger_entity )
if IsPlayer( trigger_entity ) then
local player = CastToPlayer( trigger_entity )
if player:GetClass() == Player.kCivilian and player:GetTeamId() == self.team then
-- respawn the goalie
ApplyToPlayer(player, { AT.kRespawnPlayers })
AddSchedule("goalie_bounds_notification_" .. player:GetId(), 0.1, goalie_bounds_notification, player )
end
end
end
-- goalie respawner
blue_goalie_respawner = base_goalie_respawner:new({ team = TEAM1 })
red_goalie_respawner = base_goalie_respawner:new({ team = TEAM2 })
-- returns the item
base_item_returner = trigger_ff_script:new({ item = "", message = "" })
function base_item_returner:allowed ( allowed_entity )
if IsPlayer( allowed_entity ) then
-- player has to be carrying the item or be a goalie
local player = CastToPlayer( allowed_entity )
if player:HasItem( self.item ) or player:GetClass() == Player.kCivilian then
return EVENT_ALLOWED
end
end
return EVENT_DISALLOWED
end
function base_item_returner:ontrigger ( trigger_entity )
if IsPlayer( trigger_entity ) then
local player = CastToPlayer( trigger_entity )
if player:GetClass() ~= Player.kCivilian then
-- return the item
local item = GetInfoScriptByName( self.item )
item:Return()
remove_hud_items(item, player)
ConsoleToAll( player:GetName() .. self.message )
SpeakAll ( "CTF_BALLRETURN" )
SmartMessage( player, "#FF_WATERPOLO_YOU_BOUNDS", "#FF_WATERPOLO_TEAM_BOUNDS", "#FF_WATERPOLO_ENEMY_BOUNDS", Color.kYellow, Color.kYellow, Color.kYellow )
else
-- respawn the goalie
ApplyToPlayer(player, { AT.kRespawnPlayers })
AddSchedule("goalie_bounds_notification_" .. player:GetId(), 0.1, goalie_bounds_notification, player )
end
end
end
-- ball stripper
ball_stripper = base_item_returner:new({ item = "ball", message = " took the ball out of bounds!" })
-- spawn ammo packs
waterpolo_pack_spawn_blue = blue_ammobackpack
waterpolo_pack_spawn_red = red_ammobackpack
fortball_pack_spawn_blue = blue_ammobackpack
fortball_pack_spawn_red = red_ammobackpack
-- unique fortball spawns (goalies spawn on top of the goal)
bluespawn = { validspawn = function(self,player) return player:GetTeamId() == TEAM1 and player:GetClass() ~= Player.kCivilian and player:GetClass() ~= Player.kSniper end }
redspawn = { validspawn = function(self,player) return player:GetTeamId() == TEAM2 and player:GetClass() ~= Player.kCivilian and player:GetClass() ~= Player.kSniper end }
bluespawn_goalie = { validspawn = function(self,player) return player:GetTeamId() == TEAM1 and player:GetClass() == Player.kCivilian end }
redspawn_goalie = { validspawn = function(self,player) return player:GetTeamId() == TEAM2 and player:GetClass() == Player.kCivilian end }
bluespawn_sniper = { validspawn = function(self,player) return player:GetTeamId() == TEAM1 and player:GetClass() == Player.kSniper end }
redspawn_sniper = { validspawn = function(self,player) return player:GetTeamId() == TEAM2 and player:GetClass() == Player.kSniper end }
-----------------------------------------------------------------------------
-- unique fortball locations
-----------------------------------------------------------------------------
location_ballsonia = location_info:new({ text = "Ballsonia", team = Team.kUnassigned })
location_midfield = location_info:new({ text = "Midfield", team = Team.kUnassigned })
location_blue_side = location_info:new({ text = "Blue Side", team = TEAM1 })
location_red_side = location_info:new({ text = "Red Side", team = TEAM2 })
location_blue_goal = location_info:new({ text = "Blue Goal", team = TEAM1 })
location_red_goal = location_info:new({ text = "Red Goal", team = TEAM2 })
location_upper_deck = location_info:new({ text = "Upper Deck", team = Team.kUnassigned })
location_blue_upper_deck = location_info:new({ text = "Blue Upper Deck", team = TEAM1 })
location_red_upper_deck = location_info:new({ text = "Red Upper Deck", team = TEAM2 })
location_nose_bleeds = location_info:new({ text = "Nose Bleeds", team = Team.kUnassigned })
location_blue_nose_bleeds = location_info:new({ text = "Blue Nose Bleeds", team = TEAM1 })
location_red_nose_bleeds = location_info:new({ text = "Red Nose Bleeds", team = TEAM2 })
location_rainy_sky = location_info:new({ text = "Rainy Sky", team = Team.kUnassigned })
location_death_hills = location_info:new({ text = "Death Hills", team = Team.kUnassigned })
location_sideroom1 = location_info:new({ text = "Side Room 1", team = Team.kUnassigned })
location_sideroom2 = location_info:new({ text = "Side Room 2", team = Team.kUnassigned })