--------------------------------------------------------------
-- Includes
--------------------------------------------------------------
require('o_mis')
require('o_ShootingGallery')

-- @TODO: Add Path Changing on waypoint, need to get [Closest Waypoint on New Path]
--        Also need [Number of Waypoints on Path]
-- @TODO: Optimize

--------------------------------------------------------------
-- Locals and Constants
LOCALS = {}
CONSTANTS = {}
--------------------------------------------------------------

-- Start Location for the Zone
CONSTANTS["PLAYER_START_POS"] = {x = -905.00, y = 234, z = 2.31}
CONSTANTS["PLAYER_START_ROT"] = {w = 0.91913521289825, x = 0, y = 0.39394217729568, z = 0}
CONSTANTS["SPAWN_PATH_NAME"] = "skunknodes"
SPAWNPOINTS = {}

-- cannon constants
CONSTANTS["CANNON_TEMPLATEID"] = 3879
CONSTANTS["CANNON_PLAYER_OFFSET"] = {x = -5.624, y = 0, z = -2.451}
CONSTANTS["CANNON_VELOCITY"] = 80.0
CONSTANTS["CANNON_MIN_DISTANCE"] = 10.0
CONSTANTS["CANNON_REFIRE_RATE"] = 800.0
CONSTANTS["CANNON_BARREL_OFFSET"] = {x = 0, y = 4.3, z = 9}
CONSTANTS["CANNON_TIMEOUT"] = -1
CONSTANTS["CANNON_FOV"] = 58.6
CONSTANTS["CANNON_USE_LEADERBOARDS"] = true

-- for Animations
CONSTANTS["VALID_ACTORS"] = {3109, 3110, 3111, 3112, 3125, 3126}
ACTORS = {}					-- stores actors for the instance

-- for Effects
CONSTANTS["VALID_EFFECTS"] = {3122}
EFFECTS = {}					-- stores effects for the instance


-- cannon impact skills
--CONSTANTS["CANNON_IMPACT_SKILL"] = {34, 34, 61, 62}
--CONSTANTS["CANNON_RETICULE_EFFECT"] = {"inRange", "inRange", "inRange2", "inRange3"}


--------------------------------------------------------------
-- Wave Data
waves = {}
PLAYER_SCORE = {}
--------------------------------------------------------------

-- Syntax:     [Time]   [Text to Show Player]
--------------------------------------------------------------
AddWave(waves,	30.0,	"Wave;One"   )		
AddWave(waves,	45.0,	"Wave;Two"   )
AddWave(waves,	45.0,	"Wave;Three" )
AddWave(waves,	60.0,	"Wave;Four" )


-- wave constants
CONSTANTS["NUM_WAVES"] = #waves
CONSTANTS["FIRST_WAVE_START_TIME"] = 4.0
CONSTANTS["IN_BETWEEN_WAVE_PAUSE"] = 3.0

CONSTANTS["STREAK_MOD"] = 2
CONSTANTS["STREAK_BONUS"] = {1,2,5,10}

--------------------------------------------------------------
-- Spawn Data
spawns = {}
SPAWN_DATA = {}

-- AddPath - adds a path to a spawn. Can have one or more.
-- Syntax:  AddPath(paths, "[Path Name]")


-- AddSpawn - configures data for the spawn and adds it. Can
--            only have one.
-- Syntax: AddSpawn(spawn, paths, [Template ID],
--                  [Initial Spawn Time Min], [Initial Spawn Time Max], [Does Respawn],
--                  [Respawn Time Min], [Respawn Time Max],
--                  [Initial Speed], [Score], [Change Speed at Waypoints],
--                  [Chance to Change Speed], [Min Speed], [Max Speed],
--                  [Is Moving Platform], [Despawn On Last Waypoint], [Time Score])
--
-- NOTE: All times are in Seconds (i.e. 3.50 = 3 and a half seconds)
--------------------------------------------------------------

--------------------------------------------------------------
-- Wave 1 Spawns
spawn = {}
--------------------------------------------------------------

	-- Medium Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Medium Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)
	
	-- Baby Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk3
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk4
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)






-- Add the spawns for the wave
AddSpawnsForWave(spawns,spawn)


--------------------------------------------------------------
-- Wave 2 Spawns
spawn = {}
--------------------------------------------------------------

	-- Medium Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Medium Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)
	
	-- Baby Skunk3
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk4
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk5
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk6
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)





