class ObjCondition_Use_SE extends ObjCondition_Use editinlinenew; /* -------------------------------------------------------------- ObjCondition_Use_SE -------------------------------------------------------------- Enhanced version of ObjCondition_Use. - Fixed a bug when GetCompletionPct() could return value > 1 - Added bCheckDependentsFirst - ConditionTick() stops using if bCheckDependentsFirst and DependentConditions incomplete - HoldUseSeconds use difficulty modifiers - if Screen_CountStyle == Count_Down, then seconds left are displayed on the HUD - If UseActor uses collision cylinder, it will be always taken in place, not only when it is blocking actors Author : PooSH Original Author: Alex Quick -------------------------------------------------------------- */ // if true, DependentConditions the progression var(KF_ObjectiveCondition) bool bCheckDependentsFirst; // call DependentConditions[].FindInstigator()? var(KF_ObjectiveCondition) bool bCheckDependentsInstigator; var(Audio) sound UsingSound; var protected sound OriginalUsingSound; var protected transient float InitialHoldUseSeconds; function Reset() { ResetSound(); Super.Reset(); SetTargetActor(CurrentUserName,none); } function ResetSound() { local Actor MyUseActor; // restore original ambient sound (mostly - none) if ( UsingSound != OriginalUsingSound ) { MyUseActor = GetTargetActor(UseActorName); if ( MyUseActor != none && MyUseActor.AmbientSound != OriginalUsingSound ) MyUseActor.AmbientSound = OriginalUsingSound; } } function PostBeginPlay(KF_StoryObjective MyOwner) { local Actor MyUseActor; Super.PostBeginPlay(MyOwner); InitialHoldUseSeconds = HoldUseSeconds; MyUseActor = GetTargetActor(UseActorName); if ( MyUseActor != none ) OriginalUsingSound = MyUseActor.AmbientSound; } function SetObjOwner(KF_StoryObjective NewOwner) { ResetSound(); // just to be sure we won't leave ambient sound for old actor super.SetObjOwner(NewOwner); } function ConditionActivated(pawn ActivatingPlayer) { if ( InitialHoldUseSeconds > 0 ) HoldUseSeconds = InitialHoldUseSeconds * GetTotalDifficultyModifier(); Super.ConditionActivated(ActivatingPlayer); } function ConditionTick(float DeltaTime) { Super.ConditionTick(DeltaTime); // stop using objective, if we don't match condition if ( bCheckDependentsFirst && GetTargetActor(CurrentUserName) != none && !AllowCompletion() ) StopUsingObj(Pawn(GetTargetActor(CurrentUserName))); } function bool IsTouchingUseActor(pawn Toucher) { local Actor A; local float DistSq; local Actor MyUseActor; MyUseActor = GetTargetActor(UseActorName); if(Toucher != none && MyUseActor != none) { foreach Toucher.TouchingActors(class 'Actor', A) { if(A == MyUseActor) { return true; } } // added bUseCylinderCollision in cases use actor doesn't want block actors (e.g. use blocking volume) // but just wants to collide with actors // -- PooSH if( MyUseActor.bBlockActors || MyUseActor.bUseCylinderCollision ) { DistSq = VsizeSquared(MyUseActor.Location - Toucher.Location) ; if(DistSq <= Square( (MyUseActor.CollisionRadius + (Toucher.CollisionRadius)) * 1.25 ) ) { return true; } } } return false; } function Startedusing(pawn User) { local Pawn CurrentUser; local KF_UseableMover ControlledMover; local Actor MyUseActor; local Pawn OriginalIntigator; local bool bCantUse; if ( bComplete ) return; // no point of using already completed objective MyUseActor = GetTargetActor(UseActorName); ControlledMover = KF_UseableMover(GetTargetActor(ControlledMoverName)); CurrentUser = Pawn(GetTargetActor(CurrentUserName)); if(CurrentUser == none && IsTouchingUseActor(User)) { OriginalIntigator = GetInstigator(); // Instigator must be set to check DependentConditions if ( OriginalIntigator != User ) SetTargetActor(InstigatorName, User); bCantUse = bCheckDependentsFirst && !AllowCompletion(); if ( bCantUse ) { SetTargetActor(InstigatorName, OriginalIntigator); // restore original instigator return; } SetTargetActor(InstigatorName,User); SetTargetActor(CurrentUserName,User); LastUseTime = User.Level.TimeSeconds; if(AllowCompletion()) { bWasUsed = true; } if(ControlledMover != none) { ControlledMover.StartedUsing(); } if ( HoldUseSeconds > 0 && UsingSound != none ) { MyUseActor.AmbientSound = UsingSound; MyUseActor.NetUpdateTime = MyUseActor.Level.TimeSeconds - 1; } } } function StopUsingObj(pawn User) { ResetSound(); super.StopUsingObj(User); // ensure that we are not going abouve 100% if ( FinishedUseSeconds > HoldUseSeconds ) FinishedUseSeconds = HoldUseSeconds; } // fixed progress going above 100% -- PooSH function float GetCompletionPct() { return fclamp(super.GetCompletionPct(), 0.f, 1.f); } // count down style shows remaining time -- PooSH function string GetDataString() { if(HoldUseSeconds > 0) { if ( HUD_Screen.Screen_CountStyle == 0 ) { return string( (1.f-(GetRemainingUseTime() / HoldUseSeconds))*100.f) $"%" ; } else { return string(GetRemainingUseTime()) ; } } return "" ; } /* Overriden to skip inactive dependencies -- PooSH */ function bool AllowCompletion() { local int i; local array MyInstigators; if ( DependentConditions.length > 0 ) { MyInstigators = GetInstigatorList(); for(i = 0 ; i < DependentConditions.length ; i ++) { if ( DependentConditions[i].ConditionIsActive() ) { if( !DependentConditions[i].bComplete || (bCheckDependentsInstigator && !DependentConditions[i].FindInstigator(MyInstigators)) ) { return false; } } } } return true; } defaultproperties { bCheckDependentsInstigator=True }