1. Are you planning to upload your awesome map to Hive? Please review the rules here.
    Dismiss Notice
  2. And she's bought a stairway to heaven. The 6th Special Effect Contest Results are here.
    Dismiss Notice
  3. Seek unity between the elements in the 22nd Terraining Contest Poll.
    Dismiss Notice
  4. Seize the moment! The 18th Mini Mapping Contest has commenced.
    Dismiss Notice
  5. The heavens smile on the old faithful. The 16th Techtree Contest has begun.
    Dismiss Notice
  6. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

Trigger Viewer

Combat Zone 3.7.w3x
Variables
Main
Initialization
Arrows
Loop
Tickets
Show Tickets
Toggle Radar
Toggle Cam
Increase Speed
Decrease Speed
Machine Gun
Flame Thrower
Plasma Rifle
Gun
Bombs
Aiming Rockets
Rocket Hail
Rapid Artillery Fire
Anti Air Rockets
Nuclear Missile
Missile Flare
Increase Height
Decrease Height
Tank Projectiles
Grenade
Artillery Shot
Nuclear Grenade
Plasma Bomb
Gravity Gun
Beam
Photon Cannon
Smoke Grenade
Explode
Teleport
Get On
Get Off
Parachute
Repair
Player Leaves
Console
//TESH.scrollpos=0
//TESH.alwaysfold=0
//===========================================================================
//
// TIMER AND ATTACHMENT FUNCTIONS
//
//===========================================================================

function H2I takes handle h returns integer
	return GetHandleId(h)
	return 0
endfunction

function NewTimerIndex takes timer h returns integer
	local integer hi=H2I(h)
	local integer i=hi-(hi/8000)*8000
	loop
		exitwhen udg_AV_Handles[i]==0
		set i=i+1
	endloop
	set udg_AV_Handles[i]=hi
	set udg_AV_Timers[i]=h
	return i
endfunction

function GetHandleIndex takes handle h returns integer
	local integer hi=H2I(h)
	local integer i=hi-(hi/8000)*8000
	loop
		exitwhen udg_AV_Handles[i]==hi
		set i=i+1
	endloop
	return i
endfunction

function ReleaseHandleIndex takes integer i returns nothing
	set udg_AV_Handles[i] = 0
	set udg_AV_Timers[i] = null
	set udg_AV_Int1[i] = 0
endfunction

function NewTimer takes nothing returns timer
	if udg_TimerStackN==0 then
		set udg_TimerStack[0]=CreateTimer()
		return udg_TimerStack[0]
	endif
	set udg_TimerStackN=udg_TimerStackN-1
	return udg_TimerStack[udg_TimerStackN]
endfunction

function ReleaseTimer takes timer t returns nothing
	call PauseTimer(t)
	set udg_TimerStack[udg_TimerStackN]=t
	set udg_TimerStackN=udg_TimerStackN+1
endfunction

//===========================================================================
//
// MISC FUNCTIONS
//
//===========================================================================

function GetLetterSize takes string s returns real
	if s=="|" then
		return 1.5
	elseif s=="'" or s==":" or s==";" or s=="." or s=="," then
		return 4.0
	elseif s=="1" or s=="i" or s=="!" then
		return 5.0
	elseif s=="l" or s=="I" or s=="j" or s=="(" or s=="[" or s=="]" or s=="{" or s=="}" then
		return 6.0
	elseif s==" " or s=="\"" or s==")" or s=="J" then
		return 7.0
	elseif s=="r" or s=="f" or s=="`" or s=="´" then
		return 8.0
	elseif s=="t" or s=="-" or s=="\\" or s=="*" then
		return 9.0
	elseif s=="F" then
		return 10.0
	elseif s=="s" or s=="/" or s=="?" then
		return 11.0
	elseif s=="E" or s=="L" or s=="7" or s=="+" or s=="=" or s=="<" or s==">" or s=="$" or s=="§" then
		return 12.0
	elseif s=="a" or s=="k" or s=="T" or s=="c" or s=="S" or s=="n" or s=="z" or s=="P" or s=="3" or s=="5" or s=="ä" or s=="_" or s=="~" or s=="°" or s=="^" then
		return 13.0
	elseif s=="b" or s=="B" or s=="6" or s=="v" or s=="e" or s=="x" or s=="y" or s=="2" or s=="9" or s=="h" or s=="u" or s=="ü" then
		return 14.0
	elseif s=="o" or s=="d" or s=="0" or s=="g" or s=="8" or s=="4" or s=="q" or s=="p" or s=="ö" or s=="ß" then
		return 15.0
	elseif s=="C" or s=="R" or s=="Z" or s=="V" or s=="Y" or s=="D" or s=="K" or s=="U" or s=="Ü" or s=="#" then
		return 16.0
	elseif s=="N" or s=="H" or s=="%" or s=="%%" then
		return 17.0
	elseif s=="G" or s=="X" or s=="@" then
		return 18.0
	elseif s=="A" or s=="Ä" then
		return 19.0
	elseif s=="w" or s=="O" or s=="Ö" then
		return 20.0
	elseif s=="m" or s=="Q" or s=="&" then
		return 21.0
	elseif s=="M" then
		return 25.0
	elseif s=="W" then
		return 26.0
	endif
	return 10.0
endfunction

function CenterString takes string s, real WantedSize returns string
	local real SizeToFill = WantedSize
	local integer Length = StringLength(s)
	local integer i = 0
	local integer Spaces
	local string SpacesFrom="                                                                                                    "
	local string ReturnString=s
	loop
		exitwhen i >= Length
		if SubString(s, i, i+2)=="|c" or SubString(s, i, i+2)=="|C" then
			set i = i + 10
		elseif SubString(s, i, i+2)=="|r" or SubString(s, i, i+2)=="|R" then
			set i = i + 2
		elseif SubString(s, i, i+1)=="\n" then
			return CenterString(SubString(s,0,i),WantedSize)+"\n"+CenterString(SubString(s,i+1,Length),WantedSize)
		else
			set SizeToFill = SizeToFill - GetLetterSize(SubString(s, i, i+1))
			set i = i + 1
		endif
	endloop
	set Spaces = R2I(SizeToFill/14+0.5)
	loop
		exitwhen Spaces<=0
		if Spaces<100 then
			set ReturnString = SubString(SpacesFrom,0,Spaces)+ReturnString
			set Spaces = 0
		else
			set ReturnString = SpacesFrom+ReturnString
			set Spaces = Spaces - 100
		endif
	endloop
	return ReturnString
endfunction

function ShowMessage takes integer PlayerId, string Msg returns nothing
	local string CenteredString = CenterString(Msg,650)
	if udg_constLocalPlayerId == PlayerId then
		call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.5, 0.7, 5, CenteredString)
	endif
endfunction

function ShowMessageAll takes string Msg returns nothing
	call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.5, 0.7, 5, CenterString(Msg,650))
endfunction

function AddUnitClass takes integer unitId, real AccelerationHigh, real AccelerationLow, real GroundFriction, real GroundFrictionSide, real TerrainInfluence, real AirFriction, real AirFrictionSide, real AirFrictionTop, real WingAngle, real Breaks, real Rotation, real RotationZ, real RotationFriction, real Collision, real CollisionOffset, real HoverHeight, real BulletOffsetZ, real Knockback, real GravityFactor, real Scale, string ModelPath returns integer
	local integer id = udg_classMaxId+1
	set udg_classMaxId = udg_classMaxId+1
	set udg_classUnitType[id] = unitId
	set udg_classKnockback[id] = Knockback
	set udg_classWingAngle[id] = WingAngle
	set udg_classAccelerationHigh[id] = AccelerationHigh
	set udg_classAccelerationLow[id] = AccelerationLow
	set udg_classGroundFriction[id] = GroundFriction
	set udg_classGroundFrictionSide[id] = GroundFrictionSide
	set udg_classTerrainInfluence[id] = TerrainInfluence
	set udg_classAirFriction[id] = AirFriction
	set udg_classAirFrictionSide[id] = AirFrictionSide
	set udg_classAirFrictionTop[id] = AirFrictionTop
	set udg_classHasAnySideFriction[id] = (AirFrictionTop!=0) or (AirFrictionSide!=0) or (GroundFrictionSide!=0)
	set udg_classBreaks[id] = Breaks
	set udg_classRotation[id] = Rotation
	set udg_classRotationZ[id] = RotationZ
	set udg_classRotationFriction[id] = RotationFriction
	set udg_classCollision[id] = Collision
	set udg_classCollisionOffset[id] = CollisionOffset
	set udg_classBulletOffsetZ[id] = BulletOffsetZ
	set udg_classHoverHeight[id] = HoverHeight
	set udg_classModelPath[id] = ModelPath
	set udg_classModelScale[id] = Scale
	set udg_classGravityFactor[id] = GravityFactor
	if Collision > udg_constUnitMaxCollision then
		set udg_constUnitMaxCollision = Collision
	endif
	return id
endfunction

function AddEnvironmentClass takes integer destructableId, real sizeX, real sizeY, real sizeZ, real sizeXYBuffer returns nothing
	local integer id = destructableId-'B000'
	set udg_doodadSizeX[id] = sizeX/2
	set udg_doodadSizeY[id] = sizeY/2
	set udg_doodadSizeZ[id] = sizeZ
	set udg_doodadBuffer[id] = sizeXYBuffer
endfunction

function SetControllerDummy takes integer PlayerId returns nothing
	if udg_playerControllerDummy[PlayerId]!=null then
		call RemoveUnit(udg_playerControllerDummy[PlayerId])
	endif
	set udg_playerControllerDummy[PlayerId] = CreateUnit(Player(PlayerId), udg_classUnitType[udg_objClass[udg_playerControlledObj[PlayerId]]], 14336, -18432, 270)
	call SetUnitPathing(udg_playerControllerDummy[PlayerId],false)
	call SetUnitState(udg_playerControllerDummy[PlayerId], UNIT_STATE_LIFE, GetUnitState(udg_objUnit[udg_playerControlledObj[PlayerId]], UNIT_STATE_LIFE))
	call SetUnitState(udg_playerControllerDummy[PlayerId], UNIT_STATE_MANA, GetUnitState(udg_objUnit[udg_playerControlledObj[PlayerId]], UNIT_STATE_MANA))
	if udg_objClass[udg_playerControlledObj[PlayerId]]!=udg_uSoldier then
		call SetUnitColor(udg_playerControllerDummy[PlayerId], ConvertPlayerColor(15))
	endif
	call ClearSelection()
	call SelectUnit(udg_playerControllerDummy[udg_constLocalPlayerId], true)
endfunction

function SetUnitZFacing takes unit whichUnit, real facingAngle returns nothing
	local integer i = R2I(facingAngle*0.7+0.5)
	if i>0 then
		call SetUnitAnimationByIndex(whichUnit, i)
	else
		call SetUnitAnimationByIndex(whichUnit, i+252)
	endif
endfunction

function AddObj takes player Owner, integer Class, real X, real Y, real Z, real Angle, real AngleZ returns integer
	local unit Obj = CreateUnit(Owner,udg_classUnitType[Class],14336, -18432,Angle)
	local integer ObjId = 0
	call ShowUnit(Obj,false)
	loop
		exitwhen udg_objUnit[ObjId]==null
		set ObjId = ObjId+1
	endloop
	set udg_objUnit[ObjId] = Obj
	if ObjId > udg_objMaxId then
		set udg_objMaxId = ObjId
	endif
	call SetUnitUserData(udg_objUnit[ObjId],ObjId)
	set udg_objStartX[ObjId] = X
	set udg_objStartY[ObjId] = Y
	set udg_objStartZ[ObjId] = Z
	set udg_objStartAngle[ObjId] = Angle
	set udg_objX[ObjId] = X
	set udg_objY[ObjId] = Y
	set udg_objZ[ObjId] = Z
	set udg_objAngle[ObjId] = Angle
	set udg_objAngleZ[ObjId] = AngleZ
	set udg_objRotateSpeed[ObjId] = 0
	set udg_objRotateZSpeed[ObjId] = 0
	set udg_objMGShots[ObjId] = 0
	set udg_objFlameShots[ObjId] = 0
	set udg_objPlasmaShots[ObjId] = 0
	set udg_objBombDrops[ObjId] = 0
	set udg_objAcceleration[ObjId] = 0
	set udg_objLifeSpan[ObjId] = -1
	set udg_objSpeedX[ObjId] = 0
	set udg_objSpeedY[ObjId] = 0
	set udg_objSpeedZ[ObjId] = 0
	set udg_objUnitAim[ObjId] = null
	set udg_objDead[ObjId] = false
	set udg_objAI[ObjId] = false
	set udg_objAIFlareCooldown[ObjId] = 0
	set udg_objAIWeaponCooldown[ObjId] = 0
	set udg_objAITargetPlayer[ObjId] = 0
	set udg_objClass[ObjId] = Class
	set udg_objLastEnvironmentHeight[ObjId] = 0
	set udg_objIsProjectile[ObjId] = (GetUnitAbilityLevel(Obj,'Aloc')==1)
	set udg_objFollowingRockets[ObjId] = 0
	call SetUnitPathing(Obj,false)
	call SetUnitScale(Obj,udg_classModelScale[udg_objClass[ObjId]],udg_classModelScale[udg_objClass[ObjId]],udg_classModelScale[udg_objClass[ObjId]])
	call SetUnitFlyHeight(Obj,Z,0)
	if udg_classModelPath[udg_objClass[ObjId]]=="" then
		call SetUnitAnimation( Obj, "walk" )
		call SetUnitTimeScale(Obj, 0)
	else
		set udg_objModel[ObjId]=AddSpecialEffectTarget(udg_classModelPath[Class],Obj,"origin")
		call SetUnitAnimation( Obj, "stand" )
		if udg_objIsProjectile[ObjId] then
			call SetUnitTimeScale(Obj, 100.0)
		endif
		call SetUnitZFacing(Obj, AngleZ)
	endif
	if not udg_objIsProjectile[ObjId] then
		call SetUnitPosition(Obj,X,Y)
	else
		call SetUnitX(Obj,X)
		call SetUnitY(Obj,Y)
	endif
	call ShowUnit(Obj,true)
	set Obj = null
	return ObjId
endfunction

function CreateStartingUnit takes integer PlayerId returns unit
	local integer ObjId = AddObj(Player(PlayerId), udg_uSoldier, GetStartLocationX(GetPlayerStartLocation(Player(PlayerId))), GetStartLocationY(GetPlayerStartLocation(Player(PlayerId))), 0, ModuloReal(PlayerId*180+225, 360),0)
	set udg_playerControlledObj[PlayerId]=ObjId
	call SetControllerDummy(PlayerId)
	return udg_objUnit[ObjId]
endfunction

function SpecialEffectScaledTimedWithZ_ChildRemove takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	call RemoveUnit(udg_AV_Unit[AV])
	call ReleaseHandleIndex(AV)
	call ReleaseTimer(t)
endfunction

function SpecialEffectScaledTimedWithZ_ChildKill takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	call DestroyEffect(udg_AV_Effect[AV])
	call ReleaseHandleIndex(AV)
	call ReleaseTimer(t)
endfunction

function SpecialEffectScaledTimedWithZ_ChildKillNoAttach takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	call KillUnit(udg_AV_Unit[AV])
	call ReleaseHandleIndex(AV)
	call ReleaseTimer(t)
endfunction

function SpecialEffectScaledTimedWithZ takes string modelName, real X, real Y, real Z, real Scale, real timeScale, real timeKill, real timeRemove returns unit
	local timer t
	local integer AV
	local boolean AttachEffect=true
	if modelName=="Abilities\\Weapons\\Mortar\\MortarMissile.mdl" then
		set AttachEffect=false
		set bj_lastCreatedUnit = CreateUnit(Player(15), 'h00C', 14336, -18432, GetRandomReal(0,360))
	elseif modelName=="A-Bomb.mdx" then
		set AttachEffect=false
		set bj_lastCreatedUnit = CreateUnit(Player(15), 'h00L', 14336, -18432, GetRandomReal(0,360))
	elseif modelName=="Smoke.mdx" then
		set AttachEffect=false
		set bj_lastCreatedUnit = CreateUnit(Player(15), 'h00E', 14336, -18432, GetRandomReal(0,360))
	else
		set bj_lastCreatedUnit = CreateUnit(Player(15), 'h008', 14336, -18432, GetRandomReal(0,360))
		call SetUnitZFacing(bj_lastCreatedUnit, 0)
	endif
	call ShowUnit(bj_lastCreatedUnit,false)
	call SetUnitUserData(bj_lastCreatedUnit,-1)
	call SetUnitPathing(bj_lastCreatedUnit, false)
	call SetUnitFlyHeight(bj_lastCreatedUnit, Z, 0)
	call SetUnitScale(bj_lastCreatedUnit, Scale, Scale, Scale)
	call SetUnitTimeScale(bj_lastCreatedUnit, timeScale)
	call SetUnitX(bj_lastCreatedUnit,X)
	call SetUnitY(bj_lastCreatedUnit,Y)
	call ShowUnit(bj_lastCreatedUnit,true)


	if timeKill==0 then
		if AttachEffect then
			call DestroyEffect(AddSpecialEffectTarget(modelName, bj_lastCreatedUnit, "origin"))
		else
			call KillUnit(bj_lastCreatedUnit)
		endif
	else
		set t = NewTimer()
		set AV = NewTimerIndex(t)
		if AttachEffect then
			set udg_AV_Effect[AV] = AddSpecialEffectTarget(modelName, bj_lastCreatedUnit, "origin")
			call TimerStart(t,timeKill,false, function SpecialEffectScaledTimedWithZ_ChildKill)
		else
			set udg_AV_Unit[AV] = bj_lastCreatedUnit
			call TimerStart(t,timeKill,false, function SpecialEffectScaledTimedWithZ_ChildKillNoAttach)
		endif
	endif
	if timeRemove==0 then
		call RemoveUnit(bj_lastCreatedUnit)
	else
		set t = NewTimer()
		set AV = NewTimerIndex(t)
		set udg_AV_Unit[AV] = bj_lastCreatedUnit
		call TimerStart(t,timeRemove,false, function SpecialEffectScaledTimedWithZ_ChildRemove)
	endif
	return bj_lastCreatedUnit
endfunction

function AddSpecialEffectTimed_Child takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	call DestroyEffect(udg_AV_Effect[AV])
	set udg_AV_Effect[AV] = null
	call ReleaseHandleIndex(AV)
	call ReleaseTimer(t)
endfunction

function AddSpecialEffectTimed takes string modelName, real x, real y, real duration returns nothing
	local timer t = NewTimer()
	local integer AV = NewTimerIndex(t)
	set udg_AV_Effect[AV] = AddSpecialEffect(modelName,x,y)
	call TimerStart(t,duration,false, function AddSpecialEffectTimed_Child)
endfunction

function RemoveUnitTimed_Child takes nothing returns nothing
	local unit U = bj_lastCreatedUnit
	call TriggerSleepAction( bj_cineFadeContinueDuration )
	call RemoveUnit(U)
	set U = null
endfunction

function RemoveUnitTimed takes unit U, real Time returns nothing
	set bj_lastCreatedUnit = U
	set bj_cineFadeContinueDuration = Time
	call ExecuteFunc("RemoveUnitTimed_Child")
endfunction

function MakeSoldierVulnerable takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	local integer PlayerId = udg_AV_Int1[AV]
	call SetUnitInvulnerable(udg_objUnit[udg_playerControlledObj[PlayerId]], false)
	call SetUnitInvulnerable(udg_playerControllerDummy[PlayerId], false)
	call ReleaseTimer(t)
	call ReleaseHandleIndex(AV)
endfunction

function RespawnSoldier takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	local unit U = null
	local integer PlayerId = udg_AV_Int1[AV]
	if GetPlayerSlotState(Player(PlayerId)) == PLAYER_SLOT_STATE_PLAYING then
		set U = CreateStartingUnit(PlayerId)
		call SetUnitInvulnerable(U, true)
		call SetUnitInvulnerable(udg_playerControllerDummy[PlayerId], true)
		call TimerStart(t, 5, false, function MakeSoldierVulnerable)
	else
		call ReleaseTimer(t)
		call ReleaseHandleIndex(AV)
	endif
endfunction

function RespawnVehicle takes nothing returns nothing
	local timer t = GetExpiredTimer()
	local integer AV = GetHandleIndex(t)
	local integer NewObjId = AddObj(Player(15),udg_AV_Int1[AV],udg_AV_X[AV],udg_AV_Y[AV],udg_AV_Z[AV],udg_AV_Angle[AV],0)
	call ReleaseTimer(t)
	call ReleaseHandleIndex(AV)
endfunction

function TargetEliminated takes unit Killer, unit U returns nothing
	local integer PlayerId = GetPlayerId(GetOwningPlayer(U))
	local integer UnitClass
	local integer DeadObjId = GetUnitUserData(U)
	local integer NewObjId
	local integer PlayerIdKiller = GetPlayerId(GetOwningPlayer(Killer))
	local real StartX
	local real StartY
	local real StartZ
	local real StartAngle
	local boolean RecreateSoldier = (DeadObjId==udg_playerControlledObj[PlayerId])
	local boolean DoRespawnVehicle = (GetUnitAbilityLevel(U,'A005')>0) and (not udg_objAI[DeadObjId])
	local timer t
	local integer AV
	if PlayerIdKiller>11 then
		set PlayerIdKiller=-1
	endif
	if DoRespawnVehicle then
		set UnitClass = udg_objClass[DeadObjId]
		if udg_classAccelerationLow[UnitClass]<0 then
			set udg_objAcceleration[DeadObjId] = udg_classAccelerationLow[UnitClass]
		else
			set udg_objAcceleration[DeadObjId] = 0
		endif
		set t = NewTimer()
		call TimerStart(t, udg_constVehicleRespawnTime, false, function RespawnVehicle)
		set AV = NewTimerIndex(t)
		set udg_AV_Angle[AV] = udg_objStartAngle[DeadObjId]
		set udg_AV_X[AV] = udg_objStartX[DeadObjId]
		set udg_AV_Y[AV] = udg_objStartY[DeadObjId]
		set udg_AV_Z[AV] = udg_objStartZ[DeadObjId]
		set udg_AV_Int1[AV] = UnitClass
	endif
	if PlayerIdKiller!=PlayerId and (RecreateSoldier or udg_objAI[DeadObjId]) then
		if PlayerIdKiller!=-1 then
			set udg_playerKills[PlayerIdKiller] = udg_playerKills[PlayerIdKiller] + 1
			call SetPlayerState(Player(PlayerIdKiller),PLAYER_STATE_RESOURCE_GOLD,udg_playerKills[PlayerIdKiller])
			if PlayerId>9 then
				call ShowMessage(PlayerIdKiller, "|cff00cc00You have killed a bot!|r")
			else
				call ShowMessage(PlayerIdKiller, "|cff00cc00You have killed " +GetPlayerName(Player(PlayerId))+"!|r")
			endif
		endif
	endif
	if RecreateSoldier then
		if PlayerId/2*2==PlayerId then
			set udg_Team1Tickets = udg_Team1Tickets - 1
		else
			set udg_Team2Tickets = udg_Team2Tickets - 1
		endif
		set U = udg_objUnit[udg_playerControlledObj[PlayerId]]
		set udg_playerDeaths[PlayerId] = udg_playerDeaths[PlayerId] + 1
		call SetPlayerState(Player(PlayerId),PLAYER_STATE_RESOURCE_LUMBER,udg_playerDeaths[PlayerId])
		call SetPlayerState(Player(PlayerId),PLAYER_STATE_RESOURCE_FOOD_USED,0)
		if GetLocalPlayer()==Player(PlayerId) then
			set udg_playerCamShake1 = 0
			set udg_playerCamShake2 = 0
			set udg_playerCamShake3 = 0
		endif
		set udg_playerControlledObj[PlayerId] = -1
		if PlayerIdKiller==-1 or PlayerIdKiller==PlayerId then
			call ShowMessage(PlayerId, "|cffcc0000You have killed yourself!|r")
		elseif PlayerIdKiller>9 then
			call ShowMessage(PlayerId, "|cffcc0000A bot has killed you!|r")
		else
			call ShowMessage(PlayerId, "|cffcc0000"+GetPlayerName(Player(PlayerIdKiller))+" has killed you!|r")
		endif


		set t = NewTimer()
		call TimerStart(t, 5, false, function RespawnSoldier)
		set AV = NewTimerIndex(t)
		set udg_AV_Int1[AV] = PlayerId
		call RemoveUnit(udg_playerControllerDummy[PlayerId])
	endif
	if udg_objClass[DeadObjId]!=udg_uSoldier then
		set udg_objDeathFire[DeadObjId] = CreateUnit(Player(PlayerId),'h008',14336, -18432,udg_objAngle[DeadObjId])
		call SetUnitX(udg_objDeathFire[DeadObjId],udg_objX[DeadObjId])
		call SetUnitY(udg_objDeathFire[DeadObjId],udg_objY[DeadObjId])
		call SetUnitUserData(udg_objDeathFire[DeadObjId],-1)
		set udg_objDeathFireEffect1[DeadObjId] = AddSpecialEffectTarget("Environment\\LargeBuildingFire\\LargeBuildingFire1.mdl", udg_objDeathFire[DeadObjId], "origin")
		set udg_objDeathFireEffect2[DeadObjId] = AddSpecialEffectTarget("Abilities\\Spells\\Other\\BreathOfFire\\BreathOfFireDamage.mdl", udg_objDeathFire[DeadObjId], "origin")
		call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl", udg_objX[DeadObjId],udg_objY[DeadObjId], udg_objZ[DeadObjId], 1, 1, 0, 2)
	else
		call SpecialEffectScaledTimedWithZ("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl", udg_objX[DeadObjId],udg_objY[DeadObjId], udg_objZ[DeadObjId], 1, 1, 0, 2)
	endif
	set udg_objMGShots[DeadObjId] = 0
	set udg_objFlameShots[DeadObjId] = 0
	set udg_objPlasmaShots[DeadObjId] = 0
	set udg_objBombDrops[DeadObjId] = 0
	set U = null