-- Add the spawns for the wave
AddSpawnsForWave(spawns,spawn)


--------------------------------------------------------------
-- Wave 3 Spawns
spawn = {}
--------------------------------------------------------------

	-- Medium Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Medium Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Mama Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"MamaSkunk1")
	AddPath(paths,	"MamaSkunk2")
	AddPath(paths,	"MamaSkunk3")
	AddSpawn(spawn,paths,
		 3898,	5,	15,	true, 5,	15,	4.0,	100,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)
	
	-- Baby Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)
	
	-- Baby Skunk3
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk4
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk5
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk6
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk7
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)




-- Add the spawns for the wave
AddSpawnsForWave(spawns,spawn)


--------------------------------------------------------------
-- Wave 4 Spawns
spawn = {}
--------------------------------------------------------------

	-- Medium Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Medium Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"Skunk1")
	AddPath(paths,	"Skunk2")
	AddSpawn(spawn,paths,
		 3719,	4,	10,	true,	4,	10,	4.0,	50,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Mama Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"MamaSkunk1")
	AddPath(paths,	"MamaSkunk2")
	AddPath(paths,	"MamaSkunk3")
	AddSpawn(spawn,paths,
		 3898,	5,	15,	true, 5,	15,	4.0,	100,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Mama Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"MamaSkunk1")
	AddPath(paths,	"MamaSkunk2")
	AddPath(paths,	"MamaSkunk3")
	AddSpawn(spawn,paths,
		 3898,	5,	15,	true, 5,	15,	4.0,	100,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)
	
	-- Baby Skunk1
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk2
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)
	
	-- Baby Skunk3
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk4
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk5
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk6
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk7
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk8
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk9
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)

	-- Baby Skunk10
	--------------------------------------------------------------
	paths = {}
	--------------------------------------------------------------
	AddPath(paths,	"BabySkunk1")
	AddPath(paths,	"BabySkunk2")
	AddPath(paths,	"BabySkunk3")
	AddPath(paths,	"BabySkunk4")
	AddPath(paths,	"BabySkunk5")
	AddPath(paths,	"BabySkunk6")
	AddPath(paths,	"BabySkunk7")
	AddSpawn(spawn,paths,
		 3899,	0.1,	0.1,	true,	0.1,	0.1,	4.0,	25,		false,	0.0,	1.0,	1.0,	false,		false,		0.0)




-- Add the spawns for the wave
AddSpawnsForWave(spawns,spawn)


--------------------------------------------------------------
-- Helper Functions
--------------------------------------------------------------
--------------------------------------------------------------
-- play effects on all effects in the scene
--------------------------------------------------------------
function PlaySceneEffect(effectName)

	-- trigger effects on effect objects
	for effectID = 1, #EFFECTS do

		local effect = GAMEOBJ:GetObjectByID(EFFECTS[effectID])
		effect:PlayFXEffect{ effectType = effectName }

	end

end


--------------------------------------------------------------
-- play animations on all actors in the scene, and others
--------------------------------------------------------------
function PlaySceneAnimation(anim, bPlayCannon, bPlayPlayer)

	-- play animation on actors
	for actorID = 1, #ACTORS do

		local actor = GAMEOBJ:GetObjectByID(ACTORS[actorID])
		actor:PlayAnimation{ animationID = anim }

	end

	-- play on cannon
	if (bPlayCannon == true) then

		local cannon = getObjectByName("cannonObject")
		cannon:PlayAnimation{ animationID = anim }

	end

	-- play on player
	if (bPlayPlayer == true) then

		local player = getObjectByName("activityPlayer")
		player:PlayAnimation{ animationID = anim }

	end

end

--------------------------------------------------------------
-- return if template is a valid actor
--------------------------------------------------------------
function IsValidActor(templateID)

	for actors = 1, #CONSTANTS["VALID_ACTORS"] do
		if (templateID == CONSTANTS["VALID_ACTORS"][actors]) then
			return true
		end
	end

	return false

end


--------------------------------------------------------------
-- return if template is a valid effect
--------------------------------------------------------------
function IsValidEffect(templateID)

	for effects = 1, #CONSTANTS["VALID_EFFECTS"] do
		if (templateID == CONSTANTS["VALID_EFFECTS"][effects]) then
			return true
		end
	end

	return false

end


