/* -------------------------------------------------------------- Condition_Area -------------------------------------------------------------- A Condition which is marked complete when a player either (A) leaves a volume or (B) enters a volume Can also be configured to check ZoneInfo regions. Author : Alex Quick -------------------------------------------------------------- */ class ObjCondition_Area extends KF_ObjectiveCondition editinlinenew; var () private edfindable Volume AreaVolume; var const Name AreaVolumeName,InitialAreaVolumeName; var () string AreaZoneName; var private Volume InitialVolume; var () float Duration; var () bool bRequiresWholeTeam; var private ZoneInfo AssociatedZone; // Zones are NoDelete so having a reference in here should be O.K enum EAreaConditionType { Method_LeaveArea, Method_EnterArea, }; var ()class ProximityTriggerType; var () name ProximityTag; var ()EAreaConditionType CompletionMethod; var () bool bKeepProgress; var float LastInAreaTime; var float TimeInArea; var float TimeOutOfArea; var float LastOutOfAreaTime; var bool bTimingOut; var int NumInVolume; var private array PawnInstigatorNames; function PostBeginPlay(KF_StoryObjective MyOwner) { local ZoneInfo Zone; Super.PostBeginPlay(MyOwner); if(AreaVolume != none) { SetTargetActor(InitialAreaVolumeName,AreaVolume); SetTargetActor(AreaVolumeName,AreaVolume); AreaVolume = none; } else if(AreaZoneName != "") { foreach AllObjects(class 'ZoneInfo', Zone) { if(Zone.LocationName == AreaZoneName) { AssociatedZone = Zone; break; } } } } function array GetInstigatorList() { local array PawnInstigators; local int i; for(i = 0 ; i < PawnInstigatorNames.length ; i ++) { PawnInstigators[PawnInstigators.length] = Pawn(GetTargetActor(PawnInstigatorNames[i])) ; } return PawnInstigators; } function AdjustToDifficulty(float Difficulty) { Duration /= FMax(Difficulty-2,1); } function Reset() { Super.Reset(); bTimingOut = false; TimeInArea = 0.f; TimeOutOfArea = 0.f; } function ConditionActivated(pawn ActivatingPlayer) { Super.ConditionActivated(ActivatingPlayer); Duration = FMax(Duration,0.1f); if(GetTargetActor(InitialAreaVolumeName) != none) { SetTargetActor(AreaVolumeName,GetTargetActor(InitialAreaVolumeName)); } } function ConditionTick(Float DeltaTime) { local controller AController; local Actor ProximityActor; local Volume MyAreaVolume; local int i; NumInVolume = 0; for(i = 0 ; i < PawnInstigatorNames.length ; i ++) { ReleaseTargetActor(PawnInstigatorNames[i]); } PawnInstigatorNames.length = 0; MyAreaVolume = Volume(GetTargetActor(AreaVolumeName)); if(MyAreaVolume != none || AreaZoneName != "" ) { if(MyAreaVolume != none) { if(ClassIsChildOf(ProximityTriggerType,class 'Controller')) { for ( AController=GetObjOwner().Level.ControllerList; AController!=None; AController=AController.NextController ) { if(AController.Pawn != none && AController.Pawn.Health > 0 && MyAreaVolume.Encompasses(AController.Pawn)) { if(ClassIsChildOf(AController.class,ProximityTriggerType)) { PawnInstigatorNames[PawnInstigatorNames.length] = AController.Pawn.name; SetTargetActor(AController.Pawn.name,AController.Pawn); NumInVolume ++ ; } } } } else { foreach MyAreaVolume.TouchingActors(class 'Actor', ProximityActor) { if(ProximityActor.IsA(ProximityTriggerType.name) && !ProximityActor.bPendingDelete && (ProximityTag == '' || ProximityActor.Tag == ProximityTag)) { if(ProximityActor.Instigator != none) { PawnInstigatorNames[PawnInstigatorNames.length] = ProximityActor.Instigator.name; SetTargetActor(ProximityActor.Instigator.name,ProximityActor.Instigator); } NumInVolume ++ ; } } } } else if(AreaZoneName != "") { for ( AController=GetObjOwner().Level.ControllerList; AController!=None; AController=AController.NextController ) { if(AController.Pawn != none && AController.Pawn.Health > 0 && (ClassIsChildOf(AController.Pawn.Class,ProximityTriggerType) || ClassIsChildOf(AController.Class,ProximityTriggerType)) && (ProximityTag == '' || AController.Pawn.Tag == ProximityTag)) { if(AController.Pawn.Region.Zone.LocationName == AreaZoneName) { PawnInstigatorNames[PawnInstigatorNames.length] = AController.Pawn.name; SetTargetActor(AController.Pawn.name,AController.Pawn); NumInVolume ++ ; } } } } if(NumInVolume == 0 || (bRequiresWholeTeam && NumInVolume < GetObjOwner().StoryGI.GetTotalActivePlayers())) { bTimingOut = true; if(bKeepProgress) { TimeInArea = FMax( TimeInArea - DeltaTime, 0 ); } else { TimeInArea = 0.f; } TimeOutOfArea = FMin( TimeOutOfArea + DeltaTime, Duration ); } else { bTimingOut = false; TimeInArea = FMin( TimeInArea + DeltaTime, Duration ); if(bKeepProgress) { TimeOutOfArea = FMax( TimeOutOfArea - DeltaTime, 0 ); } else { TimeOutOfArea = 0.f; } } } Super.ConditionTick(DeltaTime); } /* returns the percentage of completion for this condition */ function float GetCompletionPct() { if(CompletionMethod == Method_LeaveArea) { return FClamp(TimeOutOfArea / Duration,0.f,1.f); } else { return FClamp(TimeInArea / Duration,0.f,1.f); } } function string GetDataString() { local string DataString; local int NumActivePlayers; if(bRequiresWholeTeam ) { NumActivePlayers = GetObjOwner().StoryGI.GetTotalActivePlayers() ; if(NumActivePlayers > 1) { DataString@="["$NumInVolume$"/"$NumActivePlayers$"]" ; } } return DataString ; } function string GetHUDHint() { local string HintString; return Super.GetHUDHint(); if( (CompletionMethod == Method_LeaveArea && bTimingOut) || (CompletionMethod == Method_EnterArea && !bTimingOut) ) { HintString = Super.GetHUDHint(); } return HintString ; } function vector GetLocation(optional out Actor LocActor) { local Actor WorldLocActor; local Vector WorldLocation; local Volume MyAreaVolume; if(ConditionIsActive()) { MyAreaVolume = Volume(GetTargetActor(AreaVolumeName)); WorldLocation = Super.GetLocation(WorldLocActor); if(WorldLocActor != none) { LocActor = WorldLocActor; return WorldLocation; } if(MyAreaVolume != none) { LocActor = MyAreaVolume; return LocActor.Location; } else if(AreaZoneName != "" && AssociatedZone != none) { LocActor = AssociatedZone; return LocActor.Location; } } } DefaultProperties { AreaVolumeName = "AreaVolume" InitialAreaVolumeName = "InitialAreaVolume" CompletionMethod = Method_EnterArea ProximityTriggerType = class 'PlayerController' HUD_World=(bIgnoreWorldLocHidden=true) }