endfunction

function UnitKnockBack takes unit Obj, real SourceX, real SourceY, real SourceZ, real Power returns nothing
	local integer ObjId = GetUnitUserData(Obj)
	local real DistX = GetUnitX(Obj)-SourceX
	local real DistY = GetUnitY(Obj)-SourceY
	local real DistZ = udg_objZ[ObjId]+udg_classCollisionOffset[udg_objClass[ObjId]]-SourceZ
	local real DistXY = SquareRoot(DistX*DistX+DistY*DistY)
	local real DmgAngle = Atan2(DistY, DistX)
	local real DmgAngleZ = Atan2(DistZ, DistXY)
	local real Speed = Power*udg_constKnockback*udg_classKnockback[udg_objClass[ObjId]]/2
	set udg_objSpeedX[ObjId] = udg_objSpeedX[ObjId]+Speed*Cos(DmgAngle)*Cos(DmgAngleZ)
	set udg_objSpeedY[ObjId] = udg_objSpeedY[ObjId]+Speed*Sin(DmgAngle)*Cos(DmgAngleZ)
	set udg_objSpeedZ[ObjId] = udg_objSpeedZ[ObjId]+Speed*Sin(DmgAngleZ)
endfunction

function UnitDamageTargetSync takes unit Source, unit Target, real Damage returns nothing
	local integer i = GetPlayerId(GetOwningPlayer(Target))
	local real Life = GetUnitState(Target,UNIT_STATE_LIFE)
	if Source!=null and GetUnitAbilityLevel(Target,'Avul')==0 and not udg_playerNoDamage[i] then
		if Damage*udg_constDamage>=Life-0.5 then
			call SetUnitAnimation( Target, "death" )
			if not udg_objDead[GetUnitUserData(Target)] then
				set udg_objDead[GetUnitUserData(Target)]=true
				call TargetEliminated(Source,Target)
			endif
			call UnitDamageTarget(Source, Target, Life-0.5, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS)
		else
			call UnitDamageTarget(Source, Target, Damage*udg_constDamage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS)
		endif
		if Damage>0 then
			if Target == udg_objUnit[udg_playerControlledObj[i]] then
				if GetLocalPlayer()==Player(i) and Damage>0 then
					set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*Damage,-150),150)
					set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*Damage,-150),150)
					set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*Damage,-150),150)
				endif
				if udg_objDead[GetUnitUserData(Target)] then
					call UnitDamageTarget(Source, udg_playerControllerDummy[i], GetUnitState(udg_playerControllerDummy[i],UNIT_STATE_LIFE), true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS)
				else
					call UnitDamageTarget(Source, udg_playerControllerDummy[i], Damage*udg_constDamage, true, false, ATTACK_TYPE_NORMAL, DAMAGE_TYPE_UNKNOWN, WEAPON_TYPE_WHOKNOWS)
				endif
			endif
			if Source==Target then
				call UnitKnockBack(Target,GetUnitX(Source),GetUnitY(Source),GetUnitFlyHeight(Source)-1, Damage/5)
			else
				call UnitKnockBack(Target,GetUnitX(Source),GetUnitY(Source),GetUnitFlyHeight(Source)-1, Damage)
			endif
		endif
	endif
endfunction

function IsTargetNearby takes unit Source, real X, real Y, real Z, real Range, boolean DamageAllies returns boolean
	local unit U
	local integer TargetClass
	local integer TargetObjId
	call GroupEnumUnitsInRange( udg_tempGroup, X, Y, Range+udg_constUnitMaxCollision+1, null )
	loop
		set U = FirstOfGroup( udg_tempGroup )
		exitwhen U == null
		set TargetObjId = GetUnitUserData(U)
		if TargetObjId!=-1 and (not udg_objIsProjectile[TargetObjId]) and ((DamageAllies or GetPlayerId(GetOwningPlayer(U))>11 or not IsUnitAlly(Source, GetOwningPlayer(U))) and U!=Source) then
			set TargetClass = udg_objClass[TargetObjId]
			if ((udg_objX[TargetObjId]-X)*(udg_objX[TargetObjId]-X)+(udg_objY[TargetObjId]-Y)*(udg_objY[TargetObjId]-Y)+(udg_objZ[TargetObjId]+udg_classCollisionOffset[TargetClass]-Z)*(udg_objZ[TargetObjId]+udg_classCollisionOffset[TargetClass]-Z)) <= (Range+udg_classCollision[TargetClass])*(Range+udg_classCollision[TargetClass]) then
				call GroupClear(udg_tempGroup)
				set U = null
				return true
			endif
		endif
		call GroupRemoveUnit( udg_tempGroup, U )
	endloop
	return false
endfunction

function UnitDamageArea takes unit Source, real X, real Y, real Z, real Range, real Damage, boolean DamageSelf, boolean DamageAllies returns boolean
	local unit U
	local real DistX
	local real DistY
	local real DistZ
	local real CurDmg
	local real CurDist
	local real MaxDist
	local integer TargetClass
	local integer TargetObjId
	local boolean TargetHit = false
	call GroupEnumUnitsInRange( udg_tempGroup, X, Y, Range+udg_constUnitMaxCollision+1, null )
	loop
		set U = FirstOfGroup( udg_tempGroup )
		exitwhen U == null
		set TargetObjId = GetUnitUserData(U)
		if TargetObjId!=-1 and (not udg_objIsProjectile[TargetObjId]) and ((DamageAllies or GetPlayerId(GetOwningPlayer(U))>11 or not IsUnitAlly(Source, GetOwningPlayer(U)) or U==Source) and (DamageSelf or U!=Source)) then
			set TargetClass = udg_objClass[TargetObjId]
			set DistX = udg_objX[TargetObjId]-X
			set DistY = udg_objY[TargetObjId]-Y
			set DistZ = udg_objZ[TargetObjId]+udg_classCollisionOffset[TargetClass]-Z
			set MaxDist = Range+udg_classCollision[TargetClass]
			set CurDist = SquareRoot(DistX*DistX+DistY*DistY+DistZ*DistZ)-udg_classCollision[TargetClass]
			if CurDist < MaxDist then
				if CurDist <= 0 then
					set CurDmg = Damage
				else
					set CurDmg = Damage*(Cos(bj_PI*CurDist/MaxDist)+1)/2
				endif
				call UnitDamageTargetSync(Source, U, CurDmg)
				set TargetHit = true
			endif
		endif
		call GroupRemoveUnit( udg_tempGroup, U )
	endloop
	return TargetHit
endfunction

function UnitsAreAllied takes unit U1, unit U2 returns boolean
	return GetPlayerId(GetOwningPlayer(U2))<12 and GetPlayerId(GetOwningPlayer(U1))<12 and IsUnitAlly(U1, GetOwningPlayer(U2))
endfunction

function DiffBetweenAngles takes real angle1, real angle2 returns real
	local real d=angle2-angle1
	if d<0 then
		set d=d+360
	endif
	if d>180 then
		return 360-d
	endif
	return d
endfunction

function DiffBetweenAngles3D takes real Angle1, real AngleZ1, real Angle2, real AngleZ2 returns real
	local real DiffAngle = DiffBetweenAngles(Angle1, Angle2)
	local real DiffAngleZ = DiffBetweenAngles(AngleZ1, AngleZ2)
	return SquareRoot(DiffAngle*DiffAngle + DiffAngleZ*DiffAngleZ)
endfunction

function DistToLine takes real LinePointX, real LinePointY, real LineAngle, real ToPointX, real ToPointY returns real
	local real DistX = ToPointX-LinePointX
	local real DistY = ToPointY-LinePointY
	local real diff = LineAngle-bj_RADTODEG*Atan2(DistY,DistX)
	if diff<0 then
		set diff = diff + 360
	endif
	if diff>180 then
		set diff = 360 - diff
	endif
	return SquareRoot(DistX*DistX+DistY*DistY)*Sin(diff)
endfunction

function GetEnvironmentHeight_Child takes nothing returns nothing
	local destructable d = GetEnumDestructable()
	local integer TypeId = GetDestructableTypeId(d)-'B000'
	local real X
	local real Y
	if bj_cineFadeContinueRed < udg_doodadSizeZ[TypeId] then
		set X = GetDestructableX(d)
		set Y = GetDestructableY(d)
		if X+udg_doodadSizeX[TypeId] < bj_cineFadeContinueGreen then
			set X = X+udg_doodadSizeX[TypeId]-bj_cineFadeContinueGreen
		elseif X-udg_doodadSizeX[TypeId] > bj_cineFadeContinueGreen then
			set X = X-udg_doodadSizeX[TypeId]-bj_cineFadeContinueGreen
		else
			set X = 0
		endif
		if Y+udg_doodadSizeY[TypeId] < bj_cineFadeContinueBlue then
			set Y = Y+udg_doodadSizeY[TypeId]-bj_cineFadeContinueBlue
		elseif Y-udg_doodadSizeY[TypeId] > bj_cineFadeContinueBlue then
			set Y = Y-udg_doodadSizeY[TypeId]-bj_cineFadeContinueBlue
		else
			set Y = 0
		endif
		if X*X+Y*Y<=bj_cineFadeContinueTrans+udg_doodadBuffer[TypeId]*udg_doodadBuffer[TypeId] then
			set bj_cineFadeContinueRed = udg_doodadSizeZ[TypeId]
		endif
	endif
	set d = null
endfunction

function GetEnvironmentHeight takes real X, real Y, real CollisionSize, real MinHeight returns real
	local real r = CollisionSize-5
	if MinHeight>.1 then
		set bj_cineFadeContinueRed = MinHeight-.1
	else
		set bj_cineFadeContinueRed = 0
	endif
	if X>-4800 and X<1200 and Y>-5100 and Y<1200 then
		if bj_cineFadeContinueRed>1090 then
			return 0
		endif
		call SetRect(udg_tempRect,X-280-r, Y-280-r, X+280+r, Y+280+r)
	else
		if bj_cineFadeContinueRed>188 then
			return 0
		endif
		call SetRect(udg_tempRect,X-140-r, Y-140-r, X+140+r, Y+140+r)
	endif
	set bj_cineFadeContinueGreen = X
	set bj_cineFadeContinueBlue = Y
	set bj_cineFadeContinueTrans = r*r
	call EnumDestructablesInRect(udg_tempRect, null, function GetEnvironmentHeight_Child)
	return bj_cineFadeContinueRed
endfunction

function ReduceDoodads_Child takes nothing returns nothing
	local destructable d = GetEnumDestructable()
	local integer TypeId = GetDestructableTypeId(d)-'B000'
	if udg_doodadSizeX[TypeId]+udg_doodadBuffer[TypeId]<31 and udg_doodadSizeY[TypeId]+udg_doodadBuffer[TypeId]<31 then
		call RemoveDestructable(d)
	endif
	set d = null
endfunction

function ReduceDoodads takes nothing returns nothing
	call SetRect(udg_tempRect,-18430, -17452, 14321, 14333)
	call EnumDestructablesInRect(udg_tempRect, null, function ReduceDoodads_Child)
endfunction

function GetAIOcclusionHeight takes real X, real Y returns real
	if X>-5900 and X<2300 and Y>-6200 and Y<2300 then
		return 1250.0
	endif
	return 350.0
endfunction

function AddBot takes integer unitType, integer TargetPlayer returns nothing
	local integer ObjId = AddObj(Player(11+(TargetPlayer-((TargetPlayer+1)/2)*2)), unitType, -1800, -1800, 3500, GetRandomReal(0,360),0)
	set udg_objAI[ObjId] = true
	set udg_objSpeedX[ObjId]=5*Cos(udg_objAngle[ObjId])
	set udg_objSpeedY[ObjId]=5*Sin(udg_objAngle[ObjId])
	set udg_objAngleZ[ObjId] = -15
	set udg_objAITargetPlayer[ObjId] = TargetPlayer
	set udg_objAIWeaponCooldown[ObjId] = 0
endfunction

function SetCloudCount takes integer countClouds returns nothing
	local integer i = 0
	local unit U
	local real Scale
	call GroupEnumUnitsInRange( udg_tempGroup, 0, 0, 50000, null )
	loop
		set U = FirstOfGroup(udg_tempGroup)
		exitwhen U==null
		if GetUnitTypeId(U)=='h00W' then
			call RemoveUnit(U)
		endif
		call GroupRemoveUnit(udg_tempGroup,U)
	endloop
	set i = 1
	loop
		exitwhen i > countClouds
		set U = CreateUnit(Player(15),'h00W',GetRandomReal(-17000,13000),GetRandomReal(-17000,13000),GetRandomReal(0,360))
		call SetUnitFlyHeight(U,GetRandomReal(1400,2500),0)
		set Scale = GetRandomReal(1,1.6)
		call SetUnitScale(U, Scale, Scale, Scale)
		call SetUnitPosition(U,GetUnitX(U),GetUnitY(U))
		call SetUnitUserData(U,-1)
		set i = i + 1
	endloop
endfunction

function ObjAddForce takes real relX, real relY, real relZ, real fX, real fY, real fZ returns nothing
endfunction
Name Type Is Array Initial Value
AV_Angle real Yes
AV_Effect effect Yes
AV_Handles integer Yes
AV_Int1 integer Yes
AV_Timers timer Yes
AV_Unit unit Yes
AV_X real Yes
AV_Y real Yes
AV_Z real Yes
classAccelerationHigh real Yes
classAccelerationLow real Yes
classAirFriction real Yes
classAirFrictionSide real Yes
classAirFrictionTop real Yes
classBreaks real Yes
classBulletOffsetZ real Yes
classCollision real Yes
classCollisionOffset real Yes
classGravityFactor real Yes
classGroundFriction real Yes
classGroundFrictionSide real Yes
classHasAnySideFriction boolean Yes
classHoverHeight real Yes
classKnockback real Yes
classMaxId integer No -1
classModelPath string Yes
classModelScale real Yes
classRotation real Yes
classRotationFriction real Yes
classRotationZ real Yes
classTerrainInfluence real Yes
classUnitType unitcode Yes
classWingAngle real Yes
constCamFarZ real No 8000.00
constCollisionDamage real No 1.00
constDamage real No 1.00
constFog real No 0.50
constGravity real No 0.40
constKnockback real No 1.00
constLocalPlayerId integer No
constUnitMaxCollision real No
constUnitsPerMeter real No 30.00
constVehicleRespawnTime real No 20.00
controlFlag unit Yes
controlLoop integer No
controlMax integer No
controlState integer Yes
controlX real Yes
controlY real Yes
dmgEffect unit Yes
dmgMax integer No
dmgTime real Yes
dmgType integer Yes
dmgX real Yes
dmgY real Yes
dmgZ real Yes
doodadBuffer real Yes
doodadSizeX real Yes
doodadSizeY real Yes
doodadSizeZ real Yes
jumperX real Yes
jumperY real Yes
loopArtilleryFire integer No
loopBombsDropping integer No
loopFlameShooting integer No 1
loopMGShooting integer No
loopThreadOpen boolean No
objAcceleration real Yes
objAI boolean Yes
objAIFlareCooldown real Yes
objAITargetPlayer integer Yes
objAIWeaponCooldown real Yes
objAIWeaponCooldown2 real Yes
objAngle real Yes
objAngleZ real Yes
objAttachment effect Yes
objBombDrops integer Yes
objBulletSlot integer Yes
objClass integer Yes
objDead boolean Yes
objDeathFire unit Yes
objDeathFireEffect1 effect Yes
objDeathFireEffect2 effect Yes
objFlameShots integer Yes
objFollowingRockets integer Yes
objIsProjectile boolean Yes
objLastEnvironmentHeight real Yes
objLifeSpan real Yes
objMaxId integer No -1
objMGShots integer Yes
objModel effect Yes
objParachute unit Yes
objParachuteAngle integer Yes
objParachuteEffect effect Yes
objPlasmaShots integer Yes
objRadarTag texttag Yes
objRocketSlot integer Yes
objRotateSpeed real Yes
objRotateZSpeed real Yes
objSpeedX real Yes
objSpeedY real Yes
objSpeedZ real Yes
objStartAngle real Yes
objStartX real Yes
objStartY real Yes
objStartZ real Yes
objUnit unit Yes
objUnitAim unit Yes
objX real Yes
objY real Yes
objZ real Yes
playerCamId integer No
playerCamObj integer No
playerCamShake1 real No
playerCamShake2 real No
playerCamShake3 real No
playerCamXStatic real No
playerCamYStatic real No
playerCamZStatic real No
playerControlledObj integer Yes
playerControllerDummy unit Yes
playerDeaths integer Yes
playerKeyPressed boolean Yes
playerKills integer Yes
playerNoDamage boolean Yes
playerObjX real No
playerObjY real No
playerObjZ real No
playerPlaying boolean Yes
playerRadarOn boolean No
playerSoldierHP real Yes
Team1Tickets real No 100.00
Team2Tickets real No 100.00
tempGroup group No
tempRect rect No
terrainFriction real Yes
TimerStack timer Yes
TimerStackN integer No
uA10 integer No
uArtilleryShot integer No
uB17 integer No
uBeam integer No
uBlueBullet integer No
uBomb integer No
uBullet integer No
uCobra integer No
uF22 integer No
uFlame integer No
uFlare integer No
uFragment integer No
uGravityGun integer No
uGreatBomb integer No
uGrenade integer No
uHammerhead integer No
uHellhound integer No
uHowitzer integer No
uJeep integer No
uJu87 integer No
uME109 integer No
uMIG29 integer No
uMLRS integer No
uNuclear integer No
uNuclearBomb integer No
uOrca integer No
uPhoton integer No
uPlasma integer No
uPlasmaBomb integer No
uPlasmaSplit integer No
uRaptor integer No
uRocket integer No
uSmoke integer No
uSoldier integer No
uStealth integer No
uTank integer No
uTitan integer No
uTProjectile integer No
VictoryTeam integer No
//TESH.scrollpos=75
//TESH.alwaysfold=0
function Trig_Initialization_InitClasses takes nothing returns nothing
    //                                                             -----Ground Frict-----   --------Air Frict--------
    //                                      Type AccelHigh  AccelLow   Base    Side  Terrain     Base     Side     Top   WingAngle  Break  Rotate  RotateZ RotateFrict Collis  CollOffset Hover BulletZ  Knock  Grav Scale Model
    set udg_uCobra         = AddUnitClass( 'h00A', 0.49,     0.31,    0.080,   0.50,   0.8,    0.00018, 0.00030, 0.00010,    0.0,    0.06,  0.17,    0.12,    0.010,    75,        0,       29,    -15,   0.08,   1, 0.82, "CobraHeli.mdx"     )
    set udg_uOrca          = AddUnitClass( 'h00B', 0.48,     0.32,    0.030,   0.20,   0.2,    0.00018, 0.00030, 0.00010,    0.0,    0.06,  0.17,    0.12,    0.015,    90,        0,       45,      0,   0.06,   1, 0.91, "Orca Fighter.mdx"  )
    set udg_uF22           = AddUnitClass( 'h000', 0.46,     0.20,    0.004,   0.12,   1.0,    0.00009, 0.00150, 0.00150,    1.5,    0.10,  0.20,    0.17,    0.012,    60,        0,       18,     -8,   0.09,   1, 3.00, "FA-22 Raptor.mdx"  )
    set udg_uMIG29         = AddUnitClass( 'h00Z', 0.46,     0.20,    0.004,   0.12,   1.0,    0.00009, 0.00150, 0.00150,    1.5,    0.10,  0.20,    0.17,    0.012,    60,        0,       18,     -8,   0.09,   1, 0.60, "MIG-29.mdx"        )
    set udg_uA10           = AddUnitClass( 'h005', 0.35,     0.17,    0.004,   0.12,   1.0,    0.00008, 0.00150, 0.00150,    3.0,    0.05,  0.16,    0.14,    0.012,    80,        0,       17,    -10,   0.09,   1, 0.36, "A10 Thunderbolt II.mdx")
    set udg_uB17           = AddUnitClass( 'h00I', 0.26,     0.13,    0.003,   0.12,   1.0,    0.00007, 0.00160, 0.00170,    5.0,    0.04,  0.16,    0.10,    0.012,   100,        0,       15,    -10,   0.05,   1, 0.51, "B17 Bomber.mdx"    )
    set udg_uStealth       = AddUnitClass( 'h00N', 0.32,     0.15,    0.004,   0.12,   1.0,    0.00006, 0.00150, 0.00160,    3.0,    0.04,  0.14,    0.10,    0.015,   100,        0,       22,    -10,   0.05,   1, 2.00, "Stealth Bomber.mdx")
    set udg_uME109         = AddUnitClass( 'h00U', 0.30,     0.15,    0.005,   0.12,   1.0,    0.00010, 0.00170, 0.00180,    4.5,    0.05,  0.19,    0.15,    0.012,    80,       13,       17,      0,   0.10,   1, 1.09, "ME109.mdx"         )
    set udg_uJu87          = AddUnitClass( 'h00O', 0.30,     0.15,    0.005,   0.12,   1.0,    0.00010, 0.00170, 0.00180,    4.5,    0.05,  0.19,    0.15,    0.012,    80,       13,       17,      0,   0.10,   1, 0.60, "ju87-stuka.mdx"    )
    set udg_uRaptor        = AddUnitClass( 'h001', 0.30,     0.15,    0.005,   0.12,   1.0,    0.00020, 0.00170, 0.00180,    4.5,    0.05,  0.19,    0.15,    0.012,    80,        5,       30,     -8,   0.01, 0.1, 2.00, "Raptor.mdx"        )
    set udg_uSoldier       = AddUnitClass( 'h003', 0.70,     0.45,    0.070,   0.20,   0.2,    0.00030, 0.00000, 0.00000,    0.0,    0.40,  1.00,    0.00,    0.050,    21,       21,        0,     20,   0.18,   1, 0.31, ""                  )
    set udg_uTank          = AddUnitClass( 'h004', 0.55,     0.33,    0.014,   0.30,   1.0,    0.00020, 0.00010, 0.00020,    0.0,    0.10,  0.50,    0.00,    0.050,    55,       30,        0,     34,   0.05,   1, 0.52, ""                  )
    set udg_uHowitzer      = AddUnitClass( 'h002', 0.55,     0.33,    0.014,   0.30,   1.0,    0.00020, 0.00010, 0.00020,    0.0,    0.10,  0.50,    0.00,    0.050,    55,       30,        0,     17,   0.05,   1, 0.52, ""                  )
    set udg_uHellhound     = AddUnitClass( 'h00T', 0.56,     0.35,    0.015,   0.30,   0.9,    0.00020, 0.00020, 0.00050,    0.0,    0.15,  0.50,    0.00,    0.050,    55,       30,        0,     45,   0.05,   1, 0.73, ""                  )
    set udg_uHammerhead    = AddUnitClass( 'h00Q', 0.52,     0.30,    0.008,   0.10,   0.2,    0.00020, 0.00010, 0.00020,    0.0,    0.15,  0.50,    0.00,    0.025,    75,       30,        0,     27,   0.05,   1, 1.00, ""                  )
    set udg_uMLRS          = AddUnitClass( 'h009', 0.48,     0.25,    0.013,   0.20,   1.0,    0.00022, 0.00020, 0.00010,    0.0,    0.00,  0.60,    0.00,    0.040,    55,       30,        0,     54,   0.06,   1, 0.55, ""                  )
    set udg_uJeep          = AddUnitClass( 'h00D', 0.43,     0.20,    0.006,   0.08,   1.0,    0.00025, 0.00010, 0.00010,    0.0,    0.08,  0.50,    0.00,    0.020,    40,       30,        0,     31,   0.07,   1, 0.45, ""                  )
    set udg_uTitan         = AddUnitClass( 'h00G', 0.74,     0.30,    0.037,   0.50,   0.2,    0.00020, 0.00000, 0.00000,    0.0,    0.15,  0.50,    0.00,    0.040,    80,       80,        0,     72,   0.04,   1, 0.80, ""                  )
    set udg_uRocket        = AddUnitClass( 'h008', 1.30,     0.65,    0.000,   0.00,   0.0,    0.00006, 0.00350, 0.00350,    0.0,    0.10,  0.80,    0.80,    0.100,    15,        0,        0,      0,   0.00,   1, 0.13, "AimingRocket.mdx"  )
    set udg_uNuclear       = AddUnitClass( 'h008', 0.90,     0.45,    0.000,   0.00,   0.0,    0.00004, 0.00175, 0.00175,    0.0,    0.05,  0.10,    0.10,    0.050,    30,        0,        0,      0,   0.00,   1, 0.60, "AimingRocket.mdx"  )
    set udg_uFlame         = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00120, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    40,        0,        0,      0,   0.00,   0, 1.00, "Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl")
    set udg_uBlueBullet    = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00000, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    10,        0,        0,      0,   0.00,   0, 0.50, "BulletBlue.mdx"    )
    set udg_uBullet        = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00000, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    10,        0,        0,      0,   0.00,   0, 0.50, "Bullet.mdx"        )
    set udg_uBeam          = AddUnitClass( 'h00R', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00000, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    20,        0,        0,      0,   0.00,   0, 0.50, "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl"                  )
    set udg_uFlare         = AddUnitClass( 'h008', 0.00,     0.00,    0.400,   0.00,   1.0,    0.00015, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    15,        0,        7,      0,   0.00,   1, 1.00, "Abilities\\Weapons\\FaerieDragonMissile\\FaerieDragonMissile.mdl" )
    set udg_uTProjectile   = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00005, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    15,        0,        7,      0,   0.00,   1, 0.60, "Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl"  )
    set udg_uGrenade       = AddUnitClass( 'h00V', 0.00,     0.00,    0.350,   0.00,   1.0,    0.00020, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,     7,        0,        5,      0,   0.00,   1, 0.30, ""                  )
    set udg_uBomb          = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00016, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    15,        0,        7,      0,   0.00,   1, 0.40, "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" )
    set udg_uGreatBomb     = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00014, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    20,        0,       10,      0,   0.00,   1, 0.60, "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" )
    set udg_uNuclearBomb   = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00012, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    20,        0,       10,      0,   0.00,   1, 0.80, "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" )
    set udg_uPlasma        = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00000, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    25,        0,       12,      0,   0.00,   0, 0.60, "Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl" )
    set udg_uPhoton        = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00000, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    35,        0,       17,      0,   0.00,   0, 1.40, "Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl")
    set udg_uSmoke         = AddUnitClass( 'h008', 0.00,     0.00,    0.400,   0.00,   0.0,    0.00015, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    15,        0,        7,      0,   0.00,   1, 0.40, "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" )
    set udg_uGravityGun    = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00015, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    15,        0,        7,      0,   0.00,   1, 1.50, "Abilities\\Spells\\Human\\ManaFlare\\ManaFlareTarget.mdl" )
    set udg_uArtilleryShot = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00015, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    20,        0,       10,      0,   0.00,   1, 0.40, "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" )
    set udg_uFragment      = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00015, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,     7,        0,        5,      0,   0.00,   1, 0.20, "Abilities\\Weapons\\GyroCopter\\GyroCopterMissile.mdl" )
    set udg_uPlasmaBomb    = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00005, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,    30,        0,       15,      0,   0.00,   0, 1.25, "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl" )
    set udg_uPlasmaSplit   = AddUnitClass( 'h008', 0.00,     0.00,    0.000,   0.00,   0.0,    0.00015, 0.00000, 0.00000,    0.0,    0.00,  0.00,    0.00,    0.000,     7,        0,        5,      0,   0.00,   1, 0.25, "Abilities\\Weapons\\FrostWyrmMissile\\FrostWyrmMissile.mdl" )