--------------------------------------------------------------
-- put the player in the cannon, does not start the cannon
--------------------------------------------------------------
function enterCannon(self)

	-- get the cannon
	local cannon = getObjectByName("cannonObject")

	-- get the player
	local player = getObjectByName("activityPlayer")

	-- if we have both start it
	if ((cannon) and (player)) then
		cannon:RequestActivityEnter{bStart = false, userID = player}
	end

end


--------------------------------------------------------------
-- try to start the game
--------------------------------------------------------------
function startGame(self)

	-- get the cannon
	local cannon = getObjectByName("cannonObject")

	-- get the player
	local player = getObjectByName("activityPlayer")
	-- if we have both start it
	if ((cannon) and (player)) then

		-- put the player in if we have to, otherwise start
		if ((cannon:GetActivityUser().userID):GetID() ~= player:GetID()) then
			print("wrong player")
			cannon:RequestActivityEnter{bStart = true, userID = player}
		else
			print("starting game")
			cannon:ActivityStart{ rerouteID = player }
		end

		DoGameStartup(self)

	end

end


--------------------------------------------------------------
-- try to stop the game
--------------------------------------------------------------
function stopGame(self, bCanceling)

	-- get the cannon
	local cannon = getObjectByName("cannonObject")

	-- get the player
	local player = getObjectByName("activityPlayer")

	-- if we have both stop it if we need to, but dont exit
	if ((cannon) and (player)) then

		print("stopping game")

		cannon:ActivityStop{rerouteID = player, bExit = false, bUserCanceled = bCanceling}

		DoGameShutdown(self)

		-- if we are not exiting, shwo the summary and allow for retry
		if (bCanceling == false) then
			showSummaryDialog(self)
		end

	end

end


--------------------------------------------------------------
-- handle all the game startup data
--------------------------------------------------------------
function DoGameStartup(self)

	-- set game state and vars
	LOCALS["SpawnNum"] = 0
	LOCALS["CurSpawnNum"] = 0
	LOCALS["GameStarted"] = true
	LOCALS["ThisWave"] = 0
	LOCALS["GameScore"] = 0
	LOCALS["GameTime"] = 0
	LOCALS["NumShots"] = 0
	LOCALS["NumKills"] = 0
	LOCALS["MaxStreak"] = 0

	-- reset scores
	for waveNum = 1, tonumber(CONSTANTS["NUM_WAVES"]) do
		PLAYER_SCORE[waveNum] = 0
	end

	-- start the first wave
	LOCALS["ThisWave"] = 1
	GAMEOBJ:GetTimer():AddTimerWithCancel( CONSTANTS["FIRST_WAVE_START_TIME"], "SpawnWave1",self )

	-- Scene animations and wave number DISABLED for start, we use 3/2/1/Go instead
	
	-- play wave animation on actors, cannon, and player
	--PlaySceneAnimation("wave" .. LOCALS["ThisWave"], true, true)

	-- display wave number to player
	--DisplayWaveNumberToPlayer(self, LOCALS["ThisWave"])

	-- set the cannon reticule back to start
	setCannonReticuleSize(self, 1)

end


--------------------------------------------------------------
-- handle all the game shutdown data
--------------------------------------------------------------
function DoGameShutdown(self)

	print("game shutdown")

	LOCALS["GameStarted"] = false

	-- cancel all timers
	GAMEOBJ:GetTimer():CancelAllTimers( self )

	-- despawn all spawns
	DestroyAllSpawns(self)

end


--------------------------------------------------------------
-- Remove the player from the zone
--------------------------------------------------------------
function RemovePlayerFromZone(self, player)

	player:ServerSetUserCtrlCompPause{bPaused = false}

	-- UNCOMMENT to go back to the other zone
	player:TransferToLastNonInstance{ playerID = player, bUseLastPosition = true }

end

