Exemplo n.º 1
0
void AMatineeActor::PostNetReceive()
{
	Super::PostNetReceive();

	if (MatineeData != NULL)
	{
		TArray<AActor*> ControlledActors;
		// Build a list of actors controlled by this matinee actor
		for( int32 InfoIndex = 0; InfoIndex < GroupActorInfos.Num(); ++InfoIndex )
		{
			const FInterpGroupActorInfo& Info = GroupActorInfos[ InfoIndex ];

			for (int32 ActorIndex = 0; ActorIndex < Info.Actors.Num(); ++ActorIndex )
			{
				AActor* Actor = Info.Actors[ ActorIndex ];
				if (Actor != NULL)
				{
					ControlledActors.Add( Actor );
				}
			}
		}

		// if we just received the matinee action, set 'saved' values to default so we make sure to apply previously received values
		if (SavedInterpData == NULL)
		{
			AMatineeActor* Default = GetClass()->GetDefaultObject<AMatineeActor>();
			SavedbIsPlaying = Default->bIsPlaying;
			SavedPosition = Default->InterpPosition;
			SavedbReversePlayback = Default->bReversePlayback;
		}

		// Handle replication of flag saying that bIsPlaying really should have replicated as true.
		if (SavedReplicationForceIsPlaying != ReplicationForceIsPlaying)
		{
			bIsPlaying = true;
		}

		// apply bReversePlayback
		if (SavedbReversePlayback!= bReversePlayback)
		{
			if (SavedbIsPlaying && bIsPlaying)
			{
				// notify actors that something has changed
				for (int32 ActorIndex = 0; ActorIndex < ControlledActors.Num(); ++ActorIndex )
				{
					IMatineeInterface * IMI = Cast<IMatineeInterface>(ControlledActors[ActorIndex]);
					if (IMI)
					{
						IMI->InterpolationChanged(this);
					}
				}
			}
		}
	
		// start up interpolation, if necessary
		if (!SavedbIsPlaying && (bIsPlaying || InterpPosition != SavedPosition))
		{	
			InitInterp();

			// if we're playing forward, call Play() to process any special properties on InterpAction that may affect the meaning of 'Position' (bNoResetOnRewind, etc)
			if (!bReversePlayback)
			{
				Play();
			}

			// find affected actors and set their ControllingMatineeActor
			// @warning: this code requires the linked actors to be static object references (i.e., some other Kismet action can't be assigning them)
			// this might not work for AI pawns
		
			for (int32 ActorIndex = 0; ActorIndex < ControlledActors.Num(); ++ActorIndex )
			{
				AActor* Actor = ControlledActors[ActorIndex];
				UInterpGroupInst * GrInst = FindGroupInst(Actor);
				if (Actor != NULL && !Actor->IsPendingKill() && GrInst != NULL) 
				{
					Actor->AddControllingMatineeActor(*this);
					// fire an event if we're really playing (and not just starting it up to do a position update)
					if (bIsPlaying)
					{
						IMatineeInterface * IMI = Cast<IMatineeInterface>(Actor);
						if (IMI)
						{
							IMI->InterpolationStarted(this);
						}
					}
				}
			}

		}

		// if we received a different current position
		if (InterpPosition != SavedPosition)
		{
			//@hack: negate fade tracks if we're updating a stopped matinee
			// the right fix is probably to pass bJump=true to UpdateInterp() when (!bIsPlaying && !SavedbIsPlaying),
			// but that may have lots of other side effects I don't have time to test right now
			TArray<FSavedFadeState> SavedFadeStates;
			if (!bIsPlaying && !SavedbIsPlaying && MatineeData != NULL)
			{
				for (FLocalPlayerIterator It(GEngine, GetWorld()); It; ++It)
				{
					if (It->PlayerController != NULL && It->PlayerController->PlayerCameraManager != NULL)
					{
						new(SavedFadeStates)FSavedFadeState(It->PlayerController->PlayerCameraManager);
					}
				}
			}

			if (bIsPlaying && SavedPosition != -1 && FMath::Abs(InterpPosition - SavedPosition) < ClientSidePositionErrorTolerance)
			{
				// The error value between us and the server is too small to change gameplay, but will cause visual pops
				InterpPosition = SavedPosition;
			}
			else
			{
				// set to position replicated from server
				UpdateInterp(InterpPosition, false, false);
			}
		}

		// terminate interpolation, if necessary
		if ((SavedbIsPlaying || InterpPosition != SavedPosition) && !bIsPlaying)
		{
			TermInterp();

			// find affected actors and remove InterpAction from their LatentActions list
			for (int32 ActorIndex = 0; ActorIndex < ControlledActors.Num(); ++ActorIndex )
			{
				AActor* Actor = ControlledActors[ ActorIndex ];
				if (Actor != NULL)
				{
					Actor->RemoveControllingMatineeActor(*this);

					// fire an event if we were really playing (and not just starting it up to do a position update)
					if (SavedbIsPlaying)
					{
						IMatineeInterface * IMI = Cast<IMatineeInterface>(Actor);
						if (IMI)
						{
							IMI->InterpolationFinished(this);
						}
					}
				}
			}
		}
	}
}
Exemplo n.º 2
0
Arquivo: tzvminaa.c Projeto: DeegC/10d
zOPER_EXPORT zLONG OPERATION
InvokeInterp( zVIEW  lpInterpSubtask,                // Interpretor's subtask
              zVIEW  lpAppSubtask,                   // application's subtask
              zPCHAR szSrcDLLName,                   // name of the dialog
              zPCHAR szOperationName,                // operation to interp
              zPLONG plRC )
{
   zVIEW  vXChecker;
   zSHORT nRC;
   zLONG  lStepRC;
   zVIEW  vStackObject;                           // view to the stack object
   zVIEW  vS_View;
   zVIEW  vZ_View;
   zVIEW  vSO;
   zVIEW  vSubtask = 0;
   zVIEW  vTaskLPLR;
   zPVOID hWRKS = NULL;

   // Check to make sure the LPLR is active.
   GetViewByName( &vTaskLPLR, "TaskLPLR", lpAppSubtask, zLEVEL_TASK );
   if ( vTaskLPLR == 0 )
      InitializeLPLR( lpInterpSubtask, "" );

   aInterpreterSave[ lMultiple ].vSubtask = lpInterpSubtask;

   if ( lMultiple > 0 )
   {
      if ( lMultiple >= MAX_INTEPRETER_ENTRY )
      {
         // Error, because number of recursive entries
         //  is greater than MAX_INTEPRETER_ENTRY
         return( -99 );
      }

      vSubtask = aInterpreterSave[ lMultiple -1 ].vSubtask;

      // save the global variables
      aInterpreterSave[ lMultiple -1 ].nStackPtr = g_nStackPtr;
      g_nStackPtr = 0;
      memcpy( aInterpreterSave[ lMultiple -1 ].nCallStack,
              g_nCallStack, zsizeof( g_nCallStack ) );
      memset( g_nCallStack, 0, zsizeof( g_nCallStack ) );

      aInterpreterSave[ lMultiple -1 ].vXPGView = g_vXPGView;
      g_vXPGView = 0;

      GetViewByName( &g_vStatementView, "StatementView",
                     vSubtask, zLEVEL_SUBTASK );

      aInterpreterSave[ lMultiple -1 ].vStatementView = g_vStatementView;
      g_vStatementView = 0;

      GetViewByName( &vSO, "StackObject",
                     vSubtask, zLEVEL_SUBTASK );
      aInterpreterSave[ lMultiple -1 ].vStackObject = vSO;

      memcpy( aInterpreterSave[ lMultiple -1 ].sValueStack,
              sValueStack, zsizeof( sValueStack ) );
      memset( sValueStack, 0, zsizeof( sValueStack ) );
   }

   lMultiple++;

   // see if we can load the XPG. if not, don't parse for now, exit out
   nRC = InitInterp( lpInterpSubtask, lpAppSubtask, szSrcDLLName );
   if ( nRC < 0 )
   {
      lStepRC = 1; // if the init failed return.
      goto EndOfInvokeInterp;
   }

   // Initialize the Working Storage Manager
   if ( WRKS_Init( &hWRKS ) < 0 )
   {
      // Error in WRKS system
      MessageSend( vSubtask, "VM03002", "VML Interpretor",
                   "Error Initializing Work Storage",
                   zMSGQ_OBJECT_CONSTRAINT_ERROR, zBEEP );
      TraceLineS( "VML Interpreter Error ","Initializing Work Storage" );
      lStepRC = 1; // if the init failed return.
      goto EndOfInvokeInterp;
   }

   if ( setjmp( g_jbWRKS ) != 0 )
   {
      // Error return from longjmp
      WRKS_Close( &hWRKS );
      lStepRC = 1;
      goto EndOfInvokeInterp;
   }

   // get the program object as it was loaded by the init function.
   GetViewByName( &g_vXPGView, "XPG", lpInterpSubtask, zLEVEL_SUBTASK );

   // try to position at the correct operation in the Subtask
   nRC = SetCursorFirstEntityByString( g_vXPGView, "Operation",
                                       "Name", szOperationName, "" );
   if ( nRC != zCURSOR_SET )
   {
      // no error message here, as we assume that the operation
      //  to be called is a C operation.
      // Returning -1, the driver will try to load it from the DLL
      lStepRC = -1;
      goto EndOfInvokeInterp;
   }

   SetCursorFirstEntityByEntityCsr( g_vXPGView,
                                    "SourceFile",
                                    g_vXPGView,
                                    "SourceFileOfOperation", "" );
   SetCursorFirstEntityByEntityCsr( g_vXPGView,
                                    "OperationSource",
                                    g_vXPGView,
                                    "Operation", "" );
   SetCursorFirstEntity( g_vXPGView, "OperationText", "" );
   SetCursorFirstEntity( g_vXPGView, "Statement", "" );
   CreateViewFromViewForTask( &g_vStatementView, g_vXPGView, 0 );

   // Create all of the entities needed in the stack object
   SetStackObjectFromViews( lpInterpSubtask,
                            g_vXPGView,         // View to the XPG
                            g_vStatementView, // View to the statement
                            0 );              // index into the expression

   // Get the stack object as it was loaded with the XPG
   GetViewByName( &vStackObject,
                  "StackObject",
                  lpInterpSubtask,
                  zLEVEL_SUBTASK );
// ###blob  SetAttributeFromInteger( vStackObject,
//                            "Variable", "Value", (zLONG)lpAppSubtask );
   SetAttributeFromBlob( vStackObject, "Variable", "Value", &lpAppSubtask, sizeof( void * ) );
   SetNameForView( g_vStatementView, "StatementView", lpInterpSubtask, zLEVEL_SUBTASK );
   SetNameForView( lpAppSubtask, "ApplicationView", lpInterpSubtask, zLEVEL_SUBTASK );

   GetViewByName( &vXChecker, "TZVSXCOO", lpInterpSubtask, zLEVEL_APPLICATION );
   if ( vXChecker != 0 )
   {
      nRC = SetCursorFirstEntityByString( vXChecker, "DialogOperation", "Name", szOperationName, "" );

      if ( nRC == zCURSOR_SET )
      {
         GetViewByName( &vZ_View, "ZeidonVML", vSubtask, zLEVEL_TASK );
         GetViewByName( &vS_View, "XPG", vZ_View, zLEVEL_SUBTASK );

         SetAttributeFromString( vS_View, "Operation", "CurrentDebugFlag", "Y" );
         lStepRC = zXC_SETUP_DEBUGGER;
         goto EndOfInvokeInterp;
      }
   }

// lStepRC = zXC_STEP_EXECUTED;
#if 0
   OperationCount( 3 );
   OperationCount( 1 );
#endif
// Loop through each statement using the Go function.
   lStepRC = Go( lpAppSubtask, hWRKS, plRC );

EndOfInvokeInterp:
   // close work storage manager
   if ( hWRKS )
      WRKS_Close( &hWRKS );

   lMultiple--;
   if ( lMultiple > 0 )
   {
      vSubtask = aInterpreterSave[ lMultiple - 1 ].vSubtask;

      // restore the global variables
      g_nStackPtr = aInterpreterSave[ lMultiple - 1 ].nStackPtr;
      memcpy( g_nCallStack, aInterpreterSave[ lMultiple -1 ].nCallStack, zsizeof( g_nCallStack ) );

      g_vXPGView = aInterpreterSave[ lMultiple - 1 ].vXPGView;
      SetNameForView( g_vXPGView, "XPG", vSubtask, zLEVEL_SUBTASK );
      g_vStatementView = aInterpreterSave[ lMultiple - 1 ].vStatementView;
      SetNameForView( g_vStatementView, "StatementView", vSubtask, zLEVEL_SUBTASK );

      vSO = aInterpreterSave[ lMultiple - 1 ].vStackObject;
      SetNameForView( vSO, "StackObject", vSubtask, zLEVEL_SUBTASK );

      memcpy( sValueStack, aInterpreterSave[ lMultiple - 1 ].sValueStack, zsizeof( sValueStack ) );
   }

   return( lStepRC );
}