endfunction

function Trig_Initialization_InitEnvironment takes nothing returns nothing
    //                         Type    SizeX  SizeY  SizeZ  XYBuffer
    call AddEnvironmentClass( 'B001',     0,     0,   120,     75 )// Rock
    call AddEnvironmentClass( 'B002',     0,     0,   188,      7 )// Tree
    call AddEnvironmentClass( 'B004',     0,     0,   188,      8 )// Tent
    call AddEnvironmentClass( 'B005',     0,     0,    85,     65 )// Tent
    call AddEnvironmentClass( 'B009',   512,   512,  1090,      0 )// Building 1
    call AddEnvironmentClass( 'B00A',   512,   512,   585,      0 )// Building 2
    call AddEnvironmentClass( 'B00E',    64,    64,    60,      0 )// Crate
    call AddEnvironmentClass( 'B00H',    64,    64,   120,      0 )// Crate (2x Height)
    call AddEnvironmentClass( 'B00F',     0,     0,    60,     21 )// Barrel
    call AddEnvironmentClass( 'B003',     0,     0,   120,     21 )// Barrel (2x Height)
    call AddEnvironmentClass( 'B00C',    60,     0,    80,     10 )// Destroyed Part (1, Horizontal)
    call AddEnvironmentClass( 'B00B',     0,    60,    80,     10 )// Destroyed Part (1, Vertical)
    call AddEnvironmentClass( 'B00D',   220,     0,    80,     10 )// Destroyed Part (2, Horizontal)
    call AddEnvironmentClass( 'B00G',     0,   220,    80,     10 )// Destroyed Part (2, Vertical)
    call AddEnvironmentClass( 'B00J',     0,     0,   123,      5 )// Power Poll
    call AddEnvironmentClass( 'B00I',     0,     0,    90,      5 )// Street Light
endfunction

function Trig_Initialization_InitTerrainFriction takes nothing returns nothing
    //                                 TerrainType        FrictionFactor
    set udg_terrainFriction[ModuloInteger('Xgsb',8190)] = 1.0
    set udg_terrainFriction[ModuloInteger('Ywmb',8190)] = 1.0
    set udg_terrainFriction[ModuloInteger('Adrd',8190)] = 1.3
    set udg_terrainFriction[ModuloInteger('Adrt',8190)] = 1.4
    set udg_terrainFriction[ModuloInteger('Adrg',8190)] = 1.5
    set udg_terrainFriction[ModuloInteger('Agrs',8190)] = 1.6
    set udg_terrainFriction[ModuloInteger('Agrd',8190)] = 1.7
endfunction

function Trig_Initialization_InitObjects takes nothing returns nothing
    // Team 1 Base
    call AddObj(Player(15),udg_uJeep,4032,3392,udg_classHoverHeight[udg_uJeep],180,0)
    call AddObj(Player(15),udg_uTank,4032,3136,udg_classHoverHeight[udg_uTank],180,0)
    call AddObj(Player(15),udg_uMLRS,4032,2880,udg_classHoverHeight[udg_uMLRS],180,0)
    call AddObj(Player(15),udg_uCobra,2304,2780,udg_classHoverHeight[udg_uCobra],270,0)
    call AddObj(Player(15),udg_uF22,2526,2780,udg_classHoverHeight[udg_uF22],270,0)
    call AddObj(Player(15),udg_uA10,1984,2780,udg_classHoverHeight[udg_uA10],270,0)
    call AddObj(Player(15),udg_uME109,2304,2480,udg_classHoverHeight[udg_uME109],270,0)

    // Team 2 Base
    call AddObj(Player(15),udg_uJeep,-8512,-8128,udg_classHoverHeight[udg_uJeep],0,0)
    call AddObj(Player(15),udg_uTank,-8512,-7870,udg_classHoverHeight[udg_uTank],0,0)
    call AddObj(Player(15),udg_uMLRS,-8512,-7616,udg_classHoverHeight[udg_uMLRS],0,0)
    call AddObj(Player(15),udg_uCobra,-6112,-6528,udg_classHoverHeight[udg_uCobra],0,0)
    call AddObj(Player(15),udg_uF22,-6112,-6848,udg_classHoverHeight[udg_uF22],0,0)
    call AddObj(Player(15),udg_uA10,-6112,-6206,udg_classHoverHeight[udg_uA10],0,0)
    call AddObj(Player(15),udg_uME109,-5854,-6528,udg_classHoverHeight[udg_uME109],0,0)

    // Stealth Airfield
    call AddObj(Player(15),udg_uStealth,4288,-7614,udg_classHoverHeight[udg_uStealth],90,0)
    call AddObj(Player(15),udg_uMIG29,4544,-7380,udg_classHoverHeight[udg_uMIG29],90,0)
    call AddObj(Player(15),udg_uTitan,3100,-6594,udg_classHoverHeight[udg_uTitan],135,0)

    // B17 Airfield
    call AddObj(Player(15),udg_uB17,-7744,3394,udg_classHoverHeight[udg_uB17],0,0)
    call AddObj(Player(15),udg_uJu87,-7474,3668,udg_classHoverHeight[udg_uJu87],0,0)
    call AddObj(Player(15),udg_uRaptor,-4645,1304,udg_classHoverHeight[udg_uRaptor],90,0)

    // City
    call AddObj(Player(15),udg_uHowitzer,-1919,1980,udg_classHoverHeight[udg_uHowitzer],270,0)
    call AddObj(Player(15),udg_uHammerhead,-1984,-1342,udg_classHoverHeight[udg_uHammerhead],90,0)
    call AddObj(Player(15),udg_uHellhound,-704,-2942,udg_classHoverHeight[udg_uHellhound],0,0)
    call AddObj(Player(15),udg_uOrca,-3662,-3022,udg_classHoverHeight[udg_uOrca],0,0)
endfunction

function Trig_Initialization_RemoveDot takes nothing returns nothing
    if GetDestructableTypeId(GetEnumDestructable())=='B000' then
        call RemoveDestructable(GetEnumDestructable())
    endif
endfunction

function Trig_Initialization_Select takes nothing returns nothing
    call ReleaseTimer(GetExpiredTimer())
    call ClearSelection()
    call SelectUnit(udg_playerControllerDummy[udg_constLocalPlayerId], true)
endfunction

function Trig_Initialization_Actions takes nothing returns nothing
    local integer i = 0
    local unit U
    set udg_constLocalPlayerId = GetPlayerId(GetLocalPlayer())

    set udg_tempRect = Rect(-100,-100,100,100)
    call SetSkyModel( "Environment\\Sky\\FoggedSky\\FoggedSky.mdl" )
    call SetFloatGameState(GAME_STATE_TIME_OF_DAY, 12)
    call SetTimeOfDayScale( 0 )
    loop
        set udg_objRadarTag[i] = CreateTextTag()
        set udg_objRadarTag[i+1] = CreateTextTag()
        set udg_objRadarTag[i+2] = CreateTextTag()
        set udg_objRadarTag[i+3] = CreateTextTag()
        set udg_objRadarTag[i+4] = CreateTextTag()
        set i = i + 5
        exitwhen i >= 500
    endloop
    call Trig_Initialization_InitClasses()
    call Trig_Initialization_InitEnvironment()
    call Trig_Initialization_InitTerrainFriction()
    call Trig_Initialization_InitObjects()
    set i = 0
    loop
        set udg_playerControlledObj[i] = -1
        set i = i + 1
        exitwhen i > 15
    endloop
    set i = 0
    loop
        if GetPlayerSlotState(Player(i)) == PLAYER_SLOT_STATE_PLAYING then
            set udg_playerPlaying[i] = true
            call CreateFogModifierRectBJ( true, Player(i), FOG_OF_WAR_VISIBLE, GetWorldBounds() )
            call CreateStartingUnit(i)
        endif
        call SetPlayerAllianceStateBJ( Player(10+(i-(i/2)*2)), Player(i), bj_ALLIANCE_ALLIED_VISION )
        call SetPlayerAllianceStateBJ( Player(11+(i-((i+1)/2)*2)), Player(i), bj_ALLIANCE_UNALLIED )
        call SetPlayerAllianceStateBJ( Player(i), Player(10+(i-(i/2)*2)), bj_ALLIANCE_ALLIED_VISION )
        call SetPlayerAllianceStateBJ( Player(i), Player(11+(i-((i+1)/2)*2)), bj_ALLIANCE_UNALLIED )


        set i = i + 1
        exitwhen i > 9
    endloop
    set udg_jumperX[0] = -960
    set udg_jumperY[0] = 323
    call AddSpecialEffect("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl",udg_jumperX[0],udg_jumperY[0])
    set udg_jumperX[1] = -3521
    set udg_jumperY[1] = -4282
    call AddSpecialEffect("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl",udg_jumperX[1],udg_jumperY[1])
    set udg_jumperX[2] = 192
    set udg_jumperY[2] = -4032
    call AddSpecialEffect("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl",udg_jumperX[2],udg_jumperY[2])
    set udg_jumperX[3] = -5050
    set udg_jumperY[3] = -1090
    call AddSpecialEffect("Abilities\\Spells\\Other\\Drain\\ManaDrainTarget.mdl",udg_jumperX[3],udg_jumperY[3])

    call SetCloudCount(50)
    call SetRect(udg_tempRect,-18430, -17452, 14321, 14333)
    call EnumDestructablesInRect(udg_tempRect, null, function Trig_Initialization_RemoveDot)

    set i = 0
    call GroupEnumUnitsInRange( udg_tempGroup, 0, 0, 50000, null )
    loop
        set U = FirstOfGroup(udg_tempGroup)
        exitwhen U==null
        if GetUnitTypeId(U)=='h00Y' then
            set udg_controlFlag[i] = U
            set udg_controlX[i] = GetUnitX(U)
            set udg_controlY[i] = GetUnitY(U)
            if GetPlayerId(GetOwningPlayer(U))==10 then
                set udg_controlState[i] = 47
            else
                set udg_controlState[i] = -47
            endif
            call SetUnitAnimationByIndex(U,1)
            call SetUnitUserData(U,-1)
            call UnitAddAbility(U,'Aloc')
            set i = i + 1
        endif
        call GroupRemoveUnit(udg_tempGroup,U)
    endloop
    set udg_controlMax=i-1

    call EnableDragSelect(false, false)
    call EnablePreSelect(false, false)
    call EnableSelect(false, false)
    call EnableOcclusion(false)

    call TriggerExecute(gg_trg_Loop)

    call TimerStart(NewTimer(),0,false,function Trig_Initialization_Select)
endfunction

//===========================================================================
function InitTrig_Initialization takes nothing returns nothing
    set gg_trg_Initialization = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Initialization, function Trig_Initialization_Actions )
endfunction
function Trig_Arrows_LEFT_DOWN takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4] = true
endfunction

function Trig_Arrows_LEFT_UP takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4] = false
endfunction

function Trig_Arrows_RIGHT_DOWN takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4+1] = true
endfunction

function Trig_Arrows_RIGHT_UP takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4+1] = false
endfunction

function Trig_Arrows_DOWN_DOWN takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4+2] = true
endfunction

function Trig_Arrows_DOWN_UP takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4+2] = false
endfunction

function Trig_Arrows_UP_DOWN takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4+3] = true
endfunction

function Trig_Arrows_UP_UP takes nothing returns nothing
    set udg_playerKeyPressed[GetPlayerId(GetTriggerPlayer())*4+3] = false
endfunction

//===========================================================================
function InitTrig_Arrows_CreateTrigger takes code actionFunc, playerevent eventId returns nothing
    local trigger t = CreateTrigger()
    local integer PlayerId = 0
    call TriggerAddAction(t, actionFunc)
    loop
        exitwhen PlayerId > 9
        call TriggerRegisterPlayerEvent(t, Player(PlayerId), eventId)
        set PlayerId = PlayerId + 1
    endloop
    set t = null
endfunction

function InitTrig_Arrows takes nothing returns nothing
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_LEFT_DOWN, EVENT_PLAYER_ARROW_LEFT_DOWN)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_LEFT_UP, EVENT_PLAYER_ARROW_LEFT_UP)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_RIGHT_DOWN, EVENT_PLAYER_ARROW_RIGHT_DOWN)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_RIGHT_UP, EVENT_PLAYER_ARROW_RIGHT_UP)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_DOWN_DOWN, EVENT_PLAYER_ARROW_DOWN_DOWN)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_DOWN_UP, EVENT_PLAYER_ARROW_DOWN_UP)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_UP_DOWN, EVENT_PLAYER_ARROW_UP_DOWN)
    call InitTrig_Arrows_CreateTrigger(function Trig_Arrows_UP_UP, EVENT_PLAYER_ARROW_UP_UP)
endfunction
//TESH.scrollpos=1852
//TESH.alwaysfold=0
function ArtilleryShotSplit takes integer ObjId returns nothing
    local integer FragmentObjId
    local integer Count = 0
    local real SplitAngle
    local real SplitSpeed

    loop
        exitwhen Count>7
        set FragmentObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uFragment, udg_objX[ObjId], udg_objY[ObjId], udg_objZ[ObjId], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
        set SplitAngle = GetRandomReal(0,2*bj_PI)
        set SplitSpeed = GetRandomReal(1,10)
        set udg_objSpeedX[FragmentObjId] = udg_objSpeedX[ObjId] + SplitSpeed*Cos(SplitAngle)
        set udg_objSpeedY[FragmentObjId] = udg_objSpeedY[ObjId] + SplitSpeed*Sin(SplitAngle)
        set udg_objSpeedZ[FragmentObjId] = udg_objSpeedZ[ObjId] + GetRandomReal(-4,4)
        set Count = Count + 1
    endloop
endfunction

function PlasmaBombSplit takes integer ObjId returns nothing
    local integer FragmentObjId
    local integer Count = 0
    local real SplitAngle
    local real SplitAngleZ
    local real SplitSpeed

    loop
        exitwhen Count>7
        set SplitAngle = GetRandomReal(0,2*bj_PI)
        set SplitAngleZ = SquareRoot(GetRandomReal(0,1))*2*bj_PI
        set FragmentObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uPlasmaSplit, udg_objX[ObjId], udg_objY[ObjId], udg_objZ[ObjId], SplitAngle,SplitAngleZ)
        set SplitSpeed = GetRandomReal(1,10)
        set udg_objSpeedX[FragmentObjId] = udg_objSpeedX[ObjId] + SplitSpeed*Cos(SplitAngle)*Cos(SplitAngleZ)
        set udg_objSpeedY[FragmentObjId] = udg_objSpeedY[ObjId] + SplitSpeed*Sin(SplitAngle)*Cos(SplitAngleZ)
        set udg_objSpeedZ[FragmentObjId] = udg_objSpeedZ[ObjId] + SplitSpeed*Sin(SplitAngleZ)
        set udg_objX[FragmentObjId] = udg_objX[FragmentObjId] + udg_objSpeedX[FragmentObjId]/2
        set udg_objY[FragmentObjId] = udg_objY[FragmentObjId] + udg_objSpeedY[FragmentObjId]/2
        set udg_objZ[FragmentObjId] = udg_objZ[FragmentObjId] + udg_objSpeedZ[FragmentObjId]/2
        set Count = Count + 1
    endloop
endfunction

