ScriptName masterAmbushScript extends Actor
{Script that lives on the actor and takes care of all instances of how an actor can come out of idle state while in ambush mode}

import game
import debug

String Property ACTOR_VARIABLE = "Variable01" AutoReadOnly
{By default, this property is set to Variable01.}

Float Property ACTOR_VARIABLE_ON_TRIGGER = 1.0 AutoReadOnly
{By default this property is set to 1.} 

Float Property ACTOR_VARIABLE_ON_RESET = 0.0 AutoReadOnly

Float Property AGGRESSION_ON_TRIGGER = 2.0 AutoReadOnly
{
By default this property is set to 2 (very aggressive).
0 - Unaggressive - will not initiate combat
1 - Aggressive - will attack enemies on sight
2 - Very Aggressive - Will attack enemies and neutrals on sight
3 - Frenzied - Will attack anyone else
}

Float Property AGGRESSION_ON_RESET = 0.0 AutoReadOnly

keyword property linkKeyword auto
{if this has a linkedRef with this keyword, we will activate it once when hit, activated, or on combat begin}

bool property ambushOnTrigger = false auto
{By default, this is set to false. Set to true if you want encounter to come out of ambush when player enters trigger}

Bool Property helpAlliesOnTrigger = false auto
{By default, this is set to false. Set to true if the NPC helps nobody while ambushing, and helps allies when the ambush is triggered}

Bool Property dontResetAggression = false auto
{By default, this is set to false. Set to true if the NPC doesn't need its aggression raised when the ambush is triggered}

;**********************************************

Event onReset()
	;messagebox ("in reset")
	self.SetActorValue(ACTOR_VARIABLE, ACTOR_VARIABLE_ON_RESET)
	If dontResetAggression == False
		self.SetActorValue("Aggression", AGGRESSION_ON_RESET)
	EndIf
	If helpAlliesOnTrigger
		self.SetActorValue("Assistance", 0) ; Help nobody
	EndIf
	self.evaluatePackage()
endEvent

;**********************************************

auto State waiting
	;The actor can exit the furniture in multiple ways.  We need to listen for all of these
	;events and if any are called, then go to All Done state, since we don't need to listen
	;for any other events because any of the events will get the actor out of the furniture.
	
	;Handle Activation
	Event onActivate(ObjectReference triggerRef)
		;trace("in onactivate")
		if ambushOnTrigger || (triggerRef == game.getPlayer())
			;player has activated draugr, so leave state
			gotoState("allDone")
		else
			;trigger activated them, so set their aggression to 2, but do not leave state
			_RaiseAggression()
		endif
	endEvent
	
	;Handle onHit
	Event onHit(objectReference akAggressor, Form akWeapon, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
		;trace("in onhit")
		gotoState("allDone")
	endEvent
	
	;Handle other cases that cause them to come out of furniture
	
	;Using onGetUp as a safety net
	Event onGetUp(ObjectReference myFurniture)
		Cell parentCell = GetParentCell()
		;trace("in getup")
		if (parentCell && parentCell.IsAttached() && (is3DLoaded()))
			gotoState("allDone")
		endif
	endEvent
	
	Event OnCombatStateChanged(Actor actorRef, int aeCombatState)
		;trace("in combatstatechanged")
		if (aeCombatState != 0) ; 0 = not in combat, so non-0 means we entered combat
			gotoState("allDone")
		endIf
	endEvent
	
	;if any of the events above are caught, we leave this state, but first we need to take care
	;of setting up everything we need when we get out of our furniture.
	Event onEndState()
		;trace("in end state")
		;handle things like sarcophagus lids that are the linkedRef of the furniture
		If _TryActivateLinkedRef(getLinkedRef())
			_TryActivateLinkedRef(getNthLinkedRef(2))
		EndIf
		
		;set actor variables
		self.SetActorValue(ACTOR_VARIABLE, ACTOR_VARIABLE_ON_TRIGGER)
		_RaiseAggression()

		;check to see if actor has a linkedRef with this keyword, if so, then activate it
		If linkKeyword
			_TryActivateLinkedRef(GetLinkedRef(linkKeyword))
		EndIf
	endEvent
endState

Bool Function _TryActivateLinkedRef(ObjectReference mylinkedRef)
	If mylinkedRef
		mylinkedRef.Activate(self)
		Return True
	EndIf

	Return False
EndFunction

Function _RaiseAggression()
	If dontResetAggression == False
		self.SetActorValue("Aggression", AGGRESSION_ON_TRIGGER)
	EndIf
	If helpAlliesOnTrigger
		self.SetActorValue("Assistance", 1) ; Help allies
	EndIf
	self.EvaluatePackage()
EndFunction

;**********************************************

State allDone
	;do nothing
endState
	
;**********************************************