--------------------------------------------------------------
-- Get a random path
--------------------------------------------------------------
function GetRandomPath(spawn)

	-- pick a random
	local ran = math.random(1,#spawn.path)
	return spawn.path[ran]

end


--------------------------------------------------------------
-- spawn an object for the game
--------------------------------------------------------------
function SpawnObject(num, spawn, self, bSpawnNow)

	-- get the current spawn number
	local spawnNum = IncrementVarAndReturn("SpawnNum")

	-- save the spawn data for the object when it is loaded
	local SpawnData = {sdTemplate = spawn.id,
				 sdRespawn = spawn.bRespawn,
	             sdSpeed = spawn.speed,
	             sdScore = spawn.score,
	             sdPath = GetRandomPath(spawn),
	             sdnum = num,
	             sdChangeSpeed = spawn.bChangeSpeed,
	             sdSpeedChance = spawn.speedChangeChance,
	             sdMinSpeed = spawn.minSpeed,
	             sdMaxSpeed = spawn.maxSpeed,
	             sdMovingPlat = spawn.bMovingPlatform,
	             sdDespawnTime = spawn.despawnTime,
	             sdTimeScore = spawn.timeScore,
	             bSpawned = false}

	-- store the data
	SPAWN_DATA[tonumber(spawnNum)] = SpawnData

	-- set the timer to spawn the object
	local timerName = "DoSpawn" .. spawnNum

	-- spawn now and use initial spawn times
	if (bSpawnNow == true) then
		if (spawn.initSpawnTimeMin > 0 and spawn.initSpawnTimeMax > 0) then
			local ranSpawnTime = (math.random() * (spawn.initSpawnTimeMax - spawn.initSpawnTimeMin)) + spawn.initSpawnTimeMin
			print ("init spawning with time " .. ranSpawnTime)
			GAMEOBJ:GetTimer():AddTimerWithCancel( ranSpawnTime, timerName, self )
		else
			GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1, timerName, self )
		end

	-- respawn, use respawn times
	elseif (spawn.bRespawn == true) then
		-- pick a random spawn time
		local ranSpawnTime = (math.random() * (spawn.maxTime - spawn.minTime)) + spawn.minTime
		GAMEOBJ:GetTimer():AddTimerWithCancel( ranSpawnTime, timerName, self )
	end

end


--------------------------------------------------------------
-- destroys all spawns
--------------------------------------------------------------
function DestroyAllSpawns(self)

	local maxSpawnNum = LOCALS["CurSpawnNum"]
	for spawn = 1, maxSpawnNum do
		-- @TODO: (Optimize this)
		local spawnObject = getObjectByName("spawnObject" .. spawn)
		if (spawnObject) then
			if (spawnObject:Exists() and not spawnObject:IsDead().bDead) then
				print("removing spawn object " .. spawn)
				spawnObject:Die{killerID = spawnObject, killType = "SILENT"}
			end
		end
	end

	-- reset vars
	LOCALS["SpawnNum"] = 0
	LOCALS["CurSpawnNum"] = 0
end


--------------------------------------------------------------
-- sends a message to display the current wave text to player
--------------------------------------------------------------
function DisplayWaveNumberToPlayer(self, waveNum)

	-- @TODO: (Optimize)
	local player = getObjectByName("activityPlayer")
	if (player) then
		UI:SendMessage("ToggleFlashingText", { {"visible",  true }, {"text", waves[tonumber(waveNum)].waveStr}})

	end
end


--------------------------------------------------------------
-- look through spawn data to find the most recent data
-- that matches the template, returns nil or data
--------------------------------------------------------------
function GetLatestSpawnDataByTemplate(self,templateID)

	local spawnNum = LOCALS["SpawnNum"]
	while (spawnNum > 0) do

		-- get the data
		local SpawnData = SPAWN_DATA[tonumber(spawnNum)]

		-- check spawn flag and template
		if (SpawnData.bSpawned == false and templateID == SpawnData.sdTemplate) then

			-- set spawned flag
			SpawnData.bSpawned = true

			-- re-save data
			SPAWN_DATA[tonumber(spawnNum)] = SpawnData

			-- return the good data
			return SpawnData
		end

		-- try prev spawn data
		spawnNum = spawnNum - 1

	end

	return nil

end