function ObjExplode takes unit Obj returns nothing
    local integer ObjId = GetUnitUserData(Obj)
    local integer t = udg_objClass[ObjId]
    local real X = udg_objX[ObjId]
    local real Y = udg_objY[ObjId]
    local real Z = udg_objZ[ObjId]
    local real r
    local real r2
    local integer PlayerId
    local integer i
    if udg_objFollowingRockets[ObjId]!=0 then
        set udg_objFollowingRockets[ObjId]=0
        set i = 0
        loop
            exitwhen i > udg_objMaxId
            if udg_objUnitAim[i] ==udg_objUnit[ObjId] then
                set udg_objUnitAim[i] = null
            endif
            set i = i + 1
        endloop
    endif
    if udg_objModel[ObjId]!=null then
        call DestroyEffect(udg_objModel[ObjId])
        set udg_objModel[ObjId] = null
    endif
    if udg_objIsProjectile[ObjId] then
        call KillUnit(Obj)
        if t==udg_uBullet then
            call UnitDamageArea(Obj, X, Y, Z, 0, 25, false, false)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\GyroCopter\\GyroCopterImpact.mdl", X, Y, Z, 0.3, 5, 0, 2)
            call RemoveUnit(Obj)
        elseif t==udg_uBlueBullet then
            call UnitDamageArea(Obj, X, Y, Z, 0, 30, false, false)
            call SpecialEffectScaledTimedWithZ("Abilities\\Spells\\Undead\\AbsorbMana\\AbsorbManaBirthMissile.mdl", X, Y, Z, 0.3, 5, 0, 2)
            call RemoveUnit(Obj)
        elseif t==udg_uFlame then
            call UnitDamageArea(Obj, X, Y, Z, 50, 50, false, false)
            call SetUnitScale(Obj,1.6,1.6,1.6)
            call RemoveUnitTimed(Obj, 2)
        elseif t==udg_uRocket then
            call UnitDamageArea(Obj, X, Y, Z, 160, 130, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 1.5, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\Mortar\\MortarMissile.mdl", X, Y, Z-20, 1.4, 0.7, 0, 2)
            call SpecialEffectScaledTimedWithZ("NeutralBuildingExplosionNoSplat.mdx", X, Y, Z-20, 0.6, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1,2), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1,2), GetRandomReal(0.75,1.5), 0, 5)
            call SetUnitScale(Obj,0,0,0)
            call RemoveUnitTimed(Obj, 2)
        elseif t==udg_uTProjectile then
            call UnitDamageArea(Obj, X, Y, Z, 100, 200, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 1.5, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("NeutralBuildingExplosionNoSplat.mdx", X, Y, Z-20, 0.7, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SetUnitScale(Obj,0,0,0)
            call RemoveUnitTimed(Obj, 2)
        elseif t==udg_uPlasma then
            call UnitDamageArea(Obj, X, Y, Z, 200, 220, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 1.5, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Spells\\Undead\\OrbOfDeath\\AnnihilationMissile.mdl", X, Y, Z-20, 2, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("NeutralBuildingExplosionNoSplat.mdx", X, Y, Z-20, 0.7, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SetUnitScale(Obj,2,2,2)
            call RemoveUnitTimed(Obj, 2)
        elseif t==udg_uPhoton or t==udg_uBeam then
            call UnitDamageArea(Obj, X, Y, Z, 250, 250, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 1.5, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", X, Y, Z-20, 2.5, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\FarseerMissile\\FarseerMissile.mdl", X, Y, Z-20, 2, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("NeutralBuildingExplosionNoSplat.mdx", X, Y, Z-20, 0.7, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SetUnitScale(Obj,0,0,0)
            call RemoveUnitTimed(Obj, 2)
        elseif t==udg_uGreatBomb then
            call UnitDamageArea(Obj, X, Y, Z, 350, 300, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 3.2, 0.6, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\Mortar\\MortarMissile.mdl", X, Y, Z-20, 3, 0.5, 0, 2)
            call SpecialEffectScaledTimedWithZ("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", X, Y, Z-20, 1, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(2.5,5), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(2.5,5), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(2.5,5), GetRandomReal(0.75,1.5), 0, 5)
            call RemoveUnit(Obj)
        elseif t==udg_uBomb then
            call UnitDamageArea(Obj, X, Y, Z, 280, 200, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 2.0, 0.6, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\Mortar\\MortarMissile.mdl", X, Y, Z-20, 1.8, 0.5, 0, 2)
            call SpecialEffectScaledTimedWithZ("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", X, Y, Z-20, 1, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.5,3), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.5,3), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.5,3), GetRandomReal(0.75,1.5), 0, 5)
            call RemoveUnit(Obj)
        elseif t==udg_uGrenade or t==udg_uFragment then
            call UnitDamageArea(Obj, X, Y, Z, 180, 160, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 1.4, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\Mortar\\MortarMissile.mdl", X, Y, Z-20, 1.3, 0.7, 0, 2)
            call SpecialEffectScaledTimedWithZ("NeutralBuildingExplosionNoSplat.mdx", X, Y, Z-20, 0.55, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.0,2.0), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.0,2.0), GetRandomReal(0.75,1.5), 0, 5)
            call RemoveUnit(Obj)
        elseif t==udg_uSmoke then
            call SpecialEffectScaledTimedWithZ("Smoke.mdx", X, Y, Z-20, 1, 1, 5, 10)
            call RemoveUnit(Obj)
        elseif t==udg_uArtilleryShot then
            call ArtilleryShotSplit(ObjId)
            call RemoveUnitTimed(Obj, 1)
        elseif t==udg_uPlasmaBomb then
            call PlasmaBombSplit(ObjId)
            call SetUnitScale(Obj,0,0,0)
            call RemoveUnitTimed(Obj, 1)
        elseif t==udg_uPlasmaSplit then
            call UnitDamageArea(Obj, X, Y, Z, 180, 140, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 1.5, 0.8, 0, 2)
            call SpecialEffectScaledTimedWithZ("NeutralBuildingExplosionNoSplat.mdx", X, Y, Z-20, 0.7, 1, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z-20, GetRandomReal(1.1,2.2), GetRandomReal(0.75,1.5), 0, 5)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\Bolt\\BoltImpact.mdl", X, Y, Z-20, 2.5, 0.8, 0, 2)
            call SetUnitScale(Obj,1.5,1.5,1.5)
            call RemoveUnitTimed(Obj, 1)
        elseif t==udg_uNuclear or t==udg_uNuclearBomb then
            call UnitDamageArea(Obj, X, Y, Z, 1800, 800, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z-20, 7.5, 0.1, 0, 2)
            set udg_dmgEffect[udg_dmgMax] = SpecialEffectScaledTimedWithZ("A-Bomb.mdx", X, Y, Z-20, 1, 1, 0, 20)
            set udg_dmgX[udg_dmgMax] = X
            set udg_dmgY[udg_dmgMax] = Y
            set udg_dmgZ[udg_dmgMax] = Z
            set udg_dmgType[udg_dmgMax] = 0
            set udg_dmgTime[udg_dmgMax] = 0
            call SetUnitOwner(udg_dmgEffect[udg_dmgMax],GetOwningPlayer(Obj),false)
            set udg_dmgMax = udg_dmgMax+1
            call SetUnitScale(Obj,0,0,0)
            call RemoveUnitTimed(Obj, 1)
        elseif t==udg_uGravityGun then
            set udg_dmgEffect[udg_dmgMax] = SpecialEffectScaledTimedWithZ("BlackHole.mdx", X, Y, Z, 4, 1, 7, 9)
            set udg_dmgX[udg_dmgMax] = X
            set udg_dmgY[udg_dmgMax] = Y
            set udg_dmgZ[udg_dmgMax] = Z
            set udg_dmgType[udg_dmgMax] = 1
            set udg_dmgTime[udg_dmgMax] = 0
            call SetUnitOwner(udg_dmgEffect[udg_dmgMax],GetOwningPlayer(Obj),false)
            set udg_dmgMax = udg_dmgMax+1
            call SetUnitScale(Obj,0,0,0)
            call RemoveUnitTimed(Obj, 1)
        endif
        call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
        set udg_objUnit[ObjId] = null
       
        if udg_objUnitAim[ObjId]!=null and t==udg_uRocket then
            set i = GetUnitUserData(udg_objUnitAim[ObjId])
            set udg_objFollowingRockets[i]=udg_objFollowingRockets[i]-1
            if udg_playerControlledObj[GetPlayerId(GetOwningPlayer(udg_objUnitAim[ObjId]))]==i then
                call SetPlayerState(GetOwningPlayer(udg_objUnitAim[ObjId]),PLAYER_STATE_RESOURCE_FOOD_USED,udg_objFollowingRockets[i])
            endif
        endif
    else
        set PlayerId = GetPlayerId(GetOwningPlayer(Obj))
        call UnitDamageTargetSync(Obj,Obj,GetUnitState(Obj,UNIT_STATE_MAX_LIFE))
        if t==udg_uSoldier and PlayerId<12 then
            call SpecialEffectScaledTimedWithZ("Objects\\Spawnmodels\\Orc\\OrcSmallDeathExplode\\OrcSmallDeathExplode.mdl", X, Y, Z, 1, 1, 0, 2)
        else
            if t==udg_uA10 then
                set r = 200
            elseif t==udg_uStealth or t==udg_uB17 or t==udg_uJeep then
                set r = 300
            else
                set r = 45*(GetUnitState(Obj, UNIT_STATE_MANA)+1)
            endif
            set r2 = 0.8+r/800
            call UnitDamageArea(Obj, X,  Y, Z, 260*r2, r, false, true)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\SteamTank\\SteamTankImpact.mdl", X, Y, Z, 2.0*r2, 0.6/r2, 0, 2)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\Mortar\\MortarMissile.mdl", X, Y, Z, 1.8*r2, 0.5/r2, 0, 2)
            call SpecialEffectScaledTimedWithZ("Objects\\Spawnmodels\\Other\\NeutralBuildingExplosion\\NeutralBuildingExplosion.mdl", X, Y, Z, 1*r2, 1/r2, 0, 8)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z, GetRandomReal(1.5,3)*r2, GetRandomReal(0.75,1.5)/r2, 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z, GetRandomReal(1.5,3)*r2, GetRandomReal(0.75,1.5)/r2, 0, 5)
            call SpecialEffectScaledTimedWithZ("BombDust.mdx", X, Y, Z, GetRandomReal(1.5,3)*r2, GetRandomReal(0.75,1.5)/r2, 0, 5)
            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\RedDragonBreath\\RedDragonMissile.mdl", X, Y, Z, 3, 1, 0, 2)
        endif
        if udg_playerCamObj==ObjId then
            set udg_playerCamObj=-1
        endif
        call RemoveUnit(Obj)
        if udg_playerControlledObj[PlayerId]==ObjId then
            set udg_playerControlledObj[PlayerId] = -1
            call SetPlayerState(Player(PlayerId),PLAYER_STATE_RESOURCE_FOOD_USED,0)
        endif
        call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
        set udg_objUnit[ObjId] = null
        if udg_objParachute[ObjId]!=null then
            call DestroyEffect(udg_objParachuteEffect[ObjId])
            call RemoveUnitTimed(udg_objParachute[ObjId],1)
            set udg_objParachute[ObjId]=null
        endif
        if udg_objDeathFire[ObjId]!=null then
            call DestroyEffect(udg_objDeathFireEffect1[ObjId])
            call DestroyEffect(udg_objDeathFireEffect2[ObjId])
            call RemoveUnitTimed(udg_objDeathFire[ObjId],10)
            set udg_objDeathFire[ObjId]=null
        endif
    endif
endfunction

function AdjustParachute takes integer ObjId, boolean InitAngle returns nothing
    local integer i
    local real SpeedXY = SquareRoot(udg_objSpeedX[ObjId]*udg_objSpeedX[ObjId]+udg_objSpeedY[ObjId]*udg_objSpeedY[ObjId])
    call SetUnitFlyHeight(udg_objParachute[ObjId], udg_objZ[ObjId]+udg_classCollisionOffset[udg_objClass[ObjId]], 0)
    call SetUnitPosition(udg_objParachute[ObjId], udg_objX[ObjId], udg_objY[ObjId])
    if SpeedXY!=0 then
        call SetUnitFacing( udg_objParachute[ObjId], Atan2(udg_objSpeedY[ObjId],udg_objSpeedX[ObjId])*bj_RADTODEG )
        set i = R2I(Atan2(udg_objSpeedZ[ObjId],SpeedXY)*bj_RADTODEG+90.5)
        if i > 270 then
            set i = i-360
        elseif i < -90 then
            set i = i+360
        endif
        if i < 0 then
            set i = 0
        elseif i > 180 then
            set i = 180
        endif
    else
        set i = 0
    endif
    if not InitAngle then
        if i > udg_objParachuteAngle[ObjId]+5 then
            set i = udg_objParachuteAngle[ObjId]+5
        elseif i < udg_objParachuteAngle[ObjId]-5 then
            set i = udg_objParachuteAngle[ObjId]-5
        endif
    endif
    set udg_objParachuteAngle[ObjId] = i
    call SetUnitZFacing(udg_objParachute[ObjId], i)
endfunction

function FireMissileFlares takes integer ObjId returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(udg_objUnit[ObjId]))
    local integer Class = udg_objClass[ObjId]
    local integer FlareObjId
    local integer i = 0
    local integer FlareFollow
    local real SpeedXY
    local real SpeedX
    local real SpeedY
    local real SpeedZ
    local unit array U
    loop
        exitwhen i>1
        set FlareObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]),udg_uFlare,udg_objX[ObjId]+Cos((udg_objAngle[ObjId]+90)*bj_DEGTORAD)*(40-i*80), udg_objY[ObjId]+Sin((udg_objAngle[ObjId]+90)*bj_DEGTORAD)*(40-i*80), udg_objZ[ObjId] + udg_classCollisionOffset[Class]*Cos(udg_objAngleZ[ObjId]), udg_objAngle[ObjId],0)
        set U[i] = udg_objUnit[FlareObjId]
        set udg_objSpeedX[FlareObjId] = udg_objSpeedX[ObjId]+(25-i*50)*Cos((udg_objAngle[ObjId]+90)*bj_DEGTORAD)
        set udg_objSpeedY[FlareObjId] = udg_objSpeedY[ObjId]+(25-i*50)*Sin((udg_objAngle[ObjId]+90)*bj_DEGTORAD)
        if (Class-udg_uTitan)*(Class-udg_uHammerhead)==0 then
            set udg_objSpeedZ[FlareObjId] = udg_objSpeedZ[ObjId]+25
        else
            set udg_objSpeedZ[FlareObjId] = udg_objSpeedZ[ObjId]
        endif
        set udg_objAngle[FlareObjId] = bj_RADTODEG * Atan2(udg_objSpeedX[FlareObjId], udg_objSpeedY[FlareObjId])
        set udg_objLifeSpan[FlareObjId] = 2
        set i = i + 1
    endloop
    set i = 0
    loop
        exitwhen i > udg_objMaxId
        if udg_objUnitAim[i] ==udg_objUnit[ObjId] then
            set FlareFollow = GetRandomInt(0,1)
            set udg_objUnitAim[i] = U[FlareFollow]
            set udg_objFollowingRockets[i]=udg_objFollowingRockets[i]-1
            set udg_objFollowingRockets[GetUnitUserData(U[FlareFollow])]=udg_objFollowingRockets[GetUnitUserData(U[FlareFollow])]+1
        endif
        set i = i + 1
    endloop
    set udg_objFollowingRockets[ObjId]=0
    if PlayerId<10 then
        call SetPlayerState(Player(PlayerId),PLAYER_STATE_RESOURCE_FOOD_USED,0)
    endif

    set U[0] = null
    set U[1] = null
endfunction

function AimingRocketGetTarget takes integer RocketObjId returns unit
    local unit U
    local real X = udg_objX[RocketObjId]
    local real Y = udg_objY[RocketObjId]
    local real Z = udg_objZ[RocketObjId]
    local real DistX
    local real DistY
    local real DistZ
    local real Dist
    local unit BestTarget = null
    local real BestValue = 0
    local real CurrentValue
    local real TargetAngle
    local real TargetAngleZ
    local real TargetAngleDiff
    local integer TargetClass
    local integer TargetObjId
    call GroupEnumUnitsInRange( udg_tempGroup, X, Y, 9000, null )
    loop
        set U = FirstOfGroup( udg_tempGroup )
        exitwhen U == null
       
        if GetUnitAbilityLevel(U, 'A005')==1 and not UnitsAreAllied(U, udg_objUnit[RocketObjId]) then
            set TargetObjId = GetUnitUserData(U)
            set TargetClass = udg_objClass[TargetObjId]
            set DistX = udg_objX[TargetObjId] - X
            set DistY = udg_objY[TargetObjId] - Y
            set DistZ = udg_objZ[TargetObjId]+udg_classCollisionOffset[TargetClass] - Z
            set TargetAngle = bj_RADTODEG * Atan2(DistY, DistX)
            set TargetAngleZ = bj_RADTODEG * Atan2(DistZ, SquareRoot(DistX*DistX+DistY*DistY))
            set TargetAngleDiff = DiffBetweenAngles3D(udg_objAngle[RocketObjId], udg_objAngleZ[RocketObjId], TargetAngle, TargetAngleZ)
            if TargetAngleDiff < 50 then
                set Dist = SquareRoot(DistX*DistX+DistY*DistY+DistZ*DistZ)
                set CurrentValue = (TargetAngleDiff+20)*(Dist+5000)
                if GetPlayerId(GetOwningPlayer(U))<12 then
                    set CurrentValue = CurrentValue/4
                endif
                if CurrentValue < BestValue or BestValue == 0 then
                    set BestTarget = U
                    set BestValue = CurrentValue
                endif
            endif
        endif
        call GroupRemoveUnit(udg_tempGroup, U)
    endloop
    return BestTarget
endfunction

function FireAimingRocket takes integer ObjId, boolean Aim returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(udg_objUnit[ObjId]))
    local integer CasterUnitType = udg_objClass[ObjId]
    local unit Rocket
    local integer RocketObjId
    local real X = udg_objX[ObjId]
    local real Y = udg_objY[ObjId]
    local real SideAngleRad = (udg_objAngle[ObjId]+90)*bj_DEGTORAD
    local real SideDist = 0
    local integer i
    local real AngleZ
    local real Angle
    if CasterUnitType==udg_uF22 or CasterUnitType==udg_uMIG29 or CasterUnitType==udg_uRaptor then
        set SideDist = 60-(udg_objRocketSlot[ObjId]*120)
        set udg_objRocketSlot[ObjId] = 1-udg_objRocketSlot[ObjId]
        set X = X + SideDist*Cos(SideAngleRad)
        set Y = Y + SideDist*Sin(SideAngleRad)
    elseif (CasterUnitType-udg_uCobra)*(CasterUnitType-udg_uHellhound)==0 then
        set SideDist = 28-(udg_objRocketSlot[ObjId]*56)
        set udg_objRocketSlot[ObjId] = 1-udg_objRocketSlot[ObjId]
        set X = X + SideDist*Cos(SideAngleRad) + 30*Cos(SideAngleRad+90*bj_DEGTORAD)
        set Y = Y + SideDist*Sin(SideAngleRad) + 30*Sin(SideAngleRad+90*bj_DEGTORAD)
    elseif CasterUnitType==udg_uMLRS then
        set SideDist = GetRandomReal(0,25)
        if udg_objRocketSlot[ObjId]==0 then
            set SideDist=-SideDist
        endif
        set udg_objRocketSlot[ObjId] = 1-udg_objRocketSlot[ObjId]
        set X = X + SideDist*Cos(SideAngleRad)
        set Y = Y + SideDist*Sin(SideAngleRad)
    endif
    if CasterUnitType==udg_uMLRS then
        if Aim then
            set AngleZ = udg_objAngleZ[ObjId]+20
        else
            set AngleZ = udg_objAngleZ[ObjId]+3
        endif
    elseif CasterUnitType==udg_uF22 or CasterUnitType==udg_uMIG29 then
        set AngleZ = udg_objAngleZ[ObjId]-5
    else
        set AngleZ = udg_objAngleZ[ObjId]
    endif
    set Angle = udg_objAngle[ObjId]
    if AngleZ<-90 or AngleZ>90 then
        set AngleZ=-AngleZ+180
        if AngleZ<-180 then
            set AngleZ=AngleZ+360
        elseif AngleZ>180 then
            set AngleZ=AngleZ-360
        endif
        set Angle=Angle+180
        if Angle>360 then
            set Angle=Angle-360
        endif
    endif
    set RocketObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uRocket, X, Y, udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]]*Cos(udg_objAngleZ[ObjId]), Angle,AngleZ)
    if CasterUnitType==udg_uCobra then
        set udg_objZ[RocketObjId] = udg_objZ[RocketObjId] + 20*Cos(udg_objAngleZ[ObjId])
    endif
    set udg_objSpeedX[RocketObjId] = udg_objSpeedX[ObjId]
    set udg_objSpeedY[RocketObjId] = udg_objSpeedY[ObjId]
    set udg_objSpeedZ[RocketObjId] = udg_objSpeedZ[ObjId]
    if (CasterUnitType-udg_uMLRS)*(CasterUnitType-udg_uTitan)*(CasterUnitType-udg_uHellhound)==0 then
        set udg_objSpeedX[RocketObjId] = udg_objSpeedX[ObjId]+15*Cos(udg_objAngle[RocketObjId]*bj_DEGTORAD)*Cos(udg_objAngleZ[RocketObjId]*bj_DEGTORAD)
        set udg_objSpeedY[RocketObjId] = udg_objSpeedY[ObjId]+15*Sin(udg_objAngle[RocketObjId]*bj_DEGTORAD)*Cos(udg_objAngleZ[RocketObjId]*bj_DEGTORAD)
        set udg_objSpeedZ[RocketObjId] = udg_objSpeedZ[ObjId]+15*Sin(udg_objAngleZ[RocketObjId]*bj_DEGTORAD)
    endif
    set udg_objAcceleration[RocketObjId] = udg_classAccelerationHigh[udg_uRocket]
    if Aim then
        set udg_objUnitAim[RocketObjId] = AimingRocketGetTarget(RocketObjId)
        if udg_objUnitAim[RocketObjId]!=null then
            set i = GetUnitUserData(udg_objUnitAim[RocketObjId])
            set udg_objFollowingRockets[i]=udg_objFollowingRockets[i]+1

            if GetPlayerId(GetOwningPlayer(udg_objUnitAim[RocketObjId]))<10 then
                call SetPlayerState(GetOwningPlayer(udg_objUnitAim[RocketObjId]),PLAYER_STATE_RESOURCE_FOOD_USED,udg_objFollowingRockets[i])
            endif
        endif
        call SetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA, RMaxBJ(0,GetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA)-1))
    endif
endfunction

function Trig_Loop_FireNuclear takes integer ObjId returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(udg_objUnit[ObjId]))
    local integer CasterUnitType = udg_objClass[ObjId]
    local real X = GetUnitX(udg_objUnit[ObjId])
    local real Y = GetUnitY(udg_objUnit[ObjId])
    local integer MissileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uNuclear, X, Y, udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    local integer i
    set udg_objSpeedX[MissileObjId] = udg_objSpeedX[ObjId]
    set udg_objSpeedY[MissileObjId] = udg_objSpeedY[ObjId]
    set udg_objSpeedZ[MissileObjId] = udg_objSpeedZ[ObjId]
    set udg_objAcceleration[MissileObjId] = udg_classAccelerationHigh[udg_uNuclear]
    set udg_objUnitAim[MissileObjId] = AimingRocketGetTarget(MissileObjId)
    if udg_objUnitAim[MissileObjId]!=null then
        set i = GetUnitUserData(udg_objUnitAim[MissileObjId])
        set udg_objFollowingRockets[i]=udg_objFollowingRockets[i]+1

        if GetPlayerId(GetOwningPlayer(udg_objUnitAim[MissileObjId]))<10 then
            call SetPlayerState(GetOwningPlayer(udg_objUnitAim[MissileObjId]),PLAYER_STATE_RESOURCE_FOOD_USED,udg_objFollowingRockets[i])
        endif
    endif
    call SetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA, RMaxBJ(0,GetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA)-1))
endfunction

function Trig_Loop_FirePhotonCannon takes integer ObjId returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(udg_objUnit[ObjId]))
    local integer Class = udg_objClass[ObjId]
    local integer PhotonProjectileObjId
    local integer i = 0
    loop
        exitwhen i>1
        set PhotonProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uPhoton, GetUnitX(udg_objUnit[ObjId])+Cos((udg_objAngle[ObjId]+90)*bj_DEGTORAD)*(40-i*80), GetUnitY(udg_objUnit[ObjId])+Sin((udg_objAngle[ObjId]+90)*bj_DEGTORAD)*(40-i*80), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
        set udg_objAcceleration[PhotonProjectileObjId] = udg_classAccelerationHigh[udg_uPhoton]
        set udg_objLifeSpan[PhotonProjectileObjId] = 3
        set udg_objSpeedX[PhotonProjectileObjId] = udg_objSpeedX[ObjId] + 200*Cos(udg_objAngle[ObjId]*bj_DEGTORAD)*Cos(udg_objAngleZ[ObjId]*bj_DEGTORAD)
        set udg_objSpeedY[PhotonProjectileObjId] = udg_objSpeedY[ObjId] + 200*Sin(udg_objAngle[ObjId]*bj_DEGTORAD)*Cos(udg_objAngleZ[ObjId]*bj_DEGTORAD)
        set udg_objSpeedZ[PhotonProjectileObjId] = udg_objSpeedZ[ObjId] + 200*Sin(udg_objAngleZ[ObjId]*bj_DEGTORAD)
        set i = i + 1
    endloop

    if GetLocalPlayer()==Player(PlayerId) then
        set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*5,-150),150)
        set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*5,-150),150)
        set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*5,-150),150)
    endif
endfunction

function Trig_Loop_DropBomb takes integer ObjId returns nothing
    local integer BombObjId
    local real SideDist
    local real SideAngleRad = (udg_objAngle[ObjId]+90)*bj_DEGTORAD
    if (udg_objClass[ObjId]-udg_uB17)*(udg_objClass[ObjId]-udg_uStealth)==0 then
        set SideDist = GetRandomReal(-40,40)
        set BombObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uGreatBomb, udg_objX[ObjId]+SideDist*Cos(SideAngleRad), udg_objY[ObjId] + SideDist*Sin(SideAngleRad), udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]]*Cos(udg_objAngleZ[ObjId]), udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    else
        set SideDist = GetRandomReal(-20,20)
        set BombObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uBomb, udg_objX[ObjId]+SideDist*Cos(SideAngleRad), udg_objY[ObjId] + SideDist*Sin(SideAngleRad), udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]]*Cos(udg_objAngleZ[ObjId]), udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    endif
    set udg_objSpeedX[BombObjId] = udg_objSpeedX[ObjId]
    set udg_objSpeedY[BombObjId] = udg_objSpeedY[ObjId]
    set udg_objSpeedZ[BombObjId] = udg_objSpeedZ[ObjId]
    set udg_objBombDrops[ObjId] = udg_objBombDrops[ObjId] - 1
endfunction

function Trig_Loop_FireRapidArtillery takes integer ObjId returns nothing
    local integer BombObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uFragment, udg_objX[ObjId], udg_objY[ObjId], udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]], udg_objAngle[ObjId],0)
    local real Angle = udg_objAngle[ObjId]+GetRandomReal(-3,3)
    local real AngleZ = GetRandomReal(27,33)
    set udg_objSpeedX[BombObjId] = udg_objSpeedX[ObjId] + 38*Cos(Angle*bj_DEGTORAD)*Cos(AngleZ*bj_DEGTORAD)
    set udg_objSpeedY[BombObjId] = udg_objSpeedY[ObjId] + 38*Sin(Angle*bj_DEGTORAD)*Cos(AngleZ*bj_DEGTORAD)
    set udg_objSpeedZ[BombObjId] = udg_objSpeedZ[ObjId] + 38*Sin(AngleZ*bj_DEGTORAD)
    set udg_objBombDrops[ObjId] = udg_objBombDrops[ObjId] - 1
    if GetLocalPlayer()==GetOwningPlayer(udg_objUnit[ObjId]) then
        set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*2,-150),150)
        set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*2,-150),150)
        set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*2,-150),150)
    endif
