rott/kf_sources/KFStoryGame/Classes/ObjCondition_Use.uc
2026-07-14 20:27:09 +07:00

327 lines
8.5 KiB
Ucode

/*
--------------------------------------------------------------
Condition_Use
--------------------------------------------------------------
This Condition is marked complete when a player presses the 'Use'
key while in range of its owning actor.
Author : Alex Quick
--------------------------------------------------------------
*/
class ObjCondition_Use extends KF_ObjectiveCondition
editinlinenew;
/* requires that line of sight be maintained with the objective during the use process. Only really relevant if HoldUseSeconds is something > 0 */
var () bool bMaintainUseLOS;
/* Min View angle cosine required to perform a 'use' action */
var () float MinUseViewAngle;
/* Number of seconds a player must hold the use key for before the objective completes. Releasing the key will abort any progress. */
var () float HoldUseSeconds;
/* if true, any progress made 'Using' this objective will be kept if the player stops holding the use key. only relevant if HoldUseSeconds is > 0 */
var () bool bKeepUseProgress;
var () name UsePawn_Tag;
var float FinishedUseSeconds;
var float LastUseTime;
var bool bAcquiredPawn;
var bool bWasUsed;
var const name UseActorName,InitialUseActorName,CurrentUserName,ControlledMoverName;
var () edfindable private Actor UseActor; // this exists only for level designers.
function Reset()
{
Super.Reset();
FinishedUseSeconds = 0.f;
bWasUsed = false;
}
function PostBeginPlay(KF_StoryObjective MyOwner)
{
Super.PostBeginPlay(MyOwner);
// Ditch any reference to this actor ASAP.
if(UseActor != none)
{
SetTargetActor(InitialUseActorName,UseActor);
SetTargetActor(UseActorName,UseActor);
UseActor = none;
}
}
function SetObjOwner(KF_StoryObjective NewOwner)
{
local Actor MyUseActor;
MyUseActor = GetTargetActor(UseActorName);
if(MyUseActor == none || (NewOwner != MyUseActor && GetObjOwner() == MyUseActor))
{
SetTargetActor(UseActorName,NewOwner);
}
Super.SetObjOwner(NewOwner);
}
function ConditionActivated(pawn ActivatingPlayer)
{
local Actor InitialUseActor,MyUseActor;
local KF_UseableMover ControlledMover;
Super.ConditionActivated(ActivatingPlayer);
InitialUseActor = GetTargetActor(InitialUseActorName);
MyUseActor = GetTargetActor(UseActorName);
if(InitialuseActor != none &&
!InitialuseActor.bPendingDelete)
{
SetTargetActor('UseActorName',InitialUseActor);
if(KF_UseableMover(MyUseActor) != none)
{
SetTargetActor(ControlledMoverName,KF_UseableMover(MyUseActor));
ControlledMover = KF_UseableMover(GetTargetActor(ControlledMoverName));
if(ControlledMover != none)
{
ControlledMover.Notify_Controlled(self);
}
}
}
}
function ConditionTick(float DeltaTime)
{
local float RemainingHoldUseTime;
local Actor MyUseActor;
local Pawn CurrentUser;
UpdateUseablePawnList();
MyUseActor = GetTargetActor(UseActorName);
CurrentUser = Pawn(GetTargetActor(CurrentUserName));
/* Important we call this before the Range checks or it won't register completion */
Super.ConditionTick(DeltaTime);
if(CurrentUser != none && CurrentUser.Controller != none)
{
RemainingHoldUseTime = GetRemainingUseTime() ;
if(!InRangeAndView() || RemainingHoldUseTime <= 0)
{
StopUsingObj(CurrentUser);
}
}
}
function UpdateUseablePawnList()
{
local Controller C;
local Actor MyUseActor;
MyUseActor = GetTargetActor(UseActorName);
if(UsePawn_Tag == '' ||
(MyUseActor != none &&
MyUseActor.Tag == UsePawn_Tag))
{
return;
}
for ( C= GetObjOwner().Level.ControllerList; C!=None; C=C.NextController )
{
if(C.Pawn != none &&
!C.Pawn.bDeleteMe &&
!C.Pawn.bPendingDelete &&
C.Pawn.Health > 0 &&
C.Pawn.Tag == UsePawn_Tag)
{
SetTargetActor(UseActorName,C.Pawn);
break;
}
}
}
function bool InRangeAndView()
{
local bool bhasLOS;
local bool bInRange;
local Pawn CurrentUser;
CurrentUser = Pawn(GetTargetActor(CurrentUserName));
if(CurrentUser == none)
{
return false;
}
bHasLOS = (!bMaintainUseLOS ||
KFPlayerController_Story(CurrentUser.Controller) != none &&
KFPlayerController_Story(CurrentUser.Controller).IsLookingAtLocation(GetLocation(),MinUseViewAngle));
bInRange = IsTouchingUseActor(CurrentUser) ;
return bInRange && bHasLOS;
}
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;
}
}
if(MyUseActor.bBlockActors)
{
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;
ControlledMover = KF_UseableMover(GetTargetActor(ControlledMoverName));
CurrentUser = Pawn(GetTargetActor(CurrentUserName));
if(CurrentUser == none && IsTouchingUseActor(User))
{
SetTargetActor(InstigatorName,User);
SetTargetActor(CurrentUserName,User);
LastUseTime = User.Level.TimeSeconds;
if(AllowCompletion())
{
bWasUsed = true;
}
if(ControlledMover != none)
{
ControlledMover.StartedUsing();
}
}
}
function StoppedUsing(pawn User)
{
local KF_UseableMover ControlledMover;
ControlledMover = KF_USeableMover(GetTargetActor(ControlledMoverName));
StopusingObj(User);
if(ControlledMover != none)
{
ControlledMover.StoppedUsing();
}
}
function StopUsingObj(pawn User)
{
local Pawn CurrentUser;
CurrentUser = Pawn(GetTargetActor(CurrentUserName));
if(CurrentUser != none &&
User == CurrentUser)
{
/* Cache the amount of time we have been holding use for */
if( bKeepUseProgress)
{
FinishedUseSeconds += (User.Level.TimeSeconds - LastUseTime) ;
}
SetTargetActor(CurrentUserName,none);
}
}
function vector GetLocation(optional out actor LocActor)
{
local Actor MyUseActor;
if(ConditionIsActive())
{
MyUseActor = GetTargetActor(UseActorName);
if(MyUseActor != none &&
!MyUseActor.bPendingDelete)
{
LocActor = MyUseActor;
return MyUseActor.Location;
}
return Super.GetLocation(LocActor);
}
}
/* returns the percentage of completion for this condition */
function float GetCompletionPct()
{
if(HoldUseSeconds > 0)
{
return 1.f - (GetRemainingUseTime() / HoldUseSeconds);
}
else
{
return float(bWasUsed);
}
}
/* Wrapper for finding the amount of time a player needs to hold down the USE key to complete this condition */
function float GetRemainingUseTime()
{
local Pawn CurrentUser;
CurrentUser = Pawn(GetTargetActor(CurrentUserName));
if(CurrentUser != none)
{
return FMax(HoldUseSeconds - ((GetObjOwner().Level.TimeSeconds - LastUseTime) + FinishedUseSeconds), 0.f) ;
}
return (HoldUseSeconds - FinishedUseSeconds);
}
function string GetDataString()
{
if(HoldUseSeconds > 0)
{
return Round((1.f-(GetRemainingUseTime() / HoldUseSeconds))*100.f)$"%" ;
}
return "" ;
}
DefaultProperties
{
UseActorName = "UseActor"
InitialUseActorName = "InitialUseActor"
CurrentUserName = "CurrentUser"
ControlledMoverName = "ControlledMover"
}