--------------------------------------------------------------
-- show the summary dialog
--------------------------------------------------------------
function showSummaryDialog(self)

	-- get player
	local player = getObjectByName("activityPlayer")

	if (player) then

		-- do summary dialog

		-- Wave Score
		local score = LOCALS["GameScore"]
		--local strText = "Score:\n\n"

		--for wavenum = 1, tonumber(CONSTANTS["NUM_WAVES"]) do
		--	strText = strText .. "Wave " .. wavenum .. " = " .. PLAYER_SCORE[tonumber(wavenum)] .. "\n"
		--end

		-- Total Score
		--strText = strText .. "\nTotal: " .. score .. "\n"

		-- Accuracy
		--strText = strText .. "\nAccuracy: " .. LOCALS["NumKills"] .. "/" .. LOCALS["NumShots"] .. "\n"

		-- Highest Streak
		--strText = strText .. "\Highest Streak: " .. LOCALS["MaxStreak"] .. "\n"


		local cannon = getObjectByName("cannonObject")
		local msgReward = cannon:GetActivityReward{ playerID = player }
		
		--print("rewardMoney = " .. tostring(msgReward.rewardMoney))

		player:ShowActivitySummary{	totalScore				= score,
									waveScore1				= PLAYER_SCORE[1],
									waveScore2				= PLAYER_SCORE[2],
									waveScore3				= PLAYER_SCORE[3],
									waveScore4				= PLAYER_SCORE[4],
									numShots				= LOCALS["NumShots"],
									numKills				= LOCALS["NumKills"],
									longestStreak			= LOCALS["MaxStreak"],
									leaderboard_yourRank	= 1,					--@TODO: We don't have leaderboards, replace this when we do!
									leaderboard_topScore	= 100,					--@TODO: We don't have leaderboards, replace this when we do!
									leaderboard_yourTopScore= 100,					--@TODO: We don't have leaderboards, replace this when we do!
									rewardMoney				= msgReward.rewardMoney,
									rewardItem1Name			= msgReward.rewardItem1Name,
									rewardItem1Image		= msgReward.rewardItem1Image,
									rewardItem1StackSize	= msgReward.rewardItem1StackSize,
									rewardItem2Name			= msgReward.rewardItem2Name,
									rewardItem2Image		= msgReward.rewardItem2Image,
									rewardItem2StackSize	= msgReward.rewardItem2StackSize,
									callbackObj				= GAMEOBJ:GetZoneControlID()}

		if (cannon) then
			cannon:RequestActivitySummaryLeaderboardData{ user = player }
		end

	end

end


--------------------------------------------------------------
-- set the cannon's reticule size and skill based on wave
--------------------------------------------------------------
function setCannonReticuleSize(self, waveNum)
	local cannon = getObjectByName("cannonObject")
	cannon:SetShootingGalleryReticuleEffect{ inRangeType = "SkunkSG" }
end


--------------------------------------------------------------
-- Add more time to the current wave timer
--------------------------------------------------------------
function AddTimeToWave(self, timeToAdd)

	-- get wave number
	local waveNum = LOCALS["ThisWave"]

	-- check on next wave
	waveNum = waveNum + 1

	-- get correct timer name
	local timerName = "GameOver"
	if (waveNum <= CONSTANTS["NUM_WAVES"]) then
		timerName = "SpawnWave" .. waveNum
	end

	-- get the time left
	local theTime = GAMEOBJ:GetTimer():GetTime(timerName,self )
	if (theTime > 0.0) then

		-- cancel timer and add a new one with more time
		GAMEOBJ:GetTimer():CancelTimer(timerName, self)
		theTime = theTime + timeToAdd
		GAMEOBJ:GetTimer():AddTimerWithCancel( theTime, timerName, self )

		-- get the cannon
		local cannon = getObjectByName("cannonObject")
        cannon:AddActivityTime{ rerouteID =  getObjectByName("activityPlayer"), timeToAdd = timeToAdd }
	end

end

function RecordPlayerWaveScore(self)

	-- get wave number
	local waveNum = tonumber(LOCALS["ThisWave"])

	-- get the cannon
	local cannon = getObjectByName("cannonObject")

	if (waveNum) and (waveNum > 0) and (cannon) then

		-- get total current score
		local score = tonumber(cannon:GetActivityPoints().points)

		-- to get the wave score we must subtract prior waves from it
		for waves = 1, waveNum - 1 do
			score = score - PLAYER_SCORE[waves]
		end

		-- store the new score
		PLAYER_SCORE[waveNum] = score

	end

end

function LoadSpawnPoints(self)

	local pathMsg = LEVEL:GetPathWaypoints(CONSTANTS["SPAWN_PATH_NAME"])
	
	if (tostring(type(pathMsg)) == "table") then
		for i, v in pairs(pathMsg) do
			SPAWNPOINTS[i] = v
		end			
	end	

end


--------------------------------------------------------------
-- Game Message Handlers
--------------------------------------------------------------

--------------------------------------------------------------
-- Startup
--------------------------------------------------------------
function onStartup(self)

	-- set game state
	LOCALS["GameStarted"] = false
	LOCALS["CurSpawnNum"] = 0
	LOCALS["ThisWave"] = 0
	LOCALS["GameScore"] = 0
	LOCALS["GameTime"] = 0
	LOCALS["NumShots"] = 0
	LOCALS["NumKills"] = 0
	LOCALS["MaxStreak"] = 0

	print("Starting up")
	--LoadSpawnPoints(self)
