155 lines
5.0 KiB
Ucode
155 lines
5.0 KiB
Ucode
|
// Actor used by matinee (SeqAct_Interp) objects to replicate activation, playback, and other relevant flags to net clients
|
||
|
// Copyright 1998-2013 Epic Games, Inc. All Rights Reserved.
|
||
|
class MatineeActor extends Actor
|
||
|
native
|
||
|
nativereplication;
|
||
|
|
||
|
cpptext
|
||
|
{
|
||
|
virtual FLOAT GetNetPriority(const FVector& ViewPos, const FVector& ViewDir, APlayerController* Viewer, UActorChannel* InChannel, FLOAT Time, UBOOL bLowBandwidth);
|
||
|
virtual INT* GetOptimizedRepList(BYTE* Recent, FPropertyRetirement* Retire, INT* Ptr, UPackageMap* Map, UActorChannel* Channel);
|
||
|
virtual void TickSpecial(FLOAT DeltaTime);
|
||
|
virtual void PreNetReceive();
|
||
|
virtual void PostNetReceive();
|
||
|
// returns group index
|
||
|
INT GetGroupActor(FName GroupName);
|
||
|
UBOOL ClientInitializeAIGroupActors();
|
||
|
}
|
||
|
|
||
|
/** the SeqAct_Interp associated with this actor (this is set in C++ by the action that spawns this actor)
|
||
|
* on the client, the MatineeActor will tick this SeqAct_Interp and notify the actors it should be affecting
|
||
|
*/
|
||
|
var const SeqAct_Interp InterpAction;
|
||
|
/** properties that may change on InterpAction that we need to notify clients about, since the object's properties will not be replicated */
|
||
|
var bool bIsPlaying, bReversePlayback, bPaused;
|
||
|
var float PlayRate;
|
||
|
var float Position;
|
||
|
|
||
|
/** right now Max AIGroup per matinee is 10 **/
|
||
|
const MAX_AIGROUP_NUMBER = 10;
|
||
|
|
||
|
/** to replicate AIGroup actors - for now up to 10 it can replicate**/
|
||
|
var name AIGroupNames[MAX_AIGROUP_NUMBER];
|
||
|
var Pawn AIGroupPawns[MAX_AIGROUP_NUMBER];
|
||
|
|
||
|
/** This is used by client to indicate if AI group needs initialization or not. Client needs to wait until pawns are spawned **/
|
||
|
/** This flag is used by multiple purpose. At the end of initializtion, it will be set.
|
||
|
* 0: not initialized
|
||
|
* 1: called InitGroup
|
||
|
* 2: set init interpolation or physics stuff == DONE **/
|
||
|
var transient int AIGroupInitStage[MAX_AIGROUP_NUMBER];
|
||
|
/** This is just optimization flag to skip checking it again. If all is initialized, it will set this to be TRUE **/
|
||
|
var transient bool AllAIGroupsInitialized;
|
||
|
|
||
|
/** How much error is tolerated in the client-side position before the position that the server replicated is applied */
|
||
|
var float ClientSidePositionErrorTolerance;
|
||
|
|
||
|
/** Add AI group actors to this actor **/
|
||
|
native function AddAIGroupActor(InterpGroupInstAI AIGroupInst);
|
||
|
|
||
|
replication
|
||
|
{
|
||
|
if (bNetInitial && Role == ROLE_Authority)
|
||
|
InterpAction;
|
||
|
|
||
|
if (bNetDirty && Role == ROLE_Authority)
|
||
|
bIsPlaying, bReversePlayback, bPaused, PlayRate, Position, AIGroupNames, AIGroupPawns;
|
||
|
}
|
||
|
|
||
|
/** called by InterpAction when significant changes occur. Updates replicated data. */
|
||
|
event Update()
|
||
|
{
|
||
|
local InterpGroupInstAI AIGroupInst;
|
||
|
local int GroupID;
|
||
|
|
||
|
bIsPlaying = InterpAction.bIsPlaying;
|
||
|
bReversePlayback = InterpAction.bReversePlayback;
|
||
|
bPaused = InterpAction.bPaused;
|
||
|
PlayRate = InterpAction.PlayRate;
|
||
|
Position = InterpAction.Position;
|
||
|
bForceNetUpdate = TRUE;
|
||
|
|
||
|
if (bIsPlaying)
|
||
|
{
|
||
|
SetTimer(1.0, true, nameof(CheckPriorityRefresh));
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
ClearTimer(nameof(CheckPriorityRefresh));
|
||
|
}
|
||
|
|
||
|
// Replicate all AIGroup actors
|
||
|
if (InterpAction != none)
|
||
|
{
|
||
|
for (GroupID = 0; GroupID < InterpAction.GroupInst.Length; ++GroupID)
|
||
|
{
|
||
|
AIGroupInst = InterpGroupInstAI(InterpAction.GroupInst[GroupID]);
|
||
|
if ( AIGroupInst!=none )
|
||
|
{
|
||
|
AddAIGroupActor(AIGroupInst);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** check if we should perform a network positional update of this matinee
|
||
|
* to make sure it's in sync even if it hasn't had significant changes
|
||
|
* because it's really important (e.g. a player is standing on it or being controlled by it)
|
||
|
*/
|
||
|
function CheckPriorityRefresh()
|
||
|
{
|
||
|
local Controller C;
|
||
|
local int i;
|
||
|
|
||
|
if( InterpAction != None )
|
||
|
{
|
||
|
// check if it has a director group - if so, it's controlling the camera, so it's important
|
||
|
for (i = 0; i < InterpAction.GroupInst.length; i++)
|
||
|
{
|
||
|
if (InterpGroupInstDirector(InterpAction.GroupInst[i]) != None)
|
||
|
{
|
||
|
bNetDirty = true;
|
||
|
bForceNetUpdate = true;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// check if it is controlling a player Pawn, or a platform a player Pawn is standing on
|
||
|
foreach WorldInfo.AllControllers(class'Controller', C)
|
||
|
{
|
||
|
if ( C.bIsPlayer && C.Pawn != None &&
|
||
|
( InterpAction.LatentActors.Find(C.Pawn) != INDEX_NONE ||
|
||
|
(C.Pawn.Base != None && InterpAction.LatentActors.Find(C.Pawn.Base) != INDEX_NONE) ) )
|
||
|
{
|
||
|
bNetDirty = true;
|
||
|
bForceNetUpdate = true;
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
defaultproperties
|
||
|
{
|
||
|
Begin Object Class=SpriteComponent Name=Sprite
|
||
|
Sprite=Texture2D'EditorResources.S_Actor'
|
||
|
HiddenGame=True
|
||
|
AlwaysLoadOnClient=False
|
||
|
AlwaysLoadOnServer=False
|
||
|
SpriteCategoryName="Matinee"
|
||
|
End Object
|
||
|
Components.Add(Sprite)
|
||
|
|
||
|
bSkipActorPropertyReplication=true
|
||
|
bAlwaysRelevant=true
|
||
|
bReplicateMovement=false
|
||
|
bUpdateSimulatedPosition=false
|
||
|
bOnlyDirtyReplication=true
|
||
|
RemoteRole=ROLE_SimulatedProxy
|
||
|
NetPriority=2.7
|
||
|
NetUpdateFrequency=1.0
|
||
|
Position=-1.0
|
||
|
PlayRate=1.0
|
||
|
ClientSidePositionErrorTolerance=0.1
|
||
|
}
|