endfunction

function Trig_Loop_FirePlasma takes integer ObjId returns nothing
    local integer PlasmaProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uPlasma, udg_objX[ObjId]+30*Cos(bj_DEGTORAD*(udg_objAngle[ObjId]-90)), udg_objY[ObjId]+30*Sin(bj_DEGTORAD*(udg_objAngle[ObjId]-90)), udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]]*Cos(udg_objAngleZ[ObjId]), udg_objAngle[ObjId],udg_objAngleZ[ObjId]-2.5)
    set udg_objSpeedX[PlasmaProjectileObjId] = udg_objSpeedX[ObjId] + 200*Cos(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedY[PlasmaProjectileObjId] = udg_objSpeedY[ObjId] + 200*Sin(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedZ[PlasmaProjectileObjId] = udg_objSpeedZ[ObjId] - 6
    set udg_objPlasmaShots[ObjId] = udg_objPlasmaShots[ObjId] - 1
endfunction

function Trig_Loop_FireBullet takes integer ObjId returns nothing
    local integer BulletClass
    local integer BulletObjId
    local real X = udg_objX[ObjId]
    local real Y = udg_objY[ObjId]
    local real AccelerationXY
    local real angle = udg_objAngle[ObjId]+GetRandomReal(-0.5,0.5)
    if udg_objClass[ObjId]==udg_uHammerhead or udg_objClass[ObjId]==udg_uRaptor then
        set BulletClass = udg_uBlueBullet
        set udg_objBulletSlot[ObjId] = 1-udg_objBulletSlot[ObjId]
        set X = X+60*Cos(bj_DEGTORAD*(udg_objAngle[ObjId]-90*(1-2*udg_objBulletSlot[ObjId])))
        set Y = Y+60*Sin(bj_DEGTORAD*(udg_objAngle[ObjId]-90*(1-2*udg_objBulletSlot[ObjId])))
    else
        set BulletClass = udg_uBullet
    endif
    set BulletObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), BulletClass, X, Y, udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]]*Cos(udg_objAngleZ[ObjId]), angle,udg_objAngleZ[ObjId]+GetRandomReal(-0.5,0.5))
    set AccelerationXY = 300*Cos(udg_objAngleZ[BulletObjId]*bj_DEGTORAD)
    set udg_objSpeedX[BulletObjId] = udg_objSpeedX[ObjId] + AccelerationXY*Cos(angle*bj_DEGTORAD)
    set udg_objSpeedY[BulletObjId] = udg_objSpeedY[ObjId] + AccelerationXY*Sin(angle*bj_DEGTORAD)
    set udg_objSpeedZ[BulletObjId] = udg_objSpeedZ[ObjId] + 300*Sin(udg_objAngleZ[BulletObjId]*bj_DEGTORAD)
    set udg_objLifeSpan[BulletObjId] = 0.75
    set udg_objMGShots[ObjId] = udg_objMGShots[ObjId] - 1
endfunction

function Trig_Loop_FireFlame takes integer ObjId returns nothing
    local integer BulletObjId
    local real X = udg_objX[ObjId]
    local real Y = udg_objY[ObjId]
    local real AccelerationXY
    set BulletObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uFlame, X, Y, udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]]*Cos(udg_objAngleZ[ObjId]), udg_objAngle[ObjId]+GetRandomReal(-6,6),udg_objAngleZ[ObjId]+GetRandomReal(-3,3))
    set AccelerationXY = 50*Cos(udg_objAngleZ[BulletObjId]*bj_DEGTORAD)
    set udg_objSpeedX[BulletObjId] = udg_objSpeedX[ObjId] + AccelerationXY*Cos(udg_objAngle[BulletObjId]*bj_DEGTORAD)
    set udg_objSpeedY[BulletObjId] = udg_objSpeedY[ObjId] + AccelerationXY*Sin(udg_objAngle[BulletObjId]*bj_DEGTORAD)
    set udg_objSpeedZ[BulletObjId] = udg_objSpeedZ[ObjId] + 50*Sin(udg_objAngleZ[BulletObjId]*bj_DEGTORAD)
    set udg_objLifeSpan[BulletObjId] = GetRandomReal(1.7,2)
    set udg_objFlameShots[ObjId] = udg_objFlameShots[ObjId] - 1
endfunction

function Trig_Loop_AIControl takes integer ObjId returns nothing
    local unit Obj = udg_objUnit[ObjId]
    local integer Class = udg_objClass[ObjId]
    local real TargetX
    local real TargetY
    local real TargetZ
    local real TargetZMove
    local real DistX
    local real DistY
    local real DistZ
    local real r
    local real r2
    local real r3
    local real d
    local real AngleAim
    local real AngleZAim
    local real X = udg_objX[ObjId]
    local real Y = udg_objY[ObjId]
    local real Z = udg_objZ[ObjId]
    local integer TargetObjId = udg_playerControlledObj[udg_objAITargetPlayer[ObjId]]
    local boolean OnlyBombs = false
    local real SpeedXY = SquareRoot(udg_objSpeedX[ObjId]*udg_objSpeedX[ObjId]+udg_objSpeedY[ObjId]*udg_objSpeedY[ObjId])
    local real Speed = SquareRoot(SpeedXY*SpeedXY+udg_objSpeedZ[ObjId]*udg_objSpeedZ[ObjId])
    //Follow Target
    if udg_objUnit[TargetObjId]==null then
        set TargetX = -1800
        set TargetY = -1800
        set TargetZ = 3000
        set TargetZMove = TargetZ
        set DistX = TargetX - X
        set DistY = TargetY - Y
        set r = SquareRoot(DistX*DistX+DistY*DistY)
    else
        set TargetX = udg_objX[TargetObjId]
        set TargetY = udg_objY[TargetObjId]
        set TargetZ = udg_objZ[TargetObjId]+udg_classCollisionOffset[udg_objClass[TargetObjId]]-udg_classBulletOffsetZ[Class]
        set TargetZMove = TargetZ
        set DistX = TargetX - X
        set DistY = TargetY - Y
        set DistZ = TargetZ - Z
        set r = SquareRoot(DistX*DistX+DistY*DistY+DistZ*DistZ)
        set OnlyBombs = ((Z-TargetZ)>150 and (Class-udg_uME109)*(Class-udg_uJu87)*(Class-udg_uA10)*(Class-udg_uB17)==0) or Class==udg_uStealth
        if OnlyBombs then
            set r3 = RMaxBJ(Speed,5)
            set TargetZMove = TargetZMove+1000
            set TargetX = TargetX+(udg_objSpeedX[TargetObjId])*(r/r3)
            set TargetY = TargetY+(udg_objSpeedY[TargetObjId])*(r/r3)
            set TargetZ = TargetZ+(udg_objSpeedZ[TargetObjId])*(r/r3)
        else
            if Class==udg_uOrca then
                set r3 = Speed+200
            else
                set r3 = Speed+400
            endif
            set TargetX = TargetX+(udg_objSpeedX[TargetObjId]-udg_objSpeedX[ObjId])*(r/r3)
            set TargetY = TargetY+(udg_objSpeedY[TargetObjId]-udg_objSpeedY[ObjId])*(r/r3)
            set TargetZ = TargetZ+(udg_objSpeedZ[TargetObjId]-udg_objSpeedZ[ObjId])*(r/r3)
        endif
        set DistX = TargetX - X
        set DistY = TargetY - Y
        set r = SquareRoot(DistX*DistX+DistY*DistY)
    endif
    set r3 = GetAIOcclusionHeight(X+udg_objSpeedX[ObjId]*15,Y+udg_objSpeedY[ObjId]*15)
    set r2 = GetAIOcclusionHeight(X+udg_objSpeedX[ObjId]*5,Y+udg_objSpeedY[ObjId]*5)
    if r2>r3 then
        set r3 = r2
    endif
    if TargetZMove<r3+250 and (Class-udg_uCobra)*(Class-udg_uOrca)!=0 then
        set TargetZMove = r3+250
    endif

    set AngleAim = bj_RADTODEG * Atan2(DistY, DistX)
    set AngleZAim = bj_RADTODEG * Atan2(TargetZMove - Z, r)
    set r2 = SquareRoot(Pow(DiffBetweenAngles(AngleAim,udg_objAngle[ObjId]),2)+Pow(DiffBetweenAngles(bj_RADTODEG * Atan2(TargetZ - Z, r),udg_objAngleZ[ObjId]),2))
       
    // Set Speed
    if (Class-udg_uCobra)*(Class-udg_uOrca)==0 then
        if r2<20 and Z>TargetZ and Z+udg_objSpeedZ[ObjId]*60>r3 then
            set udg_objAcceleration[ObjId]=udg_classAccelerationLow[Class]*0.25+udg_classAccelerationHigh[Class]*0.75
        elseif Z>TargetZ+250 then
            set udg_objAcceleration[ObjId]=udg_classAccelerationLow[Class]
        else
            set udg_objAcceleration[ObjId]=udg_classAccelerationHigh[Class]
        endif
    else
        set udg_objAcceleration[ObjId]=udg_classAccelerationHigh[Class]
    endif

    if (Class-udg_uCobra)*(Class-udg_uOrca)==0 and Z+udg_objSpeedZ[ObjId]*60<r3 then
        set udg_objAcceleration[ObjId]=udg_classAccelerationHigh[Class]
        set AngleZAim = 0
    elseif Z+udg_objSpeedZ[ObjId]*100+udg_objAngleZ[ObjId]*15<r3+100 and (Class-udg_uCobra)*(Class-udg_uOrca)!=0 then
        set AngleZAim = SquareRoot(-(Z+udg_objSpeedZ[ObjId]*100+udg_objAngleZ[ObjId]*15-r3-100)/2)
        if AngleZAim<5 then
            set AngleZAim=5
        endif
    elseif r>3000 or r2>90 then
        if (Class-udg_uCobra)*(Class-udg_uOrca)==0 then
            set AngleZAim = -15
        elseif Z<2000+r3 then
            if OnlyBombs and AngleZAim<6 then
                set AngleZAim = 6
            elseif AngleZAim<3 then
                set AngleZAim = 3
            endif
        endif
    endif
           
    if AngleAim<0 then
        set AngleAim=AngleAim+360
    endif
    if AngleAim>udg_objAngle[ObjId]+180 then
        set AngleAim = AngleAim-360
    elseif AngleAim<udg_objAngle[ObjId]-180 then
        set AngleAim = AngleAim+360
    endif
           
    if AngleZAim<0 then
        set AngleZAim=AngleZAim+360
    endif
    if AngleZAim>udg_objAngleZ[ObjId]+180 then
        set AngleZAim = AngleZAim-360
    elseif AngleZAim<udg_objAngleZ[ObjId]-180 then
        set AngleZAim = AngleZAim+360
    endif
    if (Class-udg_uCobra)*(Class-udg_uOrca)==0 then
        if AngleZAim<-40 then
            set AngleZAim=-40
        endif
    else
        if AngleZAim<-25 then
            set AngleZAim=-25
        endif
        if AngleZAim>25 then
            set AngleZAim = 25
        endif
    endif
    if udg_objUnit[TargetObjId]!=null then
        if Class==udg_uOrca then
            if r2<2 and udg_objAIWeaponCooldown2[ObjId]<=0 then
                call Trig_Loop_FirePhotonCannon(ObjId)
                set udg_objAIWeaponCooldown2[ObjId]=3
            endif
        elseif r2<3 and r<5000 and not OnlyBombs then
            set udg_objMGShots[ObjId]=4
        endif
        //if r2<5 and TargetZ<500+r3 and t==udg_uStealth and GetUnitState(udg_objUnit[ObjId],UNIT_STATE_MANA)>=1 then
        //  call Trig_Loop_FireNuclear(ObjId)
        //endif
        if udg_objAIWeaponCooldown[ObjId]<=0 then
            if (Class-udg_uME109)*(Class-udg_uJu87)*(Class-udg_uA10)*(Class-udg_uB17)*(Class-udg_uStealth)==0 then
                if udg_constGravity>0 then
                    set d = r-((SquareRoot(udg_objSpeedZ[ObjId]*udg_objSpeedZ[ObjId]/(udg_constGravity*udg_constGravity)+2*(Z-TargetZ)/udg_constGravity)+udg_objSpeedZ[ObjId]/udg_constGravity)*SpeedXY*Pow(1-udg_classAirFriction[udg_uBomb]*SpeedXY/2,r/(SpeedXY+1)/4))
                    if r>200 and d<300 and d>-100 and DiffBetweenAngles(AngleAim,ModuloReal(Atan2(udg_objSpeedY[ObjId],udg_objSpeedX[ObjId])*bj_RADTODEG,360))<8 and Z>200 then
                        if (Class-udg_uME109)*(Class-udg_uJu87)==0 then
                            set udg_objBombDrops[ObjId]=2
                        else
                            set udg_objBombDrops[ObjId]=6
                        endif
                        set udg_objAIWeaponCooldown[ObjId]=3
                    endif
                endif
            elseif r>500 and r2<30 and GetUnitState(udg_objUnit[ObjId],UNIT_STATE_MANA)>=1 and udg_objClass[TargetObjId]!=udg_uSoldier then
                call FireAimingRocket(ObjId,true)
                set udg_objAIWeaponCooldown[ObjId]=1
            endif
        endif
    endif
    set udg_objAIWeaponCooldown[ObjId] = udg_objAIWeaponCooldown[ObjId] - 0.03
    set udg_objAIWeaponCooldown2[ObjId] = udg_objAIWeaponCooldown2[ObjId] - 0.03
    if udg_objAIFlareCooldown[ObjId]<=0 and udg_objFollowingRockets[ObjId]!=0 and Class!=udg_uME109 and Class!=udg_uJu87 then
        call FireMissileFlares(ObjId)
        if Class==udg_uF22 or Class==udg_uMIG29 then
            set udg_objAIFlareCooldown[ObjId]=11
        else
            set udg_objAIFlareCooldown[ObjId]=6
        endif
    endif
    set udg_objAIFlareCooldown[ObjId] = udg_objAIFlareCooldown[ObjId] - 0.03
    if (Class-udg_uCobra)*(Class-udg_uOrca)==0 then
        if r2>120 and r<2500 then
            set r = 0.1
        else
            set r = 1.0
        endif
    else

        if Z+udg_objSpeedZ[ObjId]*50+udg_objAngleZ[ObjId]*7.5<r3+100 or (r2>90 and r<2500) then
            set r = 0.1
        else
            set r = 1.0
        endif
    endif
           
    // Set XY Angle
    if AngleAim>udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId] then
        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]+udg_classRotation[Class]*r
        if udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId]>AngleAim then
            set udg_objRotateSpeed[ObjId]=AngleAim-udg_objAngle[ObjId]
        endif
    else
        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]-udg_classRotation[Class]*r
        if udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId]<AngleAim then
            set udg_objRotateSpeed[ObjId]=AngleAim-udg_objAngle[ObjId]
        endif
    endif
   
    // Set Z Angle
    if AngleZAim>udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId] then
        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]+udg_classRotationZ[Class]
        if udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId]>AngleZAim then
            set udg_objRotateZSpeed[ObjId]=AngleZAim-udg_objAngleZ[ObjId]
        endif
    else
        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]-udg_classRotationZ[Class]
        if udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId]<AngleZAim then
            set udg_objRotateZSpeed[ObjId]=AngleZAim-udg_objAngleZ[ObjId]
        endif
    endif
endfunction

function Trig_Loop_RocketControl takes integer ObjId returns nothing
    local unit Obj = udg_objUnit[ObjId]
    local integer Class = udg_objClass[ObjId]
    local real TargetX
    local real TargetY
    local real TargetZ
    local real DistX
    local real DistY
    local real DistZ
    local real r
    local real r2
    local real AngleAim
    local real AngleZAim
    local real X = udg_objX[ObjId]
    local real Y = udg_objY[ObjId]
    local real Z = udg_objZ[ObjId]
    local integer TargetObjId
    set TargetObjId = GetUnitUserData(udg_objUnitAim[ObjId])
    //Follow Target
    set TargetX = udg_objX[TargetObjId]
    set TargetY = udg_objY[TargetObjId]
    set TargetZ = udg_objZ[TargetObjId]+udg_classCollisionOffset[udg_objClass[TargetObjId]]
    set DistX = TargetX - X
    set DistY = TargetY - Y
    set DistZ = TargetZ - Z
    set r = SquareRoot(DistX*DistX+DistY*DistY+DistZ*DistZ)
    set r2 = 30+SquareRoot(udg_objSpeedX[ObjId]*udg_objSpeedX[ObjId]+udg_objSpeedY[ObjId]*udg_objSpeedY[ObjId]+udg_objSpeedZ[ObjId]*udg_objSpeedZ[ObjId])
    if r2<60 then
        set r2=60
    endif
    set TargetX = TargetX+(udg_objSpeedX[TargetObjId]-udg_objSpeedX[ObjId])*(r/r2)
    set TargetY = TargetY+(udg_objSpeedY[TargetObjId]-udg_objSpeedY[ObjId])*(r/r2)
    set TargetZ = TargetZ+(udg_objSpeedZ[TargetObjId]-udg_objSpeedZ[ObjId])*(r/r2)
    if TargetZ>3500 then
        set TargetZ = 3500
    endif
    set DistX = TargetX - X
    set DistY = TargetY - Y
    set DistZ = TargetZ - Z
    set AngleAim = bj_RADTODEG * Atan2(DistY, DistX)
    set r = SquareRoot(DistX*DistX+DistY*DistY)
    if (r-TargetZ*10)>0 then
        set AngleZAim = bj_RADTODEG * Atan2(DistZ, r) + (r-TargetZ*10)/666
    else
        set AngleZAim = bj_RADTODEG * Atan2(DistZ, r)
    endif
       
    if AngleAim<0 then
        set AngleAim=AngleAim+360
    endif
    if AngleAim>udg_objAngle[ObjId]+180 then
        set AngleAim = AngleAim-360
    elseif AngleAim<udg_objAngle[ObjId]-180 then
        set AngleAim = AngleAim+360
    endif
   
    if AngleZAim<0 then
        set AngleZAim=AngleZAim+360
    endif
    if AngleZAim>udg_objAngleZ[ObjId]+180 then
        set AngleZAim = AngleZAim-360
    elseif AngleZAim<udg_objAngleZ[ObjId]-180 then
        set AngleZAim = AngleZAim+360
    endif
       
    // Set Speed
    set r = AngleAim-udg_objAngle[ObjId]
    if udg_objAngle[ObjId]-AngleAim>r then
        set r = udg_objAngle[ObjId]-AngleAim
    endif
    if AngleZAim-udg_objAngleZ[ObjId]>r then
        set r = AngleZAim-udg_objAngleZ[ObjId]
    endif
    if udg_objAngleZ[ObjId]-AngleZAim>r then
        set r = udg_objAngleZ[ObjId]-AngleZAim
    endif
    if r>20 then
        set udg_objAcceleration[ObjId]=udg_classAccelerationLow[Class]
    else
        set udg_objAcceleration[ObjId]=udg_classAccelerationHigh[Class]
    endif
    if r>120 then
        set r = 0.7
    else
        set r = 1.0
    endif
       
    // Set XY Angle
    if AngleAim>udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId] then
        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]+udg_classRotation[Class]*r
        if udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId]>AngleAim then
            set udg_objRotateSpeed[ObjId]=AngleAim-udg_objAngle[ObjId]
        endif
    else
        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]-udg_classRotation[Class]*r
        if udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId]<AngleAim then
            set udg_objRotateSpeed[ObjId]=AngleAim-udg_objAngle[ObjId]
        endif
    endif
   
    // Set Z Angle
    if AngleZAim>udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId] then
        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]+udg_classRotationZ[Class]*r
        if udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId]>AngleZAim then
            set udg_objRotateZSpeed[ObjId]=AngleZAim-udg_objAngleZ[ObjId]
        endif
    else
        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]-udg_classRotationZ[Class]*r
        if udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId]<AngleZAim then
            set udg_objRotateZSpeed[ObjId]=AngleZAim-udg_objAngleZ[ObjId]
        endif
    endif
endfunction

function Trig_Loop_BattlefieldLeft takes integer ObjId returns nothing
    local unit Obj = udg_objUnit[ObjId]
    local integer PlayerId = GetPlayerId(GetOwningPlayer(Obj))
    local integer Class = udg_objClass[ObjId]
    if udg_playerControlledObj[PlayerId]==ObjId then
        set udg_playerNoDamage[PlayerId] = false
        call ShowMessage(PlayerId, "|cffcccc00You have left the battlefield!|r")
        call UnitDamageTargetSync(Obj,Obj,GetUnitState(Obj, UNIT_STATE_MAX_LIFE))
    endif
    if udg_objIsProjectile[ObjId] and (Class-udg_uFlare)*(Class-udg_uGrenade)!=0 then
        call KillUnit(Obj)
        if udg_objModel[ObjId]!=null then
            call DestroyEffect(udg_objModel[ObjId])
            set udg_objModel[ObjId] = null
        endif
        call SetUnitScale(Obj,0,0,0)
        call RemoveUnitTimed(Obj, 5)
        call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
        set udg_objUnit[ObjId] = null
    else
        call ObjExplode(Obj)
    endif
    set Obj=null
endfunction

function Trig_Loop_LifeSpanElapsed takes integer ObjId returns nothing
    local unit Obj = udg_objUnit[ObjId]
    local integer PlayerId = GetPlayerId(GetOwningPlayer(Obj))
    local integer Class = udg_objClass[ObjId]
    if udg_playerControlledObj[PlayerId]==ObjId then
        call KillUnit(udg_playerControllerDummy[PlayerId])
    endif
    if udg_objModel[ObjId]!=null then
        call DestroyEffect(udg_objModel[ObjId])
        set udg_objModel[ObjId] = null
    endif
    call SetUnitAnimation( Obj, "death" )
    if GetUnitAbilityLevel(Obj,'Aloc')==1 then
        call KillUnit(Obj)
        if (Class-udg_uFlare)*(Class-udg_uBlueBullet)*(Class-udg_uBullet)*(Class-udg_uBomb)*(Class-udg_uGreatBomb)*(Class-udg_uSmoke)==0 then
            call RemoveUnit(Obj)
        else
            call SetUnitScale(Obj,0,0,0)
        endif
    else
        set udg_objLifeSpan[ObjId] = -1
        call ObjExplode(Obj)
    endif
    call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
    set udg_objUnit[ObjId] = null
    set Obj=null
endfunction

