; General SubDef Doctrine for ReinforceAlert ver.1.41
; rev. 3.0

var CommsIntervalTimer
var CommsSurfaceTimer
var SubCommsInterval
var SubCommsDepth
var RunningDepth
var RunningSpeed
var StayAtCommsDepth 
var TBFC
var Reacquire
var ReacquireBrg
var ReacquireSpd
var CMActL
var CMPasL
var WeapCount
var AutoCMLoad
var Reloading
var TorpThreat
var TypSub
var NCS
VAR FCAV
VAR TEMP
VAR UKL
VAR BEZ
var Snorkeling
var TBTS
var AllowCavitation
var OldAlt
var tperdec
var tperjam
VAR GO_PING
VAR STOP_PING
var SnorkelSpd
var Diesel
var CF1
var CF2
var WJ ; Whale Jumping
var ballast
var MastRise
var OperateSpd
var OldBrg
var fulltrottle
var PassiveWashout
var TowedCutSpeed
var TowedArrayON
var TATimer
var TowedArrayIdx
var TAC
var UFT
var RT
var Snap
var HoldContact
var RC
var SAT
var SnorSpdTimer
var Charge

func TowRetract {
IF TowedArrayON THEN {
If TAC AND ( TowedCutSpeed != 50 ) Then {
	IF NOT TorpThreat THEN {
;		CounterMeasureIdx TowedArrayIdx
		UFT = RND 10
	IF ( UFT > 5 ) THEN {
		RT = 1
	} endif
} endif

} ELSEIF TAC AND ( TowedCutSpeed == 50 ) Then {
;	CounterMeasureIdx TowedArrayIdx
} ELSE {
;	DebugOut "SKIP"
} Endif
} ENDIF
	TATimer = 1000000
}

func InvalidComms {
If ( TgtSource $= "UNKNOWN" ) Then {
	SetPriority 250
	SetPersist 365
	SetAlt OwnAlt
	SetCrs OwnCrs
	OperateSpd = OwnSpd
	SetSpd OwnSpd
} ELSE {
	SetPriority 250
	SetPersist 960
	SetAlt OwnAlt
	SetCrs OwnCrs
	OperateSpd = OwnSpd
	SetSpd OwnSpd
} ENDIF
}

func Communication {
	RC = 1
	StayAtCommsDepth = 1
IF CommsSurfaceTimer > -1 THEN {
	IF Time > CommsSurfaceTimer THEN {
		StayAtCommsDepth = 0
	} endif
} endif
If OwnAlt < SubCommsDepth Then {
	SetPriority 251
	SetAlt ( SubCommsDepth + 1 )
	OperateSpd = 5
	SetSpd 5
;	DebugOut "Go To Comms Depth"
} Else {
;	DebugOut "Stay On Comms Depth"
	SetAlt OwnAlt
	OperateSpd = 5
	SetSpd 5
} Endif
}

func MissileAttack {
If ( TgtSource $= "UNKNOWN" ) Then {
	If ( ( TgtType $= "Ship" ) OR ( TgtClass $= "Stat" ) ) And ( TypSub == 4 ) Then {
		SetPersist 240
		SetSpd 10
		SetPersist 240
		SetAlt -1 
 	} Endif
} Endif

If NOT ( TgtSource $= "UNKNOWN" ) Then {
	If ( ( TgtType $= "Ship" ) OR ( TgtClass $= "Stat" ) ) And ( TypSub == 4 ) Then {
		If OwnSpd < 5 Then { SetPersist 180 SetSpd 10 } endif
		SetPersist 180
		SetAlt -1 
 	} Endif
} Endif
}

func Avoid {
	IF ( ( TgtClass $= "AIR" ) OR ( TgtClass $= "HELO" ) ) AND ( ( TGTID $= "UPD" ) OR ( TGTID $= "HOSTILE" ) ) THEN {
		RunningDepth = OwnAlt
		OldBrg = OwnCrs
		SetTactic "SubAvoidAir"
	} ELSEIF ( TgtClass $= "WEAP" ) AND ( TgtType $= "Torp" ) THEN {
		TowRetract
		WeapCount += 1
		TorpThreat = 1
		SetTactic "SubAvoidWeap"
	} ELSEIF ( TgtClass $= "WEAP" ) AND ( TgtType $= "Sonobuoy" ) THEN {
		SETPRIORITY 252 SETPERSIST 180	SteerAbeam
	} ELSEIF ( TgtClass $= "Surf" ) AND ( ( TGTID $= "UPD" ) OR ( TGTID $= "HOSTILE" ) ) THEN {
		SetTactic "SubAvoidSurf"
	} ELSEIF ( TgtClass $= "Sub" ) AND ( ( TGTID $= "UPD" ) OR ( TGTID $= "HOSTILE" ) ) THEN {
		SetTactic "SubAvoidSub"
	} ENDIF
}
IF OWNALT != OLDALT THEN {
	IF ( CF2 != 0 ) Then {
		NCS = ( ( CF2 * sqrt ( ABS OwnAlt + 33 ) ) - 0.5 )
		OLDALT = OWNALT
	} ENDIF
} ENDIF