end


--------------------------------------------------------------
-- Timers
--------------------------------------------------------------
onTimerDone = function(self, msg)

    -- parse the name to get out the wave number
    -- use the wave number to select the spawns
    -- of format "SpawnWaveXXX" where XXX is the spawn number
    if (string.starts(msg.name,"SpawnWave")) then

		if (LOCALS["GameStarted"] == true) then
			setCannonReticuleSize(self, 1)

			-- cancel all timers
			GAMEOBJ:GetTimer():CancelAllTimers( self )

			-- store this wave number
			waveNum = LOCALS["ThisWave"]

			print("Spawning Wave " .. waveNum)

			-- setup spawns for wave
			for k,v in pairs(spawns[tonumber(waveNum)]) do SpawnObject(k,v,self,true) end

			-- move to the next wave
			--waveNum = waveNum + 1

			-- there are no more waves left
			-- so stop game after this wave
			if (tonumber(waveNum) >= CONSTANTS["NUM_WAVES"]) then

				-- setup next wave
				GAMEOBJ:GetTimer():AddTimerWithCancel( waves[tonumber(waveNum)].timeLimit, "GameOver", self )

			else

				-- setup next wave
				GAMEOBJ:GetTimer():AddTimerWithCancel( waves[tonumber(waveNum)].timeLimit, "EndWave" .. waveNum,self )

			end

			local cannon = getObjectByName("cannonObject")
			local player = getObjectByName("activityPlayer")
	    	if cannon and player then
	    		cannon:StartActivityTime{ rerouteID = player, startTime = waves[tonumber(waveNum)].timeLimit }
				cannon:ActivityPause{ rerouteID = player, bPause = false }
		    end



		end
    end

	-- called when a wave ends, contains the number of the next wave
    if (string.starts(msg.name,"EndWave")) then

		if (LOCALS["GameStarted"] == true) then

			-- get rid of current spawns
			DestroyAllSpawns(self)

			-- cancel all timers
			GAMEOBJ:GetTimer():CancelAllTimers( self )

			-- record the score
			RecordPlayerWaveScore(self)

			-- get the wave number from the rest of the string
			local waveNum = string.sub(msg.name,8)

			-- store the next wave number
			waveNum = tonumber(waveNum) + 1
			LOCALS["ThisWave"] = waveNum

			-- @TODO: Do whatever we need to during the pause, wave begins after pause
			-- play wave animation on actors, cannon, and player
			PlaySceneAnimation("skunkwave" .. LOCALS["ThisWave"], true, true)

			-- display wave number to player
			DisplayWaveNumberToPlayer(self, waveNum)

			-- there are no more waves left
			-- so stop game after this wave
			if (waveNum > CONSTANTS["NUM_WAVES"]) then

				-- setup next wave
				GAMEOBJ:GetTimer():AddTimerWithCancel( 0.1, "GameOver", self )

			else

				-- setup next wave
				GAMEOBJ:GetTimer():AddTimerWithCancel( CONSTANTS["IN_BETWEEN_WAVE_PAUSE"], "SpawnWave" .. waveNum,self )

			end

			local player = getObjectByName("activityPlayer")
			local cannon = getObjectByName("cannonObject")
	    	if player and cannon then
				cannon:ActivityPause{rerouteID = player, bPause = true}
		    end

		end
    end

    -- parse the name to get out the spawn number
    -- use the spawn number to select the template id
    -- load the object
    -- of format "DoSpawnXXX" where XXX is the spawn number

    if (string.starts(msg.name,"DoSpawn")) then

		if (LOCALS["GameStarted"] == true) then

			-- get the spawn number from the rest of the string
			local spawnNum = string.sub(msg.name,8)

			-- get the template out of the spawn data
			local SpawnData = SPAWN_DATA[tonumber(spawnNum)]

			local templateID = SpawnData.sdTemplate

			--print("spawning " .. spawnNum)

			-- get the position of the first waypoint
			local startPos = GAMEOBJ:GetWaypointPos( SpawnData.sdPath, 1 )
			local config = {{"spawndata", SpawnData},
							{"streakmod", CONSTANTS["STREAK_MOD"]},
							{"streakbonus", CONSTANTS["STREAK_BONUS"]}}
			-- load the object in the world
    		RESMGR:LoadObject { objectTemplate = templateID,
    		                    bIsSmashable = true,
    		                    x = startPos.x,
    		                    y = startPos.y,
    		                    z = startPos.z,
    		                    owner = self,
								configData = config}
		end

    end

    -- end the game

    if (msg.name == "GameOver") then
		RecordPlayerWaveScore(self)
		stopGame(self, false)
    end