function Trig_Loop_Actions takes nothing returns nothing
    local integer ObjId = 0
    local integer MaxObjId = -1
    local integer TargetClass
    local integer TargetObjId
    local unit Obj
    local real Break
    local real X
    local real Y
    local real Z
    local real SpeedXY
    local real SpeedX
    local real SpeedY
    local real SpeedZ
    local real SpeedZGroundHit
    local real Speed
    local real SpeedFactor
    local real GroundFrictionFactor
    local real r
    local real r2
    local real AngleCos
    local real AngleSin
    local real AngleZCos
    local real AngleZSin
    local real AccelerationXY
    local integer PlayerId
    local integer Class
    local integer i
    local integer imax
    local real EnvironmentHeight
    local boolean IsFlying
    local boolean MovingBackWards
    local boolean CheckTerrain
    local boolean CheckUnits
    local boolean Do
    local boolean RefreshPosition
    local boolean ShowTextTag
   
    if udg_loopThreadOpen then
        call ShowMessageAll("|cffcc0000Loop Thread aborted!")
    endif
    set udg_loopThreadOpen=true
   
    loop
        if udg_objUnit[ObjId]!=null then
            set Obj = udg_objUnit[ObjId]
            set Class = udg_objClass[ObjId]
            set Do = true

            if udg_objLifeSpan[ObjId]!=-1 then
                set udg_objLifeSpan[ObjId] = udg_objLifeSpan[ObjId] - 0.03
                if udg_objLifeSpan[ObjId] <= 0 then
                    if (Class-udg_uGrenade)*(Class-udg_uSmoke)*(Class-udg_uGravityGun)*(Class-udg_uArtilleryShot)*(Class-udg_uPlasmaBomb)==0 then
                        call ObjExplode(Obj)
                    else
                        call Trig_Loop_LifeSpanElapsed(ObjId)
                    endif
                    set Do = false
                endif
            endif

            if Do then
                set Break = 0
                set X = udg_objX[ObjId]
                set Y = udg_objY[ObjId]
                set Z = udg_objZ[ObjId]
                set SpeedX = udg_objSpeedX[ObjId]
                set SpeedY = udg_objSpeedY[ObjId]
                set SpeedZ = udg_objSpeedZ[ObjId]
                set PlayerId = GetPlayerId(GetOwningPlayer(Obj))
                set EnvironmentHeight = udg_objLastEnvironmentHeight[ObjId]
                set IsFlying = Z>udg_classHoverHeight[Class]+EnvironmentHeight or udg_objDead[ObjId] or SpeedZ>udg_constGravity
                set MovingBackWards = false
                set RefreshPosition = true
               
                //Control
                if not udg_objIsProjectile[ObjId] then
                    if udg_objDead[ObjId] or PlayerId>11 then
                        if IsFlying then
                            if udg_objRotateSpeed[ObjId]>0 then
                                set r=1
                            elseif udg_objRotateSpeed[ObjId]<0 then
                                set r=-1
                            else
                                set r = GetRandomInt(0,1)*2-1
                            endif
                            set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]+r*udg_classRotation[Class]*0.5
                            if udg_objRotateZSpeed[ObjId]>0 then
                                set r=1
                            elseif udg_objRotateZSpeed[ObjId]<0 then
                                set r=-1
                            else
                                set r = GetRandomInt(0,1)*2-1
                            endif
                            if udg_classRotationZ[Class]==0 then
                                set udg_objAcceleration[ObjId] = 0
                            else
                                set udg_objRotateZSpeed[ObjId]=udg_objRotateZSpeed[ObjId]+r*udg_classRotationZ[Class]*0.5
                                set udg_objAcceleration[ObjId] = udg_classAccelerationLow[Class]
                            endif
                        else
                            set Break=1.0
                            if (Class-udg_uOrca)*(Class-udg_uCobra)==0 then
                                set udg_objAcceleration[ObjId] = (udg_classAccelerationLow[Class]+udg_classAccelerationHigh[Class])/2
                            else
                                set udg_objAcceleration[ObjId] = 0
                            endif
                            if udg_objAngleZ[ObjId]!=0 then
                                if udg_objRotateSpeed[ObjId]>0 then
                                    if udg_objRotateSpeed[ObjId]-udg_classRotation[Class]<0 then
                                        set udg_objRotateSpeed[ObjId]=0
                                    else
                                        set udg_objRotateSpeed[ObjId]=udg_objRotateSpeed[ObjId]-udg_classRotation[Class]
                                    endif
                                else
                                    if udg_objRotateSpeed[ObjId]+udg_classRotation[Class]>0 then
                                        set udg_objRotateSpeed[ObjId]=0
                                    else
                                        set udg_objRotateSpeed[ObjId]=udg_objRotateSpeed[ObjId]+udg_classRotation[Class]
                                    endif
                                    set r=-udg_objRotateSpeed[ObjId]
                                endif
                            else
                                set RefreshPosition=((SpeedX*SpeedX+SpeedY*SpeedY+SpeedZ*SpeedZ)!=0)
                            endif
                        endif
                    elseif PlayerId < 10 then
                        if SpeedX!=0 or SpeedY!=0 then
                            set r2=udg_objAngle[ObjId]-Atan2(SpeedY,SpeedX)*bj_RADTODEG
                            if r2<-180 then
                                set r2=r2+360
                            elseif r2>180 then
                                set r2=r2-360
                            endif
                            set MovingBackWards = (r2>90 or r2<-90)
                        endif
                        if udg_playerKeyPressed[PlayerId*4] then
                            set r = 1
                        elseif udg_playerKeyPressed[PlayerId*4+1] then
                            set r = -1
                        else
                            set r = 0
                        endif
                        if r==0 then
                            if udg_objRotateSpeed[ObjId]>0 then
                                if udg_objRotateSpeed[ObjId]-udg_classRotation[Class]<0 then
                                    set udg_objRotateSpeed[ObjId]=0
                                else
                                    set udg_objRotateSpeed[ObjId]=udg_objRotateSpeed[ObjId]-udg_classRotation[Class]
                                endif
                            else
                                if udg_objRotateSpeed[ObjId]+udg_classRotation[Class]>0 then
                                    set udg_objRotateSpeed[ObjId]=0
                                else
                                    set udg_objRotateSpeed[ObjId]=udg_objRotateSpeed[ObjId]+udg_classRotation[Class]
                                endif
                                set r=-udg_objRotateSpeed[ObjId]
                            endif
                        else
                            if udg_classRotationZ[Class]==0 and MovingBackWards and (not IsFlying) and SpeedX*SpeedX+SpeedY*SpeedY>0.1 then
                                set r=-r
                            endif
                            set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]+r*udg_classRotation[Class]
                        endif

                        if udg_classRotationZ[Class]!=0 then
                            set r=0
                            if udg_playerKeyPressed[PlayerId*4+2] then
                                set r = 1
                            elseif udg_playerKeyPressed[PlayerId*4+3] then
                                set r = -1
                            endif
                            set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]+r*udg_classRotationZ[Class]
                            if r==0 then
                                if udg_objRotateZSpeed[ObjId]>0 then
                                    if udg_objRotateZSpeed[ObjId]-udg_classRotationZ[Class]<0 then
                                        set udg_objRotateZSpeed[ObjId]=0
                                    else
                                        set udg_objRotateZSpeed[ObjId]=udg_objRotateZSpeed[ObjId]-udg_classRotationZ[Class]
                                    endif
                                else
                                    if udg_objRotateZSpeed[ObjId]+udg_classRotationZ[Class]>0 then
                                        set udg_objRotateZSpeed[ObjId]=0
                                    else
                                        set udg_objRotateZSpeed[ObjId]=udg_objRotateZSpeed[ObjId]+udg_classRotationZ[Class]
                                    endif
                                endif
                            endif
                            if udg_objAcceleration[ObjId]==0 and ((Class-udg_uOrca)*(Class-udg_uCobra)!=0)  then
                                set Break = 1.0
                            endif
                        else
                            if udg_playerKeyPressed[PlayerId*4+2] then
                                set udg_objAcceleration[ObjId] = -udg_classAccelerationLow[Class]
                            elseif udg_playerKeyPressed[PlayerId*4+3] then
                                set udg_objAcceleration[ObjId] = udg_classAccelerationHigh[Class]
                            else
                                set udg_objAcceleration[ObjId] = 0
                                if Class==udg_uSoldier then
                                    set Break = 1.0
                                endif
                            endif
                            if IsFlying then
                                set udg_objAcceleration[ObjId] = udg_objAcceleration[ObjId]*0.01
                            endif
                        endif
                    elseif udg_objAI[ObjId] then
                        call Trig_Loop_AIControl(ObjId)
                    endif
                elseif udg_classRotation[Class]!=0 then
                    if udg_objUnitAim[ObjId]!=null then
                        call Trig_Loop_RocketControl(ObjId)
                    else
                        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId] + GetRandomReal(-udg_classRotation[Class],udg_classRotation[Class])/2
                        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId] + GetRandomReal(-udg_classRotationZ[Class],udg_classRotationZ[Class])/2
                    endif
                endif
               
                // Rotation
                if udg_objRotateZSpeed[ObjId]!=0 then
                    set udg_objAngleZ[ObjId] = udg_objAngleZ[ObjId]+udg_objRotateZSpeed[ObjId]
                    if udg_objRotateZSpeed[ObjId]>0 then
                        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]*(1-(5+udg_objRotateZSpeed[ObjId]*2)*udg_classRotationFriction[Class])
                    else
                        set udg_objRotateZSpeed[ObjId] = udg_objRotateZSpeed[ObjId]*(1-(5-udg_objRotateZSpeed[ObjId]*2)*udg_classRotationFriction[Class])
                    endif
                    set udg_objAngleZ[ObjId] = udg_objAngleZ[ObjId]-R2I((udg_objAngleZ[ObjId]+180)/360)*360
                    if udg_objAngleZ[ObjId]<-180 then
                        set udg_objAngleZ[ObjId] = udg_objAngleZ[ObjId]+360
                    endif
                endif
                if udg_objRotateSpeed[ObjId]!=0 then
                    set udg_objAngle[ObjId] = udg_objAngle[ObjId]+udg_objRotateSpeed[ObjId]
                    if udg_objRotateSpeed[ObjId]>0 then
                        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]*(1-(5+udg_objRotateSpeed[ObjId]*2)*udg_classRotationFriction[Class])
                    else
                        set udg_objRotateSpeed[ObjId] = udg_objRotateSpeed[ObjId]*(1-(5-udg_objRotateSpeed[ObjId]*2)*udg_classRotationFriction[Class])
                    endif
                    set udg_objAngle[ObjId] = udg_objAngle[ObjId]-R2I(udg_objAngle[ObjId]/360)*360
                    if udg_objAngle[ObjId]<0 then
                        set udg_objAngle[ObjId] = udg_objAngle[ObjId]+360
                    endif
                endif

                if RefreshPosition then
                    if udg_classAirFriction[Class]!=0 then
                        set Speed=SpeedX*SpeedX+SpeedY*SpeedY+SpeedZ*SpeedZ
                        if ((Speed!=0 or IsFlying) and udg_classHasAnySideFriction[Class]) or udg_objAcceleration[ObjId]!=0 then
                            set AngleCos = Cos(udg_objAngle[ObjId]*bj_DEGTORAD)
                            set AngleSin = Sin(udg_objAngle[ObjId]*bj_DEGTORAD)
                            set AngleZCos = Cos(udg_objAngleZ[ObjId]*bj_DEGTORAD)
                            set AngleZSin = Sin(udg_objAngleZ[ObjId]*bj_DEGTORAD)
                        endif
               
                        // Acceleration
                        if udg_objDead[ObjId] then
                            set SpeedZ = SpeedZ-udg_constGravity
                        else
                            set SpeedZ = SpeedZ-udg_constGravity*udg_classGravityFactor[Class]
                        endif
                        if udg_classAccelerationHigh[Class]!=0 then
                            if udg_objAcceleration[ObjId]!=0 then
                                if (Class-udg_uOrca)*(Class-udg_uCobra)==0 then
                                    set SpeedX = SpeedX-udg_objAcceleration[ObjId]*AngleZSin*AngleCos
                                    set SpeedY = SpeedY-udg_objAcceleration[ObjId]*AngleZSin*AngleSin
                                    set SpeedZ = SpeedZ+udg_objAcceleration[ObjId]*AngleZCos
                                else
                                    set SpeedX = SpeedX+udg_objAcceleration[ObjId]*AngleZCos*AngleCos
                                    set SpeedY = SpeedY+udg_objAcceleration[ObjId]*AngleZCos*AngleSin
                                    set SpeedZ = SpeedZ+udg_objAcceleration[ObjId]*AngleZSin
                                endif
                            endif
                            if Z>3500 and SpeedZ>0 then
                                set SpeedZ=SpeedZ-(Z-3500)/100
                            endif
                        endif
               
                        if not IsFlying then
                            if SpeedZ<0 then
                                set SpeedZGroundHit = SpeedZ
                                set SpeedZ=0
                            else
                                set SpeedZGroundHit = 0
                            endif
                        endif
               
                        // Friction
                        set Speed=SpeedX*SpeedX+SpeedY*SpeedY+SpeedZ*SpeedZ
                        if Speed*udg_classAirFriction[Class]!=0 then
                            set Speed=SquareRoot(Speed)
                            set SpeedFactor = 1-udg_classAirFriction[Class]*Speed
                            if not IsFlying then
                                set i = GetTerrainType(X, Y)
                                if udg_constGravity<=0 then
                                    set GroundFrictionFactor = (0.1-(SpeedZ+SpeedZGroundHit)*4.5)*(1+(udg_terrainFriction[i-(i/8190)*8190]-1)*udg_classTerrainInfluence[Class])
                                else
                                    set GroundFrictionFactor=(0.1-(SpeedZ+SpeedZGroundHit)/(udg_constGravity+0.4)*1.8)*(1+(udg_terrainFriction[i-(i/8190)*8190]-1)*udg_classTerrainInfluence[Class])
                                endif
                                if GroundFrictionFactor<0 then
                                    set GroundFrictionFactor=0
                                endif
                                set SpeedFactor=SpeedFactor*(1-(1+1/(Speed+0.0001))*udg_classGroundFriction[Class]*GroundFrictionFactor)*(1-(0.01+Break*udg_classBreaks[Class])/(Speed+0.0001))
                            else
                                set GroundFrictionFactor = 0
                            endif
                            if udg_objParachute[ObjId]!=null then
                                set SpeedFactor = SpeedFactor*(1-0.0035*Speed)
                            endif
                            if Speed*SpeedFactor<0.01 then
                                set SpeedFactor = 0
                            endif
               
                            if Speed*SpeedFactor!=0 and udg_classHasAnySideFriction[Class] then
                                set SpeedXY = SquareRoot(SpeedX*SpeedX+SpeedY*SpeedY)
                                if SpeedXY!=0 then
                                    set r2=udg_objAngle[ObjId]-Atan2(SpeedY,SpeedX)*bj_RADTODEG
                                    if r2<-180 then
                                        set r2=r2+360
                                    elseif r2>180 then
                                        set r2=r2-360
                                    endif
                                    set MovingBackWards = (r2>90 or r2<-90)
                                    set r2 = (1-(1-(1+1/(SpeedXY+0.0001))*udg_classGroundFrictionSide[Class]*GroundFrictionFactor)*(1-udg_classAirFrictionSide[Class]*Speed))*Speed*Sin(r2*bj_DEGTORAD)
                                else
                                    set r2 = 0
                                endif
                                if MovingBackWards then
                                    set r=-udg_classAirFrictionTop[Class]*Speed*Speed*Sin((Atan2(SpeedZ,-SpeedXY)*bj_RADTODEG-udg_objAngleZ[ObjId]-udg_classWingAngle[Class])*bj_DEGTORAD)
                                else
                                    set r=-udg_classAirFrictionTop[Class]*Speed*Speed*Sin((Atan2(SpeedZ,SpeedXY)*bj_RADTODEG-udg_objAngleZ[ObjId]-udg_classWingAngle[Class])*bj_DEGTORAD)
                                endif
                                set SpeedX = (SpeedX-r2*AngleSin-r*AngleCos*AngleZSin)*SpeedFactor
                                set SpeedY = (SpeedY+r2*AngleCos-r*AngleSin*AngleZSin)*SpeedFactor
                                set SpeedZ = (SpeedZ+r*AngleZCos)*SpeedFactor
                            else
                                set SpeedX = SpeedX*SpeedFactor
                                set SpeedY = SpeedY*SpeedFactor
                                set SpeedZ = SpeedZ*SpeedFactor
                            endif
                        endif

                        // Finishing Data
                        if not IsFlying then
                            if udg_objAngleZ[ObjId]!=0 then
                                set r2=udg_objAngleZ[ObjId]
                                if r2>90 then
                                    set r2=r2-180
                                    set r = 1
                                elseif r2<-90 then
                                    set r2=r2+180
                                    set r = -1
                                elseif (r2>0 and r2<90) then
                                    set r = -1
                                else
                                    set r = 1
                                endif
                                if (Class-udg_uOrca)*(Class-udg_uCobra)==0 then
                                    set udg_objRotateZSpeed[ObjId]=0.95*udg_objRotateZSpeed[ObjId]+(udg_objRotateZSpeed[ObjId]+r2)*(r2*Pow(RMaxBJ(SpeedZ+SpeedZGroundHit-udg_constGravity,-3)*2.5,2)*r/300)
                                else
                                    set udg_objRotateZSpeed[ObjId]=0.95*udg_objRotateZSpeed[ObjId]+(udg_objRotateZSpeed[ObjId]+r2)*(r2*Pow(RMaxBJ(SpeedZ+SpeedZGroundHit,-3)*2.5,2)*r/300)
                                endif
                            endif
               
                            if SpeedZ+SpeedZGroundHit<0 then
                                set SpeedZ=0
                            endif
                   
                            if udg_objParachute[ObjId]!=null then
                                call DestroyEffect(udg_objParachuteEffect[ObjId])
                                call RemoveUnitTimed(udg_objParachute[ObjId],1)
                                set udg_objParachute[ObjId]=null
                            endif
                        endif
                    endif

                    // Movement
                    set Speed=SpeedX*SpeedX+SpeedY*SpeedY+SpeedZ*SpeedZ
                    if Speed!=0 then
                        set RefreshPosition = true
                        if X+SpeedX < -16896 or Y+SpeedY < -16896 or Y+SpeedY > 12800 or X+SpeedX > 12800 or Z+SpeedZ > 5000 then
                            call Trig_Loop_BattlefieldLeft(ObjId)
                            set Do = false
                        else
                            if udg_objIsProjectile[ObjId] and (Class-udg_uFlare)*(Class-udg_uGrenade)*(Class-udg_uSmoke)!=0 then
                                // Collision With Units
                                set Speed=SquareRoot(Speed)
                                set i = 1
                                set imax = R2I(Speed/66)+1
                                if SpeedZ<0 then
                                    set r = Z+SpeedZ-udg_classHoverHeight[Class]
                                else
                                    set r = Z-udg_classHoverHeight[Class]
                                endif
                                set CheckTerrain=imax<2 or (GetEnvironmentHeight(X+SpeedX/2,Y+SpeedY/2,udg_classCollision[Class]+Speed/2,r)+udg_classHoverHeight[Class]>Z+SpeedZ/2)
                                set CheckUnits=imax<2 or IsTargetNearby(Obj, X+SpeedX/2, Y+SpeedY/2, Z+SpeedZ/2, udg_classCollision[Class]+Speed/2, false)
                                if CheckTerrain or CheckUnits then
                                    loop
                                        exitwhen i > imax
                                        if (CheckTerrain and (GetEnvironmentHeight(X+(SpeedX*i)/imax,Y+(SpeedY*i)/imax,udg_classCollision[Class],r)+udg_classHoverHeight[Class]>Z+(SpeedZ*i)/imax)) or (CheckUnits and IsTargetNearby(Obj, X+(SpeedX*i)/imax, Y+(SpeedY*i)/imax, Z+(SpeedZ*i)/imax, udg_classCollision[Class], false)) then
                                            if (CheckTerrain and (GetEnvironmentHeight(X+(SpeedX*(i-0.66))/imax,Y+(SpeedY*(i-0.66))/imax,udg_classCollision[Class],r)+udg_classHoverHeight[Class]>Z+(SpeedZ*(i-0.66))/imax)) or (CheckUnits and IsTargetNearby(Obj, X+(SpeedX*(i-0.66))/imax, Y+(SpeedY*(i-0.66))/imax, Z+(SpeedZ*(i-0.66))/imax, udg_classCollision[Class], false)) then
                                                set udg_objX[ObjId] = X+(SpeedX*(i-0.66))/imax
                                                set udg_objY[ObjId] = Y+(SpeedY*(i-0.66))/imax
                                                set udg_objZ[ObjId] = Z+(SpeedZ*(i-0.66))/imax
                                            elseif (CheckTerrain and (GetEnvironmentHeight(X+(SpeedX*(i-0.33))/imax,Y+(SpeedY*(i-0.33))/imax,udg_classCollision[Class],r)+udg_classHoverHeight[Class]>Z+(SpeedZ*(i-0.33))/imax)) or (CheckUnits and IsTargetNearby(Obj, X+(SpeedX*(i-0.33))/imax, Y+(SpeedY*(i-0.33))/imax, Z+(SpeedZ*(i-0.33))/imax, udg_classCollision[Class], false)) then
                                                set udg_objX[ObjId] = X+(SpeedX*(i-0.33))/imax
                                                set udg_objY[ObjId] = Y+(SpeedY*(i-0.33))/imax
                                                set udg_objZ[ObjId] = Z+(SpeedZ*(i-0.33))/imax
                                            else
                                                set udg_objX[ObjId] = X+(SpeedX*i)/imax
                                                set udg_objY[ObjId] = Y+(SpeedY*i)/imax
                                                set udg_objZ[ObjId] = Z+(SpeedZ*i)/imax
                                            endif
                                            call SetUnitPosition(Obj, udg_objX[ObjId], udg_objY[ObjId])
                                            call ObjExplode(Obj)
                                            set Do = false
                                            exitwhen true
                                        endif
                                        set i = i + 1
                                    endloop
                                endif

                                set X = X + SpeedX
                                set Y = Y + SpeedY
                                set Z = Z + SpeedZ
                            else
                                // Ground Collision
                                if SpeedZ<0 then
                                    set r2 = Z+SpeedZ-udg_classHoverHeight[Class]
                                else
                                    set r2 = Z-udg_classHoverHeight[Class]
                                endif
                                set EnvironmentHeight = GetEnvironmentHeight(X + SpeedX,Y + SpeedY,udg_classCollision[Class],r2)
                                if Z-udg_classHoverHeight[Class]+SpeedZ<EnvironmentHeight and not udg_objDead[ObjId] then
                                    set r = 0
                                    if Z-udg_classHoverHeight[Class]<EnvironmentHeight then
                                        if Z-udg_classHoverHeight[Class]>=GetEnvironmentHeight(X,Y+SpeedY,udg_classCollision[Class],r2) then
                                            if udg_objIsProjectile[ObjId] then
                                                set SpeedX=SpeedX*udg_classGroundFriction[Class]-SpeedX
                                            else
                                                set r = SpeedX*SpeedX
                                                set SpeedX=0
                                            endif
                                            set SpeedY=SpeedY-SpeedY*udg_classGroundFriction[Class]
                                            set Y = Y+SpeedY
                                        elseif Z-udg_classHoverHeight[Class]>=GetEnvironmentHeight(X+SpeedX,Y,udg_classCollision[Class],r2) then
                                            if udg_objIsProjectile[ObjId] then
                                                set SpeedY=SpeedY*udg_classGroundFriction[Class]-SpeedY
                                            else
                                                set r = SpeedY*SpeedY
                                                set SpeedY=0
                                            endif
                                            set SpeedX=SpeedX-SpeedX*udg_classGroundFriction[Class]
                                            set X = X+SpeedX
                                        else
                                            if udg_objIsProjectile[ObjId] then
                                                set SpeedX=SpeedX*udg_classGroundFriction[Class]-SpeedX
                                                set SpeedY=SpeedY*udg_classGroundFriction[Class]-SpeedY
                                            else
                                                set r = SpeedX*SpeedX+SpeedY*SpeedY
                                                set SpeedX=0
                                                set SpeedY=0
                                            endif
                                        endif
                                        set EnvironmentHeight=GetEnvironmentHeight(X,Y,udg_classCollision[Class],r2)
                                        if Z-udg_classHoverHeight[Class]+SpeedZ<EnvironmentHeight and Z-udg_classHoverHeight[Class]>=EnvironmentHeight then
                                            if udg_objIsProjectile[ObjId] then
                                                set SpeedZ = SpeedZ*udg_classGroundFriction[Class]-SpeedZ
                                            else
                                                set r = r+SpeedZ*SpeedZ
                                                set SpeedZ = 0
                                            endif
                                            set Z = EnvironmentHeight+udg_classHoverHeight[Class]
                                        else
                                            set Z = Z+SpeedZ
                                            set SpeedZ=SpeedZ-SpeedZ*udg_classGroundFriction[Class]
                                        endif
                                    else
                                        if udg_objIsProjectile[ObjId] then
                                            set SpeedZ = SpeedZ*udg_classGroundFriction[Class]-SpeedZ
                                        else
                                            set r = SpeedZ*SpeedZ
                                            set SpeedZ = 0
                                        endif
                                        set X = X + SpeedX
                                        set Y = Y + SpeedY
                                        set Z = EnvironmentHeight+udg_classHoverHeight[Class]
                                    endif
                                    set r = (r/(udg_classBreaks[Class]+0.1)*udg_constCollisionDamage-250)/25
                                    if r>0 then
                                        if (Class==udg_uSoldier) then
                                            call SpecialEffectScaledTimedWithZ("Objects\\Spawnmodels\\Critters\\Albatross\\CritterBloodAlbatross.mdl", X, Y, Z, 1, 1, 0, 2)
                                        else
                                            call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl", X, Y, Z, 1, 1, 0, 2)
                                        endif
                                        call UnitDamageTargetSync(Obj,Obj,r)
                                    endif
                                else
                                    set X = X + SpeedX
                                    set Y = Y + SpeedY
                                    set Z = Z + SpeedZ
                                endif
                            endif
                            // Ground Collision End
                        endif
                    endif
                    if Do then
                        // Animation
                        if udg_classRotationZ[Class]!=0 then
                            call SetUnitZFacing(Obj,udg_objAngleZ[ObjId])
                        elseif udg_objIsProjectile[ObjId] then
                            if Class==udg_uFlare then
                                call SetUnitScale(Obj,udg_objLifeSpan[ObjId]/2,udg_objLifeSpan[ObjId]/2,udg_objLifeSpan[ObjId]/2)
                            elseif Class==udg_uGrenade then
                                call SetUnitTimeScale( Obj, 0.2*Speed )
                            endif
                        elseif IsFlying then
                            call SetUnitTimeScale( Obj, 0.3 )
                        else
                            if (Class-udg_uHowitzer)*(Class-udg_uTank)*(Class-udg_uMLRS)==0 then
                                set r = 0.3
                            elseif (Class-udg_uTitan)*(Class-udg_uHellhound)*(Class-udg_uSoldier)==0 then
                                set r = 0.19
                            else
                                set r = 0.1
                            endif
                            if udg_objRotateSpeed[ObjId]>0 then
                                set r2=udg_objRotateSpeed[ObjId]*2
                            else
                                set r2=-udg_objRotateSpeed[ObjId]*2
                            endif
                            set Speed = SpeedX*SpeedX+SpeedY*SpeedY+SpeedZ*SpeedZ
                            if Speed>r2*r2 then
                                if MovingBackWards then
                                    call SetUnitTimeScale( Obj, -SquareRoot(Speed)*r )
                                else
                                    call SetUnitTimeScale( Obj, SquareRoot(Speed)*r )
                                endif
                            elseif MovingBackWards then
                                call SetUnitTimeScale( Obj, -r2*r )
                            else
                                call SetUnitTimeScale( Obj, r2*r )
                            endif
                        endif

                        // Movement
                        set udg_objSpeedX[ObjId] = SpeedX
                        set udg_objSpeedY[ObjId] = SpeedY
                        set udg_objSpeedZ[ObjId] = SpeedZ
                        set udg_objLastEnvironmentHeight[ObjId] = EnvironmentHeight

                        call SetUnitFlyHeight(Obj, Z, 0)
                        call SetUnitFacing( Obj, udg_objAngle[ObjId] )
                        if udg_objIsProjectile[ObjId] then
                            call SetUnitX(Obj, X)
                            call SetUnitY(Obj, Y)
                        elseif X!=udg_objX[ObjId] or Y!=udg_objY[ObjId] or Z!=udg_objZ[ObjId] or udg_objRotateZSpeed[ObjId]!=0 or udg_objRotateSpeed[ObjId]!=0 then
                            call SetUnitPosition(Obj, X, Y)
                        endif
                        set udg_objX[ObjId] = X
                        set udg_objY[ObjId] = Y
                        set udg_objZ[ObjId] = Z
                        if udg_objParachute[ObjId]!=null then
                            call AdjustParachute(ObjId,false)
                        endif
                        if udg_objDeathFire[ObjId]!=null then
                            call SetUnitFlyHeight(udg_objDeathFire[ObjId], udg_objZ[ObjId]+udg_classCollisionOffset[Class]+GetRandomReal(-0.3,0.3)*udg_classCollision[Class], 0)
                            call SetUnitX(udg_objDeathFire[ObjId], udg_objX[ObjId]+GetRandomReal(-0.3,0.3)*udg_classCollision[Class])
                            call SetUnitY(udg_objDeathFire[ObjId], udg_objY[ObjId]+GetRandomReal(-0.3,0.3)*udg_classCollision[Class])
                        endif
                    endif
                endif
                if Do then
                    if udg_objDead[ObjId] then
                        if EnvironmentHeight+udg_classHoverHeight[Class]<Z then
                            set MaxObjId = ObjId
                        else
                            call ObjExplode(Obj)
                        endif
                    else
                        if not udg_objIsProjectile[ObjId] then
                            // Fire Weapons
                            if udg_objMGShots[ObjId] > 0 and (ObjId+udg_loopMGShooting)/4*4==ObjId+udg_loopMGShooting then
                                call Trig_Loop_FireBullet(ObjId)
                                if Class==udg_uHammerhead or Class==udg_uRaptor then
                                    call Trig_Loop_FireBullet(ObjId)
                                endif
                            elseif udg_objPlasmaShots[ObjId] > 0 and (ObjId+udg_loopBombsDropping)/5*5==ObjId+udg_loopBombsDropping then
                                call Trig_Loop_FirePlasma(ObjId)
                            endif
                            if Class==udg_uHowitzer then
                                if udg_objBombDrops[ObjId] > 0 and ObjId+udg_loopArtilleryFire==(ObjId+udg_loopArtilleryFire)/15*15 then
                                    call Trig_Loop_FireRapidArtillery(ObjId)
                                endif
                            else
                                if udg_objBombDrops[ObjId] > 0 and (ObjId+udg_loopBombsDropping)/5*5==ObjId+udg_loopBombsDropping then
                                    if Class==udg_uMLRS then
                                        call FireAimingRocket(ObjId,false)
                                        set udg_objBombDrops[ObjId] = udg_objBombDrops[ObjId] - 1
                                    else
                                        call Trig_Loop_DropBomb(ObjId)
                                    endif
                                elseif udg_objFlameShots[ObjId] > 0 and (ObjId+udg_loopFlameShooting)/3*3==ObjId+udg_loopFlameShooting then
                                    call Trig_Loop_FireFlame(ObjId)
                                endif
                            endif

                            // Radar
                            if udg_playerRadarOn then
                                set i = udg_playerControlledObj[udg_constLocalPlayerId]
                                if (Class!=udg_uSoldier) and GetUnitAbilityLevel(udg_objUnit[i],'A00S')>0 and i!=ObjId then
                                    set X = udg_objX[ObjId]-GetCameraEyePositionX()
                                    set Y = udg_objY[ObjId]-GetCameraEyePositionY()
                                    set Z = udg_objZ[ObjId]-GetCameraEyePositionZ()
                                    set r = SquareRoot(X*X+Y*Y)
                                    if DiffBetweenAngles(GetCameraField(CAMERA_FIELD_ROTATION)*bj_RADTODEG,Atan2(Y,X)*bj_RADTODEG)>90 then
                                        set r = -r
                                    endif
                                    set ShowTextTag = DiffBetweenAngles(Atan2(Z,r)*bj_RADTODEG,GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)*bj_RADTODEG)<90
                                    if ShowTextTag then
                                        if X*X+Y*Y+Z*Z<udg_constCamFarZ*udg_constCamFarZ then
                                            set X = udg_objX[ObjId]-udg_objX[i]
                                            set Y = udg_objY[ObjId]-udg_objY[i]
                                            set Z = udg_objZ[ObjId]+udg_classCollisionOffset[Class]-udg_objZ[i]-udg_classCollisionOffset[udg_objClass[i]]
                                            call SetTextTagText(udg_objRadarTag[ObjId], ". "+I2S(R2I(SquareRoot(X*X+Y*Y+Z*Z)/udg_constUnitsPerMeter/5)*5)+"m",0.015)
                                            call SetTextTagPos(udg_objRadarTag[ObjId], udg_objX[ObjId],udg_objY[ObjId],udg_objZ[ObjId]+udg_classCollisionOffset[Class])
                                            call SetTextTagVisibility(udg_objRadarTag[ObjId], true)
                                        else
                                            call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
                                        endif
                                    else
                                        call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
                                    endif
                                else
                                    call SetTextTagVisibility(udg_objRadarTag[ObjId], false)
                                endif
                            endif
                        endif
                        set MaxObjId = ObjId
                    endif
                endif
            endif
        endif
        set ObjId = ObjId + 1
        exitwhen ObjId > udg_objMaxId
    endloop
    set udg_objMaxId = MaxObjId

    // Camera
    set i = GetRandomInt(0,7)
    if i<4 then
        if udg_playerCamShake1>=0 then
            if 0.9*udg_playerCamShake1<1 then
                set udg_playerCamShake1=0
            else
                set udg_playerCamShake1=(-0.9*udg_playerCamShake3)+1
            endif
        elseif 0.9*udg_playerCamShake1>-1 then
            set udg_playerCamShake1=0
        else
            set udg_playerCamShake1=(-0.9*udg_playerCamShake3)-1
        endif
    endif
    if (i/2)*2==i then
        if udg_playerCamShake2>=0 then
            if 0.9*udg_playerCamShake2<1 then
                set udg_playerCamShake2=0
            else
                set udg_playerCamShake2=(-0.9*udg_playerCamShake2)+1
            endif
        elseif 0.9*udg_playerCamShake2>-1 then
            set udg_playerCamShake2=0
        else
            set udg_playerCamShake2=(-0.9*udg_playerCamShake2)-1
        endif
    endif
    if (i<6) and (i!=3) and (i!=2) then
        if udg_playerCamShake3>=0 then
            if 0.9*udg_playerCamShake3<1 then
                set udg_playerCamShake3=0
            else
                set udg_playerCamShake3=(-0.9*udg_playerCamShake3)+1
            endif
        elseif 0.9*udg_playerCamShake3>-1 then
            set udg_playerCamShake3=0
        else
            set udg_playerCamShake3=(-0.9*udg_playerCamShake3)-1
        endif
    endif

    set ObjId = udg_playerControlledObj[udg_constLocalPlayerId]
    if ObjId!=-1 then
        set Class = udg_objClass[ObjId]
        call SetCameraField(CAMERA_FIELD_FARZ, udg_constCamFarZ, 0)
        if udg_playerCamId == 2 then
            set SpeedX = udg_playerCamXStatic-udg_objX[ObjId]
            set SpeedY = udg_playerCamYStatic-udg_objY[ObjId]
            set SpeedZ = udg_playerCamZStatic-udg_objZ[ObjId]-udg_classCollisionOffset[Class]
            set SpeedXY = SquareRoot(SpeedX*SpeedX+SpeedY*SpeedY)
            call SetCameraTargetController(udg_objUnit[ObjId], SpeedX, SpeedY, false)
            call SetCameraField(CAMERA_FIELD_ZOFFSET, udg_playerCamZStatic, 0)
            call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, bj_RADTODEG * Atan2(-SpeedZ, SpeedXY), 0)


            call SetCameraField(CAMERA_FIELD_ROTATION, bj_RADTODEG * Atan2(-SpeedY, -SpeedX), 0)
            call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 0, 0)
        else
            if udg_playerCamId == 3 then
                if Class==udg_uMLRS then
                    set X = 27
                    set Z = 70
                    set r2 = udg_objAngleZ[ObjId]+10
                else
                    if Class==udg_uRaptor then
                        set X = -135
                        set Z = 63
                    elseif udg_classRotationZ[Class]!=0 then
                        set X = -135
                        set Z = 45
                    elseif Class==udg_uJeep then
                        set X = -4.5
                        set Z = 55
                    elseif Class==udg_uTank then
                        set X = -9
                        set Z = 72
                    elseif Class==udg_uTitan then
                        set X = -63
                        set Z = 180
                    elseif Class==udg_uHammerhead then
                        set X = -81
                        set Z = 100
                    elseif Class==udg_uSoldier then
                        set X = -27
                        set Z = 50
                    else
                        set X = -135
                        set Z = 63
                    endif
                    set r2 = udg_objAngleZ[ObjId]
                endif
                call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, r2+udg_playerCamShake1/22.5, 0)
                call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, udg_playerCamShake2/1.5, 0)
                call SetCameraField(CAMERA_FIELD_ZOFFSET, udg_objZ[ObjId]+Z*Cos(r2*bj_DEGTORAD)+X*Sin(r2*bj_DEGTORAD)+udg_playerCamShake2/3, 0)
                call SetCameraField(CAMERA_FIELD_ROTATION, udg_objAngle[ObjId]+udg_playerCamShake3/15, 0)
                set r = Z*Sin(-r2*bj_DEGTORAD)+X*Cos(r2*bj_DEGTORAD)
                call SetCameraTargetController(udg_objUnit[ObjId], r*Cos(udg_objAngle[ObjId]*bj_DEGTORAD), r*Sin(udg_objAngle[ObjId]*bj_DEGTORAD), false)
            elseif udg_playerCamId == 1 then
                call SetCameraField(CAMERA_FIELD_ZOFFSET, udg_objZ[ObjId]+udg_classCollisionOffset[Class]+60+udg_playerCamShake2/3, 0)
                call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 340.0+udg_playerCamShake1/22.5, 1.6)
                call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 2800.0+udg_playerCamShake2/1.5, 1.6)
                call SetCameraField(CAMERA_FIELD_ROTATION, udg_objAngle[ObjId]+udg_playerCamShake3/15, 1.6)
                call SetCameraTargetController(udg_objUnit[ObjId], 0, 0, false)
            elseif udg_playerCamId == 4 then
                call SetCameraField(CAMERA_FIELD_ZOFFSET, udg_objZ[ObjId]+udg_classCollisionOffset[Class]+60+udg_playerCamShake2/3, 0)
                call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, udg_playerCamShake1/22.5, 0)
                if Class==udg_uOrca then
                    call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 630.0+udg_playerCamShake2/1.5, 0)
                else
                    call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 450.0+udg_playerCamShake2/1.5, 0)
                endif
                call SetCameraField(CAMERA_FIELD_ROTATION, udg_objAngle[ObjId]+udg_playerCamShake3/15, 0)
                call SetCameraTargetController(udg_objUnit[ObjId], 0, 0, false)
            else
                call SetCameraField(CAMERA_FIELD_ZOFFSET, udg_objZ[ObjId]+udg_classCollisionOffset[Class]+60+udg_playerCamShake2/3, 0)
                call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 345.0+udg_playerCamShake1/22.5, 0)
                if Class==udg_uOrca then
                    call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 630.0+udg_playerCamShake2/1.5, 0)
                else
                    call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 450.0+udg_playerCamShake2/1.5, 0)
                endif
                call SetCameraField(CAMERA_FIELD_ROTATION, udg_objAngle[ObjId]+udg_playerCamShake3/15, 0)
                call SetCameraTargetController(udg_objUnit[ObjId], 0, 0, false)
            endif

            set udg_playerCamXStatic = udg_objX[ObjId]
            set udg_playerCamYStatic = udg_objY[ObjId]
            set udg_playerCamZStatic = udg_objZ[ObjId]+udg_classCollisionOffset[Class]
        endif
        set udg_playerObjX = udg_objX[ObjId]
        set udg_playerObjY = udg_objY[ObjId]
        set udg_playerObjZ = udg_objZ[ObjId]+udg_classCollisionOffset[Class]+60
        set udg_playerCamObj = ObjId
    else
        call SetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK, 300, 5)
        call SetCameraField(CAMERA_FIELD_ROTATION, 90, 5)
        call SetCameraField(CAMERA_FIELD_FARZ, udg_constCamFarZ, 5)
        if udg_playerCamObj!=-1 then
            set udg_playerObjX=udg_objX[udg_playerCamObj]
            set udg_playerObjY=udg_objY[udg_playerCamObj]
            set udg_playerObjZ=udg_objZ[udg_playerCamObj]+udg_classCollisionOffset[udg_objClass[udg_playerCamObj]]+90
            call SetCameraTargetController(udg_objUnit[udg_playerCamObj], 0, 0, false)
        else
            call SetCameraPosition(udg_playerObjX, udg_playerObjY)
        endif
        call SetCameraField(CAMERA_FIELD_ZOFFSET, udg_playerObjZ, 0)
        call SetCameraField(CAMERA_FIELD_TARGET_DISTANCE, 3600, 5)
    endif

    // Update Cooldowns
    set udg_loopBombsDropping = udg_loopBombsDropping+1
    if udg_loopBombsDropping == 5 then
        set udg_loopBombsDropping = 0
    endif
    set udg_loopArtilleryFire = udg_loopArtilleryFire+1
    if udg_loopArtilleryFire == 15 then
        set udg_loopArtilleryFire = 0
    endif
    set udg_loopMGShooting = udg_loopMGShooting+1
    if udg_loopMGShooting == 3 then
        set udg_loopMGShooting = 0
    endif
    set udg_loopFlameShooting = udg_loopFlameShooting+1
    if udg_loopFlameShooting == 3 then
        set udg_loopFlameShooting = 0
    endif

    // Nuclear Explosions
    set i = 0
    set imax = 0
    loop
        exitwhen i>=udg_dmgMax
        if udg_dmgTime[i]!=-1 then
            if udg_dmgType[i]==1 then
                // Black Hole
                set r = udg_constKnockback
                set udg_constKnockback = -30*udg_constKnockback
                call UnitDamageArea(udg_dmgEffect[i], udg_dmgX[i], udg_dmgY[i], udg_dmgZ[i], 2500, 25/(udg_dmgTime[i]+5), false, true)
                if udg_dmgTime[i]<8 then
                    set udg_dmgTime[i] = udg_dmgTime[i]+0.03
                    set imax = i
                else
                    set udg_dmgTime[i]=-1
                endif

                set udg_constKnockback = r
            else
                // Nuclear Explosion
                if udg_dmgTime[i]<9 then
                    call UnitDamageArea(udg_dmgEffect[i], udg_dmgX[i], udg_dmgY[i], udg_dmgZ[i], 1600+udg_dmgTime[i]*300, 30/(udg_dmgTime[i]+1), false, true)
                endif
                if udg_dmgTime[i]<15 then
                    call UnitDamageArea(udg_dmgEffect[i], udg_dmgX[i], udg_dmgY[i], udg_dmgZ[i]+udg_dmgTime[i]*150, 1200, 40/(udg_dmgTime[i]+1), false, true)
                    set udg_dmgTime[i] = udg_dmgTime[i]+0.03
                    set imax = i
                else
                    set udg_dmgTime[i]=-1
                endif
            endif
        endif
        set i = i + 1
    endloop
    set udg_dmgMax=imax+1

    // Jumpers
    call GroupEnumUnitsInRange( udg_tempGroup, udg_jumperX[udg_loopMGShooting], udg_jumperY[udg_loopMGShooting], 100, null )
    loop
        set Obj = FirstOfGroup( udg_tempGroup )
        exitwhen Obj == null
        set TargetObjId = GetUnitUserData(Obj)
        if TargetObjId!=-1 and not udg_objIsProjectile[TargetObjId] then
            set TargetClass = udg_objClass[TargetObjId]
            if udg_objZ[TargetObjId]==udg_objLastEnvironmentHeight[ObjId]+udg_classHoverHeight[TargetClass] then
                set udg_objSpeedZ[TargetObjId]=40
                set udg_objSpeedX[TargetObjId]=udg_objSpeedX[TargetObjId]*1.3
                set udg_objSpeedY[TargetObjId]=udg_objSpeedY[TargetObjId]*1.3
            endif
        endif
        call GroupRemoveUnit( udg_tempGroup, Obj )
    endloop

    // Control Points
    set i = udg_controlLoop+1
    if i>udg_controlMax then
        set i = 0
    endif
    call GroupEnumUnitsInRange( udg_tempGroup, udg_controlX[i], udg_controlY[i], 500, null )
    loop
        set Obj = FirstOfGroup( udg_tempGroup )
        exitwhen Obj == null
        set TargetObjId = GetUnitUserData(Obj)
        if TargetObjId!=-1 and not udg_objIsProjectile[TargetObjId] then
            set TargetClass = udg_objClass[TargetObjId]
            set PlayerId = GetPlayerId(GetOwningPlayer(Obj))
            if udg_objZ[TargetObjId]<udg_classHoverHeight[TargetClass]+50 and PlayerId<10 then
                if PlayerId/2*2==0 then
                    set udg_controlState[i] = udg_controlState[i]+1
                else
                    set udg_controlState[i] = udg_controlState[i]-1
                endif
            endif
        endif
        call GroupRemoveUnit( udg_tempGroup, Obj )
    endloop
    if udg_controlState[i]>0 then
        if GetPlayerId(GetOwningPlayer(udg_controlFlag[i]))!=10 then
            call SetUnitOwner(udg_controlFlag[i],Player(10),true)
        endif
        if udg_controlState[i]>47 then
            set udg_controlState[i]=47
        endif
        call SetUnitAnimationByIndex(udg_controlFlag[i],48-udg_controlState[i])
    else
        if GetPlayerId(GetOwningPlayer(udg_controlFlag[i]))!=11 then
            call SetUnitOwner(udg_controlFlag[i],Player(11),true)
        endif
        if udg_controlState[i]<-47 then
            set udg_controlState[i]=-47
        endif
        call SetUnitAnimationByIndex(udg_controlFlag[i],48+udg_controlState[i])
    endif
    set udg_controlLoop = i

    set udg_loopThreadOpen=false
