scope PedestalReceive initializer init
	import Units
	import Game
	import TerrainData
	import RegisterPlayerUnitEvent
	import SoundControl
	import DummyUnitStack

	constant string  DUMMY_MODEL         = "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl"
	constant string  EFFECT_MODEL        = "Abilities\\Spells\\Human\\HolyBolt\\HolyBoltSpecialArt.mdl"
	constant string  RUNE_SECURED        = "rune-secured.mp3"
	constant integer PEDESTAL_ID         = 'h003'
	constant integer SPAWN_COUNT         =  20
	constant real    ENUM_EPSILON        =  32.
	constant vec3    TARGET_PILLAR_LEFT  = vec3(-1630., 3798., 100.)
	constant vec3    TARGET_PILLAR_RIGHT = vec3(-1470., 3644., 100.)

	// matches gameplay constant - "Inventory - Drop Item Range"
	constant real    ITEM_DROP_OFFS     = 100.
	constant real	 ITEM_SPAWN_HEIGHT  =  40.
	constant real    SPAWN_PERIOD       =   1. / 10.
	constant real    INITIAL_PITCH      =  13. * PI / 32.
	constant real    INITIAL_VELOCITY   = 500.
	constant real    ACCELERATION       =  80.
	constant real    CLOCK_PERIOD       =   1. / 30.
	constant real    AIR_FRICTION       = CLOCK_PERIOD * 7. / 5.

	struct Effect
		vec3 velocity
		vec3 target
		unit dummy
		effect attached
	end

	timer time    = CreateTimer()
	timer time2   = CreateTimer()
	group grp     = CreateGroup()
	rect  rctEpsilon
	item fakeRune = CreateItem('I000', TerrainData.SAFE_X, TerrainData.SAFE_Y)
	integer spawnCount
	integer effectIndex = -1
	Effect array fxDb

	function fxSpawn3 takes nothing returns nothing
		integer index = 0
		Effect iter
		vec3 diff
		real dX
		real dY
		real dH

		loop
			exitwhen index > effectIndex
			iter = fxDb[index]

			dX = iter.dummy.getX()
			dY = iter.dummy.getY()
			dH = iter.dummy.getFlyHeight()

			diff = iter.target - vec3(dX, dY, dH)

			iter.velocity += ACCELERATION * CLOCK_PERIOD * diff.norm()
			iter.velocity *= (1. - AIR_FRICTION)

			iter.dummy.setX(dX + iter.velocity.x)
			iter.dummy.setY(dY + iter.velocity.y)
			iter.dummy.setFlyHeight(dH + iter.velocity.z, 0.)

			if Game.roundEnabled or vec3(dX + iter.velocity.x, dY + iter.velocity.y, dH + iter.velocity.z).distToVec(iter.target) < 2. * iter.velocity.length() then
				iter.attached.destr()
				iter.dummy.setX(iter.target.x)
				iter.dummy.setY(iter.target.y)
				iter.dummy.setFlyHeight(iter.target.z, 0.)
				AddSpecialEffectTarget(EFFECT_MODEL, iter.dummy, "origin").destr()
				DummyUnitStack.delayedRelease(iter.dummy, 1.)

				destroy iter
				fxDb[index] = fxDb[effectIndex]
				effectIndex--
				index--

				if effectIndex == -1 then
					time2.pause()
				end
			end

			index++
		end
	end

	function fxSpawn2 takes nothing returns nothing
		Effect fx
		real randTarget  = GetRandomReal(0., 1.)
		real randAng     = GetRandomReal(0., 2. * PI)

		if spawnCount > 0 and not Game.roundEnabled then
			fx = new Effect()
			fx.velocity = vec3(INITIAL_VELOCITY * CLOCK_PERIOD * Cos(INITIAL_PITCH) * Cos(randAng), INITIAL_VELOCITY * CLOCK_PERIOD * Cos(INITIAL_PITCH) * Sin(randAng), INITIAL_VELOCITY * CLOCK_PERIOD * Sin(INITIAL_PITCH))
			fx.dummy = DummyUnitStack.get()
			fx.attached = AddSpecialEffectTarget(DUMMY_MODEL, fx.dummy, "origin")
			fx.dummy.setFlyHeight(ITEM_SPAWN_HEIGHT, 0.)
			fx.dummy.setPos(GetItemX(fakeRune), GetItemY(fakeRune))

			if randTarget < .5 then
				fx.target = TARGET_PILLAR_LEFT
			else
				fx.target = TARGET_PILLAR_RIGHT
			end

			effectIndex++
			fxDb[effectIndex] = fx
			if effectIndex == 0 then
				time2.startPeriodic(CLOCK_PERIOD, function fxSpawn3)
			end

			spawnCount--
		else
			time.pause()
			fakeRune.setPos(TerrainData.SAFE_X, TerrainData.SAFE_Y)
		end
	end

	function fxSpawn takes unit u, real facing returns nothing
		fakeRune.setPos(GetUnitX(u) + ITEM_DROP_OFFS * Cos(facing), GetUnitY(u) + ITEM_DROP_OFFS * Sin(facing))
		spawnCount = SPAWN_COUNT
		TimerStart(time, SPAWN_PERIOD, true, function fxSpawn2)
	end

	function act takes nothing returns nothing
		unit iter

		// search group for artifact
		GroupEnumUnitsInRect(grp, rctEpsilon, null)
		loop
			iter = FirstOfGroup(grp)
			exitwhen iter == null
			if (UnitHasItem(iter, Units.artifact) or UnitHasItem(iter, Units.artifact2)) and Game.roundEnabled then
				SoundControl.play(RUNE_SECURED, 1., 127)
				FogEnable(false)
				PanCameraToTimed(GetUnitX(iter), GetUnitY(iter), 0.)
				SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 1024., 0.)
				fxSpawn(iter, iter.getFacing())

				Game.hunterWin()
				SetItemPosition(Units.artifact,  TerrainData.SAFE_X, TerrainData.SAFE_Y)
				SetItemPosition(Units.artifact2, TerrainData.SAFE_X, TerrainData.SAFE_Y)

				exitwhen true
			end
			GroupRemoveUnit(grp, iter)
		end
	end

	function init takes nothing returns nothing
		trigger trig = CreateTrigger()
		rect    rct  = Rect(TerrainData.HALL_MIN_X, TerrainData.HALL_MIN_Y, TerrainData.HALL_MAX_X, TerrainData.HALL_MAX_Y)
		region  reg  = CreateRegion()
		RegionAddRect(reg, rct)
		rctEpsilon = Rect(TerrainData.HALL_MIN_X - ENUM_EPSILON, TerrainData.HALL_MIN_Y - ENUM_EPSILON, TerrainData.HALL_MAX_X + ENUM_EPSILON, TerrainData.HALL_MAX_Y + ENUM_EPSILON)

		registerPlayerUnitEvent(EVENT_PLAYER_UNIT_PICKUP_ITEM, function act)
		TriggerRegisterEnterRegion(trig, reg, null)
		TriggerAddAction(trig, function act)

		SoundControl.preload(RUNE_SECURED)

		RemoveRect(rct)
	end
endscope