end


--------------------------------------------------------------
-- Called when a Child is loaded
--------------------------------------------------------------
function onChildLoaded(self, msg)

	-- look through spawn data to find the most recent data
	-- that matches the template
	--local SpawnData = GetLatestSpawnDataByTemplate(self,msg.templateID)
	local SpawnData = msg.childID:GetVar("spawndata")
	
	if (SpawnData) then

		local curSpawnNum = IncrementVarAndReturn("CurSpawnNum")

		-- store spawn for use later
		storeObjectByName("spawnObject" .. curSpawnNum, msg.childID)

		-- store who the parent is
		storeParent(self, msg.childID)

		-- store the spawn data in the child (@TODO: Need to Optimize)
		msg.childID:SetVar("SpawnData", SpawnData)

		
		if (SpawnData.sdMovingPlat == true) then
			msg.childID:SetPathingSpeed{ speed = SpawnData.sdSpeed }
			msg.childID:SetMovingPlatformParams{ wsPlatformPath = SpawnData.sdPath, iStartIndex = 0 }
		else
			-- assign child's waypoint
			msg.childID:SetVar("attached_path",SpawnData.sdPath)
			msg.childID:SetVar("attached_path_start",0)

			-- start child on path
			msg.childID:FollowWaypoints()
			msg.childID:SetPathingSpeed{ speed = SpawnData.sdSpeed }
		end

	else
		-- error
		print("Error: Spawned object " .. msg.templateID .. " but saved data not found for it!")
	end

end


--------------------------------------------------------------
-- Called when Player Loads into Zone
--------------------------------------------------------------
function onPlayerLoaded(self, msg)

	print ("Player Entered: " .. msg.playerID:GetName().name)

	-- stun and move player to level start location
	-- @TODO: Sometimes this teleport works and sometimes it does not.....ghosting distance?
	local player = msg.playerID

	player:ServerSetUserCtrlCompPause{bPaused = true}

	player:CancelMission{ missionID = 30 }

--	player:Teleport{pos = CONSTANTS["PLAYER_START_POS"],
--	                x = CONSTANTS["PLAYER_START_ROT"].x,
--	                y = CONSTANTS["PLAYER_START_ROT"].y,
--	                z = CONSTANTS["PLAYER_START_ROT"].z,
--	                w = CONSTANTS["PLAYER_START_ROT"].w,
--	                bSetRotation = true}

	if (LOCALS["GameStarted"] == false) then
		-- get the player
		local player = getObjectByName("activityPlayer")

		-- store the player for later use
		if (player == nil) then
			storeObjectByName("activityPlayer", msg.playerID)
		end

		-- put the player in the cannon
		enterCannon(self)
	end

end


--------------------------------------------------------------
-- Sent from an object after loading into zone
--------------------------------------------------------------
function onObjectLoaded(self, msg)
	-- Cannon Object Loaded
	if (msg.templateID == CONSTANTS["CANNON_TEMPLATEID"]) then
		-- Override the cannon shooting parameters
		msg.objectID:SetShootingGalleryParams{playerPosOffset =    CONSTANTS["CANNON_PLAYER_OFFSET"],
		                                      projectileVelocity = CONSTANTS["CANNON_VELOCITY"],
		                                      cooldown =           CONSTANTS["CANNON_REFIRE_RATE"],
		                                      muzzlePosOffset =    CONSTANTS["CANNON_BARREL_OFFSET"],
		                                      minDistance =        CONSTANTS["CANNON_MIN_DISTANCE"],
		                                      timeLimit =          CONSTANTS["CANNON_TIMEOUT"],
		                                      cameraFOV =          CONSTANTS["CANNON_FOV"],
											  bUseLeaderboards =   CONSTANTS["CANNON_USE_LEADERBOARDS"]}

		-- store the cannon object for use later
		storeObjectByName("cannonObject", msg.objectID)

		if (LOCALS["GameStarted"] == false) then
			-- try to put hte player in the cannon
			enterCannon(self)
		end

	-- check for actors
	elseif ( IsValidActor(msg.templateID) == true ) then

		-- store the actor
		local nextActor = #ACTORS + 1
		ACTORS[nextActor] = msg.objectID:GetID()

	-- check for effects
	elseif ( IsValidEffect(msg.templateID) == true ) then

		-- store the actor
		local nextEffect = #EFFECTS + 1
		EFFECTS[nextEffect] = msg.objectID:GetID()

	end