endfunction

//===========================================================================
function InitTrig_Loop takes nothing returns nothing
    set gg_trg_Loop = CreateTrigger(  )
    call TriggerRegisterTimerEvent(gg_trg_Loop, 0.03, true)
    call TriggerAddAction( gg_trg_Loop, function Trig_Loop_Actions )
endfunction
//TESH.scrollpos=24
//TESH.alwaysfold=0
function Trig_Tickets_Victory takes integer Team returns nothing
    local integer PlayerId = 9+Team
    local real X
    local real Y
    local unit Missile
    local integer MissileObjId
    local real Angle = GetRandomReal(0,360)
    if Team==1 then
        set X = -7850
        set Y = -7850
    else
        set X = 3650
        set Y = 3400
    endif
    set MissileObjId = AddObj(Player(PlayerId), udg_uNuclear, X, Y, 6000, Angle,-90)
    set Missile = udg_objUnit[MissileObjId]
    set udg_objSpeedX[MissileObjId] = 0
    set udg_objSpeedY[MissileObjId] = 0
    set udg_objSpeedZ[MissileObjId] = -40
    set udg_objAcceleration[MissileObjId] = udg_classAccelerationHigh[udg_uNuclear]
    call SetUnitPosition(Missile,X,Y)
    set Missile = null

    call ShowMessageAll("|cfffed312Team "+I2S(Team)+" has won the match!|r")
    call DestroyTrigger(GetTriggeringTrigger())
endfunction

function Trig_Tickets_Actions takes nothing returns nothing
    local integer i = 0
    local integer Team1CPs = 0
    local integer Team2CPs = 0
    loop
        exitwhen i >udg_controlMax
        if udg_controlState[i]>0 then
            set Team1CPs = Team1CPs + 1
        elseif udg_controlState[i]<0 then
            set Team2CPs = Team2CPs + 1
        endif
        set i = i + 1
    endloop
    if Team1CPs<3 then
        set udg_Team1Tickets = udg_Team1Tickets+0.15*(Team1CPs-3)
    endif
    if Team2CPs<3 then
        set udg_Team2Tickets = udg_Team2Tickets+0.15*(Team2CPs-3)
    endif
    if udg_Team1Tickets<1 then
        call Trig_Tickets_Victory(2)
    elseif udg_Team2Tickets<1 then
        call Trig_Tickets_Victory(1)
    endif
endfunction

//===========================================================================
function InitTrig_Tickets takes nothing returns nothing
    set gg_trg_Tickets = CreateTrigger(  )
    call TriggerRegisterTimerEventPeriodic( gg_trg_Tickets, 1.00 )
    call TriggerAddAction( gg_trg_Tickets, function Trig_Tickets_Actions )
endfunction
function Trig_Show_Tickets_Actions takes nothing returns nothing
    call ShowMessage(GetPlayerId(GetTriggerPlayer()),"|cfffed312Team 1 Tickets: "+I2S(R2I(udg_Team1Tickets))+" / Team 2 Tickets: "+I2S(R2I(udg_Team2Tickets))+"|r")
endfunction