IF INIT THEN {
	GO_PING = 0
	STOP_PING = -1
	FCAV = 0
	UKL = 0
	AllowCavitation = 0
	CF1 = DBBuoyFlags
	CF2 = ( CF1 * 0.1 )
	ballast = 1
	OperateSpd = OwnSpd
;	TowedArrayIdx = DBIdxFromRecNum 1365
	TATimer = 1000000
	IF ( DBCMFlags & 8 ) == 8 THEN { TAC = 1 TowedArrayON = 1 } ENDIF
; -------------------------------------------------------
IF ( DBUser1Flags & 1 ) == 1 THEN { TypSub = 1 Diesel = 1 } ENDIF
IF ( DBUser1Flags & 2 ) == 2 THEN { TypSub = 2 } ENDIF
IF ( DBUser1Flags & 4 ) == 4 THEN { TypSub = 3 } ENDIF
IF ( DBUser1Flags & 8 ) == 8 THEN { TypSub = 4 } ENDIF
IF ( DBUser1Flags & 16 ) == 16 THEN { TypSub = 5 } ENDIF
IF ( DBUser1Flags & 32 ) == 32 THEN { WJ = 1 } ENDIF
IF ( DBUser1Flags & 64 ) == 64 THEN { TypSub = 7 } ENDIF
IF ( DBUser1Flags & 128 ) == 128 THEN { TypSub = 8 } ENDIF
; --------------------------------------------------
; Comms depth data
	SubCommsDepth = ( PeriDepth - 3 )
IF ( DBUser2Flags & 1 ) == 1 THEN {
	SubCommsDepth = ( -6.6 + PeriDepth )
} ELSEIF ( DBUser2Flags & 2 ) == 2 THEN {
	SubCommsDepth = ( -39.36 + PeriDepth )
} ELSEIF ( DBUser2Flags & 4 ) == 4 THEN {
	SubCommsDepth = ( -72.16 + PeriDepth )
} ELSEIF ( DBUser2Flags & 8 ) == 8 THEN {
	SubCommsDepth = ( -104.96 + PeriDepth )
} ELSEIF ( DBUser2Flags & 16 ) == 16 THEN {
	SubCommsDepth = ( -137.76 + PeriDepth )
} ELSEIF ( DBUser2Flags & 32 ) == 32 THEN {
	SubCommsDepth = ( -170.56 + PeriDepth )
} ELSEIF ( DBUser2Flags & 64 ) == 64 THEN {
	SubCommsDepth = ( -203.36 + PeriDepth )
} ELSEIF ( DBUser2Flags & 128 ) == 128 THEN {
	SubCommsDepth = ( -301.76 + PeriDepth )
} ENDIF 
; ----------------------------------------------------

	IF SubCommsInterval <= 0 THEN {
		SubCommsInterval = 7200
		CommsIntervalTimer = ( Time + SubCommsInterval )
	IF ( 50 >= RND 100 ) Then {
		SnorkelSpd = 0
	} ELSE {
		SnorkelSpd = 6
	} ENDIF
		CommsSurfaceTimer = -1
	} ENDIF
	Charge = 1
	SnorSpdTimer = 1000000
	Reacquire = 0
	StayAtCommsDepth = 0
	WeapCount = 0
	AutoCMLoad = 0
	Reloading = 0
	TorpThreat = 0
	CMPasL = 1
	CMActL = 1
} ELSEIF LostTrack THEN {
;	DEBUGOUT "Doctrine SubDef: Lost Track!"
	IF ( TorpThreat ) THEN {
IF ( ( TgtClass $= "Missile" ) OR ( TgtClass $= "Weap" ) ) THEN {
	WeapCount -= 1
} ENDIF
		IF ( WeapCount == 0 ) THEN {
			AutoCMLoad = ( Time + 90 + ( RND 90 ) )
			Reloading = True
			TorpThreat = False
;			DebugOut OwnName
;			DebugOut "Lost Track of all Weapons"
;			DebugOut "Reloading Countermeasures"
		IF ( TowedArrayON != 1 ) THEN {
			TowedArrayON = 0
			TATimer = ( Time + 180 )
;			DebugOut "Initiated DEPLOY Towed Array"
		} ENDIF
		} ENDIF
	} ENDIF
; ------------------------------------------------
	IF ( Order $= "Track" ) AND ( AssignedTarget != 0 ) Then {
		IF SAT > 899 Then {
;		DebugOut "this was an assigned target, let's try to reacquire it"
		ReacquireBrg = TgtBrg
		ReacquireSpd = ( TgtSpd + 5 )
		Reacquire = 1
	} ENDIF
} ENDIF
} ELSE {
	IF ( Time > AutoCMLoad ) AND ( Reloading ) THEN {
		CMActL = 1
		CMPasL = 1
		Reloading = 0
;		DebugOut OwnName
;		DebugOut "Countermeasures Reloaded"
	} ENDIF

IF NewTrack THEN {
	If ( TgtAge != 0 ) Then {
		If ( OwnAlt < SubCommsDepth ) Then {
			InvalidComms
		} Endif
If ( OwnAlt >= SubCommsDepth ) Then {
 	MissileAttack
} Endif

} ELSE {
	PassiveWashout = TgtSrcLevel "ESM"
	TowedCutSpeed = TgtSrcLevel "Active Intercept"
	IF Order $= "Track" THEN {
		IF AssignedTarget THEN {
;			DebugOut "We've been ordered to TRACK this target"
			Reacquire = 0
			SetTactic "SubAssignedTrack"
		} ELSE {
;			DebugOut "Sub skipping unassigned TRACK target"
		} ENDIF
	} ELSEIF Order $= "Transit" THEN {
		IF ( TgtSource $= "Active Intercept" ) AND ( TgtID $= "Hostile" ) AND ( TgtType $= "Sub" ) THEN {
;		DebugOut "We've been ordered to transit, NO prosecuting active pinged sub. Off-mission."
;			SetTactic "SubAtkSub"
		} ENDIF
		IF ( ( TgtClass $= "Missile" ) OR ( TgtType $= "Torp" ) ) THEN {
;		DebugOut "We've been ordered to transit, avoid only weapon."
			WeapCount += 1
			TorpThreat = 1
;			DebugOut "Sub_Avoid_Weap_Transit_Tactic"
			SetTactic "SubAvoidWeap"
		} endif
	} ELSE {
;		DEBUGOUT "We're ready to prosecute this target"
        		IF ( ( TgtClass $= "Surf" ) AND NOT ( TgtID $= "NEUTRAL" ) ) THEN {
;			DebugOut "Doctrine: sub engage surf"
			SetTactic "SubAtkSurf"
		} ELSEIF ( TgtClass $= "SUB" ) AND NOT ( TgtType $= "BIOLOGIC" ) THEN {
;			DebugOut "Sub_Atk_Sub"
			SetTactic "SubAtkSub"
		} ELSEIF ( ( TgtClass $= "Missile" ) OR ( TgtType $= "Torp" ) ) THEN {
			WeapCount += 1
			TorpThreat = 1
;			DebugOut "Sub_Avoid_Weap"
			SetTactic "SubAvoidWeap"
		} ELSE {
;			AVOID
		} ELSEIF ( ( TgtClass $= "AIR" ) OR ( TgtClass $= "HELO" ) ) AND ( ( TGTID $= "UPD" ) OR ( TGTID $= "HOSTILE" ) ) THEN {
			RunningDepth = OwnAlt
			OldBrg = OwnCrs
;			DebugOut "Sub_Avoid_Air"
			SetTactic "SubAvoidAir"
		} ENDIF
	} ENDIF
} ENDIF
} ELSE {
	IF Reacquire THEN {
;		DebugOut "Reacquire Section"
		SetPriority 250	SetCrs ReacquireBrg
		SetSpd ReacquireSpd
		IF ( OwnAlt > -100 ) AND ( CommsSurfaceTimer < 0 ) THEN {
			SetPriority 252
			SetAlt -150
;			DebugOut "Going to -150"
		} ENDIF
	} ELSE {
		If RC and ( TBFC > 0 ) THEN {
;			DebugOut "A communication session is emergency interrupt"
			RC = 0
			StayAtCommsDepth = 0
			CommsSurfaceTimer = -1
			CommsIntervalTimer = ( Time + SubCommsInterval )
		} ENDIF
		IF NOT TBFC THEN {
			IF StayAtCommsDepth THEN {
				Communication
			} ELSE {
;				DebugOut "Ongoing check timers comms"
				IF ( CommsIntervalTimer > -1 ) AND ( Time > CommsIntervalTimer ) THEN {
					CommsIntervalTimer = -1
					CommsSurfaceTimer = ( Time + 300 + Rnd 360 )
					RunningDepth = OwnAlt
					RunningSpeed = OwnSpd
				} ENDIF	
				IF CommsSurfaceTimer > -1 THEN {
					IF Time > CommsSurfaceTimer THEN {
;					DebugOut "A communication session is completed"
						RC = 0
						StayAtCommsDepth = 0
						CommsSurfaceTimer = -1
						CommsIntervalTimer = ( Time + SubCommsInterval )
						SetPriority 252
						SetAlt RunningDepth
						SetSpd RunningSpeed
					} ELSE {
						Communication
					} ENDIF
				} ENDIF
			} ENDIF
		} ENDIF
	} ENDIF
} ENDIF

IF ( Time > TATimer ) THEN {
	TowedArrayON = 1
	TATimer = 1000000
	SensorEnable "#TowedArray_AI*" 1
	SensorEnable "#TowedArray_AI_Deep" 1
	SensorEnable "#TowedArray_AIO" 1
	SensorEnable "#TowedArray_PU" 1
	SensorEnable "#TowedArray_SU" 1
	SensorEnable "#TowedArray_U" 1
;	DebugOut "Towed Array Has Been FULLY DEPLOYED"
} ENDIF
; --------------------------------------------------------------------
IF NOT TBTS THEN {
IF DIESEL Then {
IF NOT Snorkeling THEN {
	IF BatteryPercent < 50 THEN {
			Charge = 0
		IF BatteryPercent < 10 THEN {
			SetPriority 255
			RunningDepth = OwnAlt
			RunningSpeed = OwnSpd
			OperateSpd = 5
			SetAlt PeriDepth
			Snorkeling = 1
		} ELSEIF NOT TBTS THEN {
			RunningDepth = OwnAlt
			RunningSpeed = OwnSpd
			OperateSpd = 5
			SetAlt PeriDepth
			Snorkeling = 1
		} ENDIF
	} ENDIF
} ELSE {
	SetAlt ( PeriDepth + 4 )
IF ( OwnAlt > PeriDepth ) THEN {
	OperateSpd = SnorkelSpd
	If Not MastRise Then {
		MastRise = 1
		SetSnorkel On
	} endif
} ENDIF
IF TBTS THEN {
	IF BatteryPercent > 20 THEN {
		SetSnorkel Off
		MastRise = 0
		Snorkeling = 0
		SnorSpdTimer = ( Time + 60 )
		OperateSpd = 5
		SetSpd RunningSpeed
	} ENDIF
} ELSEIF BatteryPercent > 90 THEN {
	SnorSpdTimer = ( Time + 60 )
	SetSnorkel Off
	MastRise = 0
	Snorkeling = 0
	OperateSpd = 5
	SetAlt RunningDepth
	} ENDIF	
} ENDIF
} ENDIF
} ENDIF

If Not Charge Then {
	SetSpd OperateSpd
} endif

If ( Time >= SnorSpdTimer ) Then {
;	DebugOut "A snorkeling session is complete"
	SnorSpdTimer = 1000000
	Charge = 1
	SetSpd RunningSpeed
} endif

If ( ( Charge == 0 ) and ( TBTS > 0 ) ) THEN {
;	DebugOut "A snorkeling session is emergency interrupt"
	SnorSpdTimer = 1000000
	SetSnorkel Off
	MastRise = 0
	Snorkeling = 0
	Charge = 1
} ENDIF

; --------------------------------------------------------------------

IF ( ( BEZ == 1 ) AND ( FullTrottle == 0 ) ) Then {
	IF OperateSPD > ( NCS ) THEN {
;		DebugOut "AI Conn, AI Sonar: Cavitation."
		TEMP = ( NCS )
		SetPriority 255
		SETSPD TEMP
	} ENDIF
} ENDIF
} ENDIF

if ( tperdec != 0 ) and ( time > tperdec ) then { tperdec = 0 } endif
if ( tperjam != 0 ) and ( time > tperjam ) then { tperjam = 0 } endif

IF GO_PING THEN {
	IF STOP_PING == -1 THEN {
		STOP_PING = ( GetEntVar "HoldContact" )
		GO_PING = 0
	} ENDIF
} ENDIF

IF ( STOP_PING != -1 ) AND ( TIME > STOP_PING ) THEN {
	STOP_PING = -1
	PREENABLE
	PASSIVEENABLE
} ENDIF
if ( ownalt - 30 ) < TerrainAlt then {
	SetPriority 250 SetAlt ( ownalt + 30 ) 
} endif
If ( ballast != 1 ) Then { ballast = 0 } Endif
If ( TowedArrayON != 1 ) Then { TowedArrayON = 0 } Endif
	TBFC = TorpThreat
	TBTS = TorpThreat
