328 lines
8.8 KiB
Ucode
328 lines
8.8 KiB
Ucode
/*
|
|
--------------------------------------------------------------
|
|
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<Actor> 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<name> 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<Pawn> GetInstigatorList()
|
|
{
|
|
local array<Pawn> 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)
|
|
}
|