//===========================================================================
function InitTrig_Show_Tickets takes nothing returns nothing
    local integer i = 0
    set gg_trg_Show_Tickets = CreateTrigger(  )
    loop
        exitwhen i > 9
        call TriggerRegisterPlayerEventEndCinematic( gg_trg_Show_Tickets, Player(i) )
        set i = i + 1
    endloop
    call TriggerAddAction( gg_trg_Show_Tickets, function Trig_Show_Tickets_Actions )
endfunction
function Trig_Toggle_Radar_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00S'
endfunction

function Trig_Toggle_Radar_Actions takes nothing returns nothing
    local integer i = 0
    if GetOwningPlayer(GetTriggerUnit())==GetLocalPlayer() then
        set udg_playerRadarOn = not udg_playerRadarOn
        if not udg_playerRadarOn then
            loop
                exitwhen i > udg_objMaxId
                call SetTextTagVisibility(udg_objRadarTag[i], false)
                set i = i + 1
            endloop
        endif
    endif
endfunction

//===========================================================================
function InitTrig_Toggle_Radar takes nothing returns nothing
    set gg_trg_Toggle_Radar = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Toggle_Radar, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Toggle_Radar, Condition( function Trig_Toggle_Radar_Conditions ) )
    call TriggerAddAction( gg_trg_Toggle_Radar, function Trig_Toggle_Radar_Actions )
endfunction
function Trig_Toggle_Cam_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A001'
endfunction

function Trig_Toggle_Cam_Actions takes nothing returns nothing
    if GetOwningPlayer(GetTriggerUnit())==GetLocalPlayer() then
        set udg_playerCamId = udg_playerCamId+1
        if udg_playerCamId>4 then
            set udg_playerCamId = 0
        endif
    endif
endfunction

//===========================================================================
function InitTrig_Toggle_Cam takes nothing returns nothing
    set gg_trg_Toggle_Cam = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Toggle_Cam, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Toggle_Cam, Condition( function Trig_Toggle_Cam_Conditions ) )
    call TriggerAddAction( gg_trg_Toggle_Cam, function Trig_Toggle_Cam_Actions )
endfunction
function Trig_Change_Speed_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00J'
endfunction

function Trig_Change_Speed_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    if udg_objAcceleration[ObjId]>0 then
        set udg_objAcceleration[ObjId] = udg_classAccelerationHigh[udg_objClass[ObjId]]
    else
        set udg_objAcceleration[ObjId] = udg_classAccelerationLow[udg_objClass[ObjId]]
    endif
endfunction

//===========================================================================
function InitTrig_Increase_Speed takes nothing returns nothing
    set gg_trg_Increase_Speed = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Increase_Speed, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Increase_Speed, Condition( function Trig_Change_Speed_Conditions ) )
    call TriggerAddAction( gg_trg_Increase_Speed, function Trig_Change_Speed_Actions )
endfunction
function Trig_Decrease_Speed_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A002'
endfunction

function Trig_Decrease_Speed_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    if udg_objAcceleration[ObjId]<=udg_classAccelerationLow[udg_objClass[ObjId]] then
        set udg_objAcceleration[ObjId] = 0
    else
        set udg_objAcceleration[ObjId] = udg_classAccelerationLow[udg_objClass[ObjId]]
    endif
endfunction

//===========================================================================
function InitTrig_Decrease_Speed takes nothing returns nothing
    set gg_trg_Decrease_Speed = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Decrease_Speed, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Decrease_Speed, Condition( function Trig_Decrease_Speed_Conditions ) )
    call TriggerAddAction( gg_trg_Decrease_Speed, function Trig_Decrease_Speed_Actions )
endfunction
function Trig_Machine_Gun_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A003'
endfunction

function Trig_Machine_Gun_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    if udg_objClass[ObjId]==udg_uHammerhead or udg_objClass[ObjId]==udg_uRaptor then
        set udg_objMGShots[ObjId] = 30
    else
        set udg_objMGShots[ObjId] = 15
    endif
endfunction

//===========================================================================
function InitTrig_Machine_Gun takes nothing returns nothing
    set gg_trg_Machine_Gun = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Machine_Gun, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Machine_Gun, Condition( function Trig_Machine_Gun_Conditions ) )
    call TriggerAddAction( gg_trg_Machine_Gun, function Trig_Machine_Gun_Actions )
endfunction
function Trig_Flame_Thrower_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00G'
endfunction

function Trig_Flame_Thrower_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    set udg_objFlameShots[ObjId] = 12
endfunction

//===========================================================================
function InitTrig_Flame_Thrower takes nothing returns nothing
    set gg_trg_Flame_Thrower = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Flame_Thrower, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Flame_Thrower, Condition( function Trig_Flame_Thrower_Conditions ) )
    call TriggerAddAction( gg_trg_Flame_Thrower, function Trig_Flame_Thrower_Actions )
endfunction
function Trig_Plasma_Rifle_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00O'
endfunction

function Trig_Plasma_Rifle_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    set udg_objPlasmaShots[ObjId] = 4
endfunction

//===========================================================================
function InitTrig_Plasma_Rifle takes nothing returns nothing
    set gg_trg_Plasma_Rifle = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Plasma_Rifle, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Plasma_Rifle, Condition( function Trig_Plasma_Rifle_Conditions ) )
    call TriggerAddAction( gg_trg_Plasma_Rifle, function Trig_Plasma_Rifle_Actions )
endfunction
function Trig_Gun_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00K'
endfunction

function Trig_Gun_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    set udg_objMGShots[ObjId] = 1
endfunction

//===========================================================================
function InitTrig_Gun takes nothing returns nothing
    set gg_trg_Gun = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Gun, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Gun, Condition( function Trig_Gun_Conditions ) )
    call TriggerAddAction( gg_trg_Gun, function Trig_Gun_Actions )
endfunction
function Trig_Bombs_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00B'
endfunction

function Trig_Bombs_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    if udg_objZ[ObjId]>udg_classHoverHeight[udg_objClass[ObjId]] then
        if (udg_objClass[ObjId]-udg_uME109)*(udg_objClass[ObjId]-udg_uJu87)==0 then
            set udg_objBombDrops[ObjId] = 2
        else
            set udg_objBombDrops[ObjId] = 6
        endif
    endif
endfunction

//===========================================================================
function InitTrig_Bombs takes nothing returns nothing
    set gg_trg_Bombs = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Bombs, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Bombs, Condition( function Trig_Bombs_Conditions ) )
    call TriggerAddAction( gg_trg_Bombs, function Trig_Bombs_Actions )
endfunction
function Trig_Aiming_Rockets_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A004'
endfunction

function Trig_Aiming_Rockets_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    call FireAimingRocket(ObjId,true)
endfunction

//===========================================================================
function InitTrig_Aiming_Rockets takes nothing returns nothing
    set gg_trg_Aiming_Rockets = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Aiming_Rockets, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Aiming_Rockets, Condition( function Trig_Aiming_Rockets_Conditions ) )
    call TriggerAddAction( gg_trg_Aiming_Rockets, function Trig_Aiming_Rockets_Actions )
endfunction
function Trig_Rocket_Hail_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00U'
endfunction

function Trig_Rocket_Hail_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    set udg_objBombDrops[ObjId] = 4
    call SetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA, RMaxBJ(0,GetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA)-2))
endfunction

//===========================================================================
function InitTrig_Rocket_Hail takes nothing returns nothing
    set gg_trg_Rocket_Hail = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rocket_Hail, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Rocket_Hail, Condition( function Trig_Rocket_Hail_Conditions ) )
    call TriggerAddAction( gg_trg_Rocket_Hail, function Trig_Rocket_Hail_Actions )
endfunction
function Trig_Rapid_Artillery_Fire_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00W'
endfunction

function Trig_Rapid_Artillery_Fire_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    set udg_objBombDrops[ObjId] = 4
endfunction

//===========================================================================
function InitTrig_Rapid_Artillery_Fire takes nothing returns nothing
    set gg_trg_Rapid_Artillery_Fire = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Rapid_Artillery_Fire, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Rapid_Artillery_Fire, Condition( function Trig_Rapid_Artillery_Fire_Conditions ) )
    call TriggerAddAction( gg_trg_Rapid_Artillery_Fire, function Trig_Rapid_Artillery_Fire_Actions )
endfunction
function Trig_Anti_Air_Rockets_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A009'
endfunction

function Trig_Anti_Air_Rockets_GetTarget takes integer RocketObjId returns unit
    local unit U
    local real X = GetUnitX(udg_objUnit[RocketObjId])
    local real Y = GetUnitY(udg_objUnit[RocketObjId])
    local real Z = GetUnitFlyHeight(udg_objUnit[RocketObjId]) + udg_classBulletOffsetZ[udg_objClass[RocketObjId]]
    local real TargetX
    local real TargetY
    local real TargetZ
    local real DistX
    local real DistY
    local real DistZ
    local real Dist
    local unit BestTarget = null
    local real BestValue = 0
    local real CurrentValue
    local real TargetAngleZ
    local real TargetAngleDiff
    local integer TargetClass
    call GroupEnumUnitsInRange( udg_tempGroup, X, Y, 9000, null )
    loop
        set U = FirstOfGroup( udg_tempGroup )
        exitwhen U == null
       
        if GetUnitAbilityLevel(U, 'A005')==1 and not UnitsAreAllied(U, udg_objUnit[RocketObjId]) then
            set TargetClass = udg_objClass[GetUnitUserData(U)]
            set TargetX = GetUnitX(U)
            set TargetY = GetUnitY(U)
            set TargetZ = GetUnitFlyHeight(U)+udg_classCollisionOffset[TargetClass]
            set DistX = TargetX - X
            set DistY = TargetY - Y
            set DistZ = TargetZ - Z
            set TargetAngleZ = bj_RADTODEG * Atan2(DistZ, SquareRoot(DistX*DistX+DistY*DistY))
            set TargetAngleDiff = DiffBetweenAngles(90, TargetAngleZ)
            set Dist = SquareRoot(DistX*DistX+DistY*DistY+DistZ*DistZ)
            set CurrentValue = (TargetAngleDiff+20)*(Dist+5000)
            if GetPlayerId(GetOwningPlayer(U))<12 then
                set CurrentValue = CurrentValue/4
            endif
            if CurrentValue < BestValue or BestValue == 0 then
                set BestTarget = U
                set BestValue = CurrentValue
            endif
        endif
        call GroupRemoveUnit(udg_tempGroup, U)
    endloop
    return BestTarget
endfunction

function Trig_Anti_Air_Rockets_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer CasterUnitType = udg_objClass[ObjId]
    local unit Rocket
    local integer RocketObjId
    local real X = GetUnitX(udg_objUnit[ObjId])
    local real Y = GetUnitY(udg_objUnit[ObjId])
    local unit Aim = Trig_Anti_Air_Rockets_GetTarget(ObjId)
    local real angle
    local integer i
    if Aim!=null then
        set angle = bj_RADTODEG * Atan2(GetUnitY(Aim) - Y, GetUnitX(Aim) - X)+GetRandomReal(-3,3)
    else
        set angle = GetRandomReal(0,360)
    endif

    set RocketObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uRocket, X, Y, udg_objZ[ObjId] + udg_classBulletOffsetZ[udg_objClass[ObjId]], angle,90+GetRandomReal(-3,0))
    set Rocket = udg_objUnit[RocketObjId]
    set udg_objUnitAim[RocketObjId] = Aim
    if Aim!=null then
        set i = GetUnitUserData(Aim)
        set udg_objFollowingRockets[i]=udg_objFollowingRockets[i]+1
        if GetPlayerId(GetOwningPlayer(Aim))<10 then
            call SetPlayerState(GetOwningPlayer(Aim),PLAYER_STATE_RESOURCE_FOOD_USED,udg_objFollowingRockets[i])
        endif
    endif
    set udg_objSpeedX[RocketObjId] = udg_objSpeedX[ObjId]
    set udg_objSpeedY[RocketObjId] = udg_objSpeedY[ObjId]
    set udg_objSpeedZ[RocketObjId] = udg_objSpeedZ[ObjId]+10
    set udg_objAcceleration[RocketObjId] = udg_classAccelerationHigh[udg_uRocket]
    call SetUnitPosition(Rocket,X,Y)
    call SetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA, RMaxBJ(0,GetUnitState(udg_objUnit[ObjId], UNIT_STATE_MANA)-1))
    set Rocket = null
    set Aim = null
endfunction

//===========================================================================
function InitTrig_Anti_Air_Rockets takes nothing returns nothing
    set gg_trg_Anti_Air_Rockets = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Anti_Air_Rockets, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Anti_Air_Rockets, Condition( function Trig_Anti_Air_Rockets_Conditions ) )
    call TriggerAddAction( gg_trg_Anti_Air_Rockets, function Trig_Anti_Air_Rockets_Actions )
endfunction
function Trig_Nuclear_Missile_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A006'
endfunction

function Trig_Nuclear_Missile_Actions takes nothing returns nothing
    call Trig_Loop_FireNuclear(udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))])
endfunction

//===========================================================================
function InitTrig_Nuclear_Missile takes nothing returns nothing
    set gg_trg_Nuclear_Missile = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Nuclear_Missile, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Nuclear_Missile, Condition( function Trig_Nuclear_Missile_Conditions ) )
    call TriggerAddAction( gg_trg_Nuclear_Missile, function Trig_Nuclear_Missile_Actions )
endfunction
function Trig_Missile_Flare_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00E' or GetSpellAbilityId() == 'A00R'
endfunction

function Trig_Missile_Flare_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    call FireMissileFlares(ObjId)
endfunction

//===========================================================================
function InitTrig_Missile_Flare takes nothing returns nothing
    set gg_trg_Missile_Flare = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Missile_Flare, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Missile_Flare, Condition( function Trig_Missile_Flare_Conditions ) )
    call TriggerAddAction( gg_trg_Missile_Flare, function Trig_Missile_Flare_Actions )
endfunction
function Trig_Increase_Height_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00H'
endfunction

function Trig_Increase_Height_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    if udg_objAcceleration[ObjId]>udg_classAccelerationLow[udg_objClass[ObjId]] then
        set udg_objAcceleration[ObjId] = udg_classAccelerationHigh[udg_objClass[ObjId]]
    else
        set udg_objAcceleration[ObjId] = (udg_classAccelerationLow[udg_objClass[ObjId]]+udg_classAccelerationHigh[udg_objClass[ObjId]])/2
    endif
endfunction

//===========================================================================
function InitTrig_Increase_Height takes nothing returns nothing
    set gg_trg_Increase_Height = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Increase_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Increase_Height, Condition( function Trig_Increase_Height_Conditions ) )
    call TriggerAddAction( gg_trg_Increase_Height, function Trig_Increase_Height_Actions )
endfunction
function Trig_Decrease_Height_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00I'
endfunction

function Trig_Decrease_Height_Actions takes nothing returns nothing
    local integer ObjId = udg_playerControlledObj[GetPlayerId(GetOwningPlayer(GetTriggerUnit()))]
    if udg_objAcceleration[ObjId]<=(udg_classAccelerationLow[udg_objClass[ObjId]]+udg_classAccelerationHigh[udg_objClass[ObjId]])/2 then
        set udg_objAcceleration[ObjId] = udg_classAccelerationLow[udg_objClass[ObjId]]
    else
        set udg_objAcceleration[ObjId] = (udg_classAccelerationLow[udg_objClass[ObjId]]+udg_classAccelerationHigh[udg_objClass[ObjId]])/2
    endif
endfunction

//===========================================================================
function InitTrig_Decrease_Height takes nothing returns nothing
    set gg_trg_Decrease_Height = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Decrease_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
    call TriggerAddCondition( gg_trg_Decrease_Height, Condition( function Trig_Decrease_Height_Conditions ) )
    call TriggerAddAction( gg_trg_Decrease_Height, function Trig_Decrease_Height_Actions )
endfunction
function Trig_Tank_Projectiles_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00D'
endfunction

function Trig_Tank_Projectiles_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer Class = udg_objClass[ObjId]
    local integer TankProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uTProjectile, GetUnitX(udg_objUnit[ObjId]), GetUnitY(udg_objUnit[ObjId]), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    local unit TankProjectile = udg_objUnit[TankProjectileObjId]
    local real OffsetX = Cos(udg_objAngle[ObjId]*bj_DEGTORAD)
    local real OffsetY = Sin(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedX[TankProjectileObjId] = udg_objSpeedX[ObjId] + 250*OffsetX
    set udg_objSpeedY[TankProjectileObjId] = udg_objSpeedY[ObjId] + 250*OffsetY
    set udg_objSpeedZ[TankProjectileObjId] = udg_objSpeedZ[ObjId] + 2
    set udg_objLifeSpan[TankProjectileObjId] = 3
    call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl", udg_objX[ObjId]+140*OffsetX, udg_objY[ObjId]+140*OffsetY, udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], 0.5, 1, 0, 0.2)
    call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl", udg_objX[ObjId]+190*OffsetX, udg_objY[ObjId]+190*OffsetY, udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], 0.3, 1, 0, 0.2)
    call SpecialEffectScaledTimedWithZ("Abilities\\Weapons\\RocketMissile\\RocketMissile.mdl", udg_objX[ObjId]+240*OffsetX, udg_objY[ObjId]+240*OffsetY, udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], 0.1, 1, 0, 0.2)

    if GetLocalPlayer()==Player(PlayerId) then
        set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*5,-150),150)
        set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*5,-150),150)
        set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*5,-150),150)
    endif

    set TankProjectile = null
endfunction

//===========================================================================
function InitTrig_Tank_Projectiles takes nothing returns nothing
    set gg_trg_Tank_Projectiles = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Tank_Projectiles, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Tank_Projectiles, Condition( function Trig_Tank_Projectiles_Conditions ) )
    call TriggerAddAction( gg_trg_Tank_Projectiles, function Trig_Tank_Projectiles_Actions )
endfunction
function Trig_Grenade_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00P'
endfunction

function Trig_Grenade_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer Class = udg_objClass[ObjId]
    local integer TankProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uGrenade, GetUnitX(udg_objUnit[ObjId]), GetUnitY(udg_objUnit[ObjId]), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    local unit TankProjectile = udg_objUnit[TankProjectileObjId]
    set udg_objSpeedX[TankProjectileObjId] = udg_objSpeedX[ObjId] + 8*Cos(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedY[TankProjectileObjId] = udg_objSpeedY[ObjId] + 8*Sin(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedZ[TankProjectileObjId] = udg_objSpeedZ[ObjId] + 8
    set udg_objLifeSpan[TankProjectileObjId] = 2
    set TankProjectile = null
endfunction

//===========================================================================
function InitTrig_Grenade takes nothing returns nothing
    set gg_trg_Grenade = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Grenade, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Grenade, Condition( function Trig_Grenade_Conditions ) )
    call TriggerAddAction( gg_trg_Grenade, function Trig_Grenade_Actions )
endfunction
function Trig_Artillery_Shot_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00Q'
endfunction

function Trig_Artillery_Shot_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer Class = udg_objClass[ObjId]
    local integer TankProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uArtilleryShot, GetUnitX(udg_objUnit[ObjId]), GetUnitY(udg_objUnit[ObjId]), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    set udg_objSpeedX[TankProjectileObjId] = udg_objSpeedX[ObjId] + 46*Cos(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedY[TankProjectileObjId] = udg_objSpeedY[ObjId] + 46*Sin(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedZ[TankProjectileObjId] = udg_objSpeedZ[ObjId] + 26
    set udg_objLifeSpan[TankProjectileObjId] = 2

    if GetLocalPlayer()==Player(PlayerId) then
        set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*5,-150),150)
        set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*5,-150),150)
        set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*5,-150),150)
    endif
endfunction

//===========================================================================
function InitTrig_Artillery_Shot takes nothing returns nothing
    set gg_trg_Artillery_Shot = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Artillery_Shot, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Artillery_Shot, Condition( function Trig_Artillery_Shot_Conditions ) )
    call TriggerAddAction( gg_trg_Artillery_Shot, function Trig_Artillery_Shot_Actions )
endfunction
function Trig_Nuclear_Grenade_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00X'
endfunction

function Trig_Nuclear_Grenade_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer Class = udg_objClass[ObjId]
    local integer TankProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uNuclearBomb, GetUnitX(udg_objUnit[ObjId]), GetUnitY(udg_objUnit[ObjId]), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    set udg_objSpeedX[TankProjectileObjId] = udg_objSpeedX[ObjId] + 60*Cos(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedY[TankProjectileObjId] = udg_objSpeedY[ObjId] + 60*Sin(udg_objAngle[ObjId]*bj_DEGTORAD)
    set udg_objSpeedZ[TankProjectileObjId] = udg_objSpeedZ[ObjId] + 34

    if GetLocalPlayer()==Player(PlayerId) then
        set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*8,-150),150)
        set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*8,-150),150)
        set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*8,-150),150)
    endif
endfunction

//===========================================================================
function InitTrig_Nuclear_Grenade takes nothing returns nothing
    set gg_trg_Nuclear_Grenade = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Nuclear_Grenade, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Nuclear_Grenade, Condition( function Trig_Nuclear_Grenade_Conditions ) )
    call TriggerAddAction( gg_trg_Nuclear_Grenade, function Trig_Nuclear_Grenade_Actions )
endfunction
function Trig_Plasma_Bomb_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00V'
endfunction

function Trig_Plasma_Bomb_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer Class = udg_objClass[ObjId]
    local integer TankProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uPlasmaBomb, GetUnitX(udg_objUnit[ObjId]), GetUnitY(udg_objUnit[ObjId]), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    set udg_objSpeedX[TankProjectileObjId] = udg_objSpeedX[ObjId] + 50*Cos(udg_objAngle[ObjId]*bj_DEGTORAD)*Cos(udg_objAngleZ[ObjId]*bj_DEGTORAD)
    set udg_objSpeedY[TankProjectileObjId] = udg_objSpeedY[ObjId] + 50*Sin(udg_objAngle[ObjId]*bj_DEGTORAD)*Cos(udg_objAngleZ[ObjId]*bj_DEGTORAD)
    set udg_objSpeedZ[TankProjectileObjId] = udg_objSpeedZ[ObjId] + 50*Sin(udg_objAngleZ[ObjId]*bj_DEGTORAD)
    set udg_objLifeSpan[TankProjectileObjId] = 0.5

    if GetLocalPlayer()==Player(PlayerId) then
        set udg_playerCamShake1=RMinBJ(RMaxBJ(udg_playerCamShake1+RSignBJ(udg_playerCamShake1)*5,-150),150)
        set udg_playerCamShake2=RMinBJ(RMaxBJ(udg_playerCamShake2+RSignBJ(udg_playerCamShake2)*5,-150),150)
        set udg_playerCamShake3=RMinBJ(RMaxBJ(udg_playerCamShake3+RSignBJ(udg_playerCamShake3)*5,-150),150)
    endif
endfunction

//===========================================================================
function InitTrig_Plasma_Bomb takes nothing returns nothing
    set gg_trg_Plasma_Bomb = CreateTrigger(  )
    call TriggerRegisterAnyUnitEventBJ( gg_trg_Plasma_Bomb, EVENT_PLAYER_UNIT_SPELL_CAST )
    call TriggerAddCondition( gg_trg_Plasma_Bomb, Condition( function Trig_Plasma_Bomb_Conditions ) )
    call TriggerAddAction( gg_trg_Plasma_Bomb, function Trig_Plasma_Bomb_Actions )
endfunction
function Trig_Gravity_Gun_Conditions takes nothing returns boolean
    return GetSpellAbilityId() == 'A00T'
endfunction

function Trig_Gravity_Gun_Actions takes nothing returns nothing
    local integer PlayerId = GetPlayerId(GetOwningPlayer(GetTriggerUnit()))
    local integer ObjId = udg_playerControlledObj[PlayerId]
    local integer Class = udg_objClass[ObjId]
    local integer TankProjectileObjId = AddObj(GetOwningPlayer(udg_objUnit[ObjId]), udg_uGravityGun, GetUnitX(udg_objUnit[ObjId]), GetUnitY(udg_objUnit[ObjId]), udg_objZ[ObjId] + udg_classBulletOffsetZ[Class], udg_objAngle[ObjId],udg_objAngleZ[ObjId])
    set udg_objSpeedX[TankProjectileObjId] = udg_objSpeedX[ObjId]