end


--------------------------------------------------------------
-- Sent from the cannon to get a score for the player
--------------------------------------------------------------
function onDoCalculateActivityRating(self, msg)

	-- save the score and time for later use
	LOCALS["GameScore"] = msg.fValue1
	LOCALS["GameTime"]  = msg.fValue2
	LOCALS["NumShots"]  = msg.fValue3	-- shots fired
	LOCALS["NumKills"]  = msg.fValue4	-- targets hit
	LOCALS["MaxStreak"] = msg.fValue5	-- max streak

    -- also return the score as the result for the activity
	msg.outActivityRating = msg.fValue1
	return msg

end


--------------------------------------------------------------
-- Sent from a player when responding from a messagebox
--------------------------------------------------------------
function onMessageBoxRespond(self, msg)

	-- make sure this is the right player
	local player = getObjectByName("activityPlayer")
	if (player:GetID() == msg.sender:GetID()) then

		if msg.identifier == "Shooting_Gallery_Summary" then
			strText = "Retry?"
			-- show the summary message box
			player:DisplayMessageBox{bShow = true,
									 imageID = 2,
									 callbackClient = GAMEOBJ:GetZoneControlID(),
									 text = strText,
									 identifier = "Shooting_Gallery_Retry"}
		else
			-- User wants to retry or is closing the big help to start the game
			if ((msg.iButton == 1 and msg.identifier == "Shooting_Gallery_Retry") or
				(msg.identifier == "SkunkSG")) then

				startGame(self)

			-- User wants to quit
			elseif (msg.iButton == 0 and msg.identifier == "Shooting_Gallery_Retry") then

				-- called before we leave the cannon, so we can trigger a loading screen
				-- as soon as possible. Should still remove player from cannon on server
				RemovePlayerFromZone(self, player)

				-- get the cannon and exit
				local cannon = getObjectByName("cannonObject")
				if (cannon) then
					cannon:RequestActivityExit{userID = player, bUserCancel = false}
				end

			end
		end

	end

end


--------------------------------------------------------------
-- Sent from the spawn objects on death
--------------------------------------------------------------
function onUpdateMissionTask(self, msg)
	if msg.taskType ~= "kill" then
		-- get this wave number
		local waveNum = tonumber(LOCALS["ThisWave"])

		if (LOCALS["GameStarted"] == true) and (waveNum) and (waveNum > 0) then

			-- get the spawn data (@TODO: Need to Optimize)
			local spawnData = msg.target:GetVar("SpawnData")

			-- spawn the right object
			if (spawnData) and (spawnData.sdRespawn == true) then
				SpawnObject(spawnData.sdnum,spawns[waveNum][spawnData.sdnum],self,false)
			end

			-- check for time adding, disregard if death was SILENT
			if (spawnData.sdTimeScore > 0.0 and msg.taskType ~= "SILENT") then
				AddTimeToWave(self,spawnData.sdTimeScore)
			end

		end
	end
end

--------------------------------------------------------------
-- User is exiting via cancel
--------------------------------------------------------------
function onRequestActivityExit(self, msg)

	if (msg.bUserCancel == true) then
		stopGame(self,msg.bUserCancel)
		RemovePlayerFromZone(self, msg.userID)
	end

end


--------------------------------------------------------------
-- Cannon is firing
--------------------------------------------------------------
function onShootingGalleryFire(self, msg)

	-- play fire animation on actors
	PlaySceneAnimation("fire", false, false)
	PlaySceneEffect("fire")

end

function onNotifyObject(self, msg)
	if msg.name == "escaped" then
			--skunk has escaped, penalize player
			local score = msg.ObjIDSender:GetActivityPoints()
			score.points = score.points * -1
			msg.ObjIDSender:NotifyObject{name = "setpoints", param1 = score.points, param2 = score.addTime}
			getObjectByName("cannonObject"):UpdateMissionTask{target = msg.ObjIDSender, taskType = "kill